--- /dev/null
+The following people contributed significantly to spice-gtk:
+
+Gerd Hoffmann <kraxel@redhat.com> - original author
+Marc-André Lureau <marcandre.lureau@redhat.com> - maintainer
+Hans de Goede <hdegoede@redhat.com> - usb redirection
+Christophe Fergeau <cfergeau@redhat.com> - smartcard
--- /dev/null
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
--- /dev/null
+2016-10-07 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ spicy: fix reset of terminal when quit
+ Only restore the terminal if it was actually saved.
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ usb: fix libusb_get_active_config_descriptor()
+ I wrongly replaced "assert(!get_active_config())" with
+ "if (!get_active_config())" in the previous commit.
+
+2016-10-07 Snir Sheriber <ssheribe@redhat.com>
+
+ Avoid compression of isochronous devices
+ Device is considered isochronous if one of its endpoints is
+ defined as isochronous transfer, in that case data transfer
+ over the usbredir channel will not be compressed
+ (it is assumed that there is a strong correlation between
+ isochronous devices and devices which their data is usually
+ compressed)
+
+ E.g.
+ Camera/mic device will usually be recognised as isochronous
+ while storage devices won't
+
+ Message-Id: <1475766822-26809-2-git-send-email-ssheribe@redhat.com>
+
+2016-10-06 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Update NEWS for 0.33 release
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ build-sys: bump spice-glib version
+ New symbols in spice-glib, bump before release.
+
+ spicy: only watch stdin if testing org.spice.spicy port
+ This fixes starting spicy with a shell in the background with &, spicy
+ would hang in tcsetattr().
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-10-05 Victor Toso <me@victortoso.com>
+
+ tests: fix -Wall -Wextra compiler warnings
+ With -Wall a few -Wunused-variable and -Wunused-but-set-variable;
+ With -Wextra lots of -Wunused-parameter and a few -Wsign-compare.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-10-03 Victor Toso <me@victortoso.com>
+
+ tests: set binaries to have 'test' name prefix
+ To follow test-spice-uri and test-file-transfer standard.
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-09-14 Pavel Grunt <pgrunt@redhat.com>
+
+ widget: Inform about transfer failure
+ Call spice_main_file_copy_finish to get result of the transfer
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-09-09 Pavel Grunt <pgrunt@redhat.com>
+
+ Remove trailing semicolon
+
+2016-09-07 Frediano Ziglio <fziglio@redhat.com>
+
+ Ignore modifiers messages if no modifiers changed
+ This avoid keep sending modifiers changes if guest is not
+ synchronising the changes.
+
+ I consider this as an improving as this avoids client to try again
+ and again to force synchronisation however this does not prevent
+ every unwanted keystroke insertion which possibly can be a real
+ problem on some configurations.
+
+ For instance if guest do not handle caps lock as the client do
+ if client uses another modifiers (as num lock) this can force
+ inserting virtual caps keypress.
+
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+2016-09-07 Christophe Fergeau <cfergeau@redhat.com>
+
+ spicy: fix 'tabled' typo
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+2016-09-02 Pavel Grunt <pgrunt@redhat.com>
+
+ clipboard: Return early if check_clipboard_size_limits() fails
+ b0a2ff4 "clipboard: Add fixup_clipboard_text helper"
+ mistakenly removed some early returns when text conversion fails for
+ some reason. This commit readds it.
+
+ util: Remove unused GError parameter
+ The parameter is removed from functions:
+ get_line
+ spice_convert_newlines
+ spice_unix2dos
+ spice_dos2unix
+
+ It was introduced in 75f1ea3ee9c4dbd6c5f27896caee07792bbdbba4
+ but never used
+
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-09-01 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Translate file transfer error messages
+ If we are to ever display error messages to a user in a UI, they need to
+ be translated.
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-09-01 Pavel Grunt <pgrunt@redhat.com>
+
+ file-transfer: Add guards to public functions
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ file-transfer: Add documentation for public functions
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-09-01 Christophe Fergeau <cfergeau@redhat.com>
+
+ clipboard: Use gtk_clipboard_request_text for text data
+ Currently, when the agent asks us for VD_AGENT_CLIPBOARD_UTF8_TEXT data,
+ spice-gtk looks up for the first X11 target which would provide it with
+ UTF8_TEXT data, and uses that for the clipboard request. This means we
+ will use UTF8_STRING as the target for gtk_clipboard_request_contents().
+
+ However, some applications who can copy and paste text do not
+ necessarily support the UTF8_STRING target. This is the case for Motif
+ applications which support the STRING target however. It turns out gtk+
+ also provides a gtk_clipboard_request_text() method which will try
+ several targets (UTF8_TEXT, COMPOUND_TEXT, TEXT), and will ensure the
+ returned string is UTF-8, so we can use that when the agent asks us for
+ some text data.
+
+ This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1348624
+
+ clipboard: Add fixup_clipboard_text helper
+ This makes clipboard_received_cb a bit shorter, and will be useful
+ in the next commit.
+
+2016-09-01 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Add ability to get sizes from SpiceFileTransferTask
+ If a client is handling multiple SpiceFileTransferTasks at one time,
+ it's not currently possible to provide a single overall progress to the
+ user. The only information that the client can get is the percentage
+ progress. This patch adds two new properties:
+ - total-bytes: the size of the file transfer task in bytes
+ - transferred-bytes: the number of bytes already transferred
+
+ This allows a client UI to calculate the combined progress for all
+ ongoing transfer tasks and present it to the user. Two convenience
+ functions were added to retrieve these values:
+ - spice_file_transfer_task_get_total_bytes()
+ - spice_file_transfer_task_get_transferred_bytes()
+
+2016-08-30 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: remove PKG_PREREQ
+ I added it to make sure AC_SUBST happened, but apparently AC_SUBST
+ happens with very old pkg-config versions too, no need to check
+ pkg-config pkg.m4 version.
+
+2016-08-26 Christophe Fergeau <cfergeau@redhat.com>
+
+ mouse: Fix pointer grabbing in server mode
+ Trying to click on spice-gtk window while in server mode should result
+ in a pointer grab. This is currently failing, with the cursor wrapping
+ to the top left corner of the window instead without being grabbed.
+
+ This is caused by our use of gtk_event_box_set_above_child(),
+ when clicking on the SpiceWidget, the grab is implicitly taken by
+ the window which is above the event box (which is an internal
+ GtkEventBox input-only GdkWindow). Then when we call gdk_pointer_grab()
+ on the GtkEventBox::window, we get a grab-broken event indicating the
+ grab was transferred from the internal input-only window to
+ GtkEventBox::window (see gtk+ bug
+ https://bugzilla.gnome.org/show_bug.cgi?id=769635#c2 for a detailed
+ explanation).
+
+ This commit ignores grab-broken events when the GdkWindow who got the
+ grab corresponds to the one we called gdk_pointer_grab() on.
+ An alternative would be to call gdk_pointer_grab() on the GdkWindow
+ which received the button-press-event, but the call chain between
+ button_event() and the eventual gdk_pointer_grab() call, so it would be
+ not so elegant to pass the correct GdkWindow all the way.
+
+2016-08-26 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ widget: set keypress-delay to 0 on unix socket
+ There is no strong need for keypress-delay on local connection (not
+ verified: unless the system is heavily loaded, in which case the VM will
+ probably be stuck too and may or not repeat the key when running).
+
+ The benefit of removing keypress-delay is that games or interfaces that
+ require "realtime" responses, such as FPS, are slightly better without
+ the 100ms input delay.
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ widget: make set_keypress_delay a function
+ So the widget can call it without going through g_object_set().
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ channel: add read-only socket property
+ Channel users (such as spice widget) may want to know some connection
+ details. Instead of exposing various connection properties, we may as
+ well just have a GSocket property, with a strong warning on usage.
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-08-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: simplify checking for x11
+ We no longer need the gtk+-quartz/win32 check, however we can simplify
+ the x11 check if building gtk+-x11
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ build-sys: require recent pkg-config
+ So we can drop the AC_SUBST for _CFLAGS & _LIBS variable (since 0.24
+ but there is no clean way to check that before PKG_PREREQ in 0.29,
+ released last year)
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-08-22 Francois Gouget <fgouget@codeweavers.com>
+
+ streaming: Fix the VideoDecoder queue_frame() documentation
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-08-19 Ian Stakenvicius <axs@gentoo.org>
+
+ Add missing libX11 reference to build system
+ GTK on its own is not enough to ensure libX11 is properly linked with
+ libspice-client-gtk. This patch adds X11_LIBS to SPICE_GTK_LIBADD_COMMON
+ (and X11_CFLAGS to a relevant section as well) in src/Makefile.am, and
+ performs an approriate pkg-config based check to determine the correct
+ values in configure.ac when not building for win32 or quartz.
+
+ For more info see http://bugs.gentoo.org/585118
+
+2016-08-19 Frediano Ziglio <fziglio@redhat.com>
+
+ Add Italian .po file.
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+ Initialise gettext library properly
+ This will allow internationalisation to work correctly.
+
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+2016-08-16 Pavel Grunt <pgrunt@redhat.com>
+
+ Do not require epoxy for Windows
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+ widget: Fix rendering issues with CSD on Windows
+ Replace GDK_WINDOW_HWND by gdk_win32_window_get_impl_hwnd() which gets
+ the HWND directly, without any side effects.
+
+ Related:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1352216
+
+ Acked-by: Fabiano Fidêncio <fabiano@fidencio.org>
+
+2016-08-12 Francois Gouget <fgouget@codeweavers.com>
+
+ streaming: Create the pipeline at the same time as the GStreamer decoder
+ This lets create_gstreamer_decoder() fail if it cannot create the
+ pipeline it needs, allowing the caller to try fallbacks.
+ This also means the pipeline has the same lifetime as the decoder which
+ makes it possible to remove a check in queue_frame().
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ streaming: Don't crash if the stream creation fails
+ Note that this implies closing the stream before receiving any frame.
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ streaming: Don't crash if no frame was received before closing the stream
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-08-12 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Improve file transfer error messages
+ In preparation for potentially displaying error messages to a user in a
+ UI, I thought I'd improve the messages slightly.
+
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+ Fix docs for SpiceFileTransferTask::progress
+ This property actually represents a fractional value from 0 to 1.0, not
+ a percentage between 0 and 100.
+
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+2016-08-11 Francois Gouget <fgouget@codeweavers.com>
+
+ streaming: Check the stream id in display_update_stream_report() too
+ It's safer and more consistent than assuming the caller has done the
+ check already.
+
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+2016-08-10 Pavel Grunt <pgrunt@redhat.com>
+
+ vmcstream: Do not disconnect cancellable in coroutine
+ It is disconnected when spice_vmc_input_stream_read_all_finish()
+ is called.
+
+ Silence many warnings appearing with webdav:
+ GLib-GObject-WARNING **: gsignal.c:2635: instance '0x7fe658015c40' has no handler with id '13555'
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ channel-webdav: Remove extra SpiceWebdavChannel parameter
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+2016-08-10 Victor Toso <victortoso@redhat.com>
+
+ file-transfer: improve GHashTable with value_destroy_func
+ By using g_hash_table_new_full() we can unref its value which is the
+ SpiceFileTransferTask. This makes the code a little bit simpler as
+ nowhere we use the xfer-task after removing it from hash table.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ file-transfer: increase reference for channel-main
+ SpiceMainChannel uses the SpiceFileTransferTask reference given in the
+ hash table provided by spice_file_transfer_task_create_tasks(). That
+ means SpiceFileTransferTask is not holding a reference for itself but
+ it relies on it due the async calls it provides.
+
+ This patch increases the reference of each SpiceFileTransferTask for
+ the hash table which will be unref'ed by channel-main in
+ file_transfer_operation_task_finished(); the original reference is
+ kept to SpiceFileTransferTask to be freed after the finish signal is
+ emitted on spice_file_transfer_task_close_stream_cb().
+
+ This patch fixes some critical warnings as we have two g_object_unref
+ but only one reference.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ channel-main: make debug helpful in case of failures
+ Debug should come before the g_return_if_fail() otherwise we lose
+ important debug data.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ channel-main: improve code to use FileTransferOperation
+ Since commit b26818d0e00666 we are grouping all transferred files per
+ operation (drag and drop); That leaded to some design flaws in the
+ code. The changes suggested in this patch are (in execution order):
+
+ * On spice_file_transfer_task_read_async()
+ - Passing FileTransferOperation data so in the callback and in further
+ function calls, we don't need to look for this;
+
+ Note that FileTransferOperation is not freed while any of its
+ SpiceFileTransferTask exists and by design they are never finished
+ while on pending state, so file_xfer_read_async_cb() should have a
+ valid FileTransferOperation pointer.
+
+ * On file_xfer_read_async_cb()
+ - Removed unnecessary variables;
+
+ * On file_xfer_flush_async()
+ - Using SpiceFileTransferTask as parameter which can retrieve the
+ SpiceMainChannel and the GCancellable;
+ - Using SpiceFileTransferTask as source_object for GTask with
+ FileTransferOperation as user_data which is helpful for its
+ callback;
+
+ * On file_xfer_flush_finish() and file_xfer_data_flushed_cb()
+ - Using SpiceFileTransferTask as parameter and source_object check for
+ GTask
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-transfer: Move initializations to _task_new()
+ This was a request introduced at f6b3b697093a16de to be done after
+ moving the SpiceFileTransferTask code to its own file.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+2016-08-05 Christophe Fergeau <cfergeau@redhat.com>
+
+ wocky: Pass GTask around instead of ConnectAsyncData
+ Now that the ConnectAsyncData we need is set as GTask data, we can pass
+ around the GTask rather than the ConnectAsyncData instance, and remove
+ the GTask pointer from it. We can get the ConnectAsyncData from the
+ GTask when needed using g_task_get_task_data().
+
+ wocky: Set ConnectAsyncData instance as GTask data
+ Currently, the ConnectAsyncData instance is leaked if for example
+ we trigger one codepath calling g_task_return_error(). If we
+ associate it with the GTask with g_task_set_task_data(),
+ this kind of leak will be avoided.
+
+ wocky: Simplify wocky_http_proxy_connect_finish()
+ Rather than returning the whole ConnectAsyncData struct with
+ g_task_return_pointer(), we can return only the GIOStream object as this
+ is what we are interested in.
+
+ This has the side-effect of fixing a ConnectAsyncData leak as after
+ calling g_task_propagate_pointer() the old code had ownership of the
+ ConnectAsyncData instance but was never freeing it.
+
+ The leak is:
+ ==20010== 4,348 (56 direct, 4,292 indirect) bytes in 1 blocks are definitely lost in loss record 20,762 of 20,999
+ ==20010== at 0x4C2DA60: calloc (vg_replace_malloc.c:711)
+ ==20010== by 0xD0F6EB0: g_malloc0 (gmem.c:124)
+ ==20010== by 0x75C0978: wocky_http_proxy_connect_async (wocky-http-proxy.c:359)
+ ==20010== by 0xCB4E22C: g_socket_client_connected_callback (gsocketclient.c:1548)
+ ==20010== by 0xCB57342: g_task_return_now (gtask.c:1107)
+ ==20010== by 0xCB579E5: g_task_return (gtask.c:1165)
+ ==20010== by 0xCB4FB1C: g_socket_connection_connect_callback (gsocketconnection.c:236)
+ ==20010== by 0xCB47160: socket_source_dispatch (gsocket.c:3543)
+ ==20010== by 0xD0F1702: g_main_dispatch (gmain.c:3154)
+ ==20010== by 0xD0F1702: g_main_context_dispatch (gmain.c:3769)
+ ==20010== by 0xD0F1AAF: g_main_context_iterate.isra.29 (gmain.c:3840)
+ ==20010== by 0xD0F1B5B: g_main_context_iteration (gmain.c:3901)
+ ==20010== by 0xCB7D58C: g_application_run (gapplication.c:2381)
+ ==20010== by 0x41571C: main (remote-viewer-main.c:42)
+
+2016-08-03 Christophe Fergeau <cfergeau@redhat.com>
+
+ spicy: Fix spice_file_transfer_task_get_filename leak
+ It was wrongly annotated as (transfer none)
+
+ An alternative would be to store what is returned by
+ g_file_get_basename() in SpiceFileTransferTask and return that, this
+ would allow to make spice_file_transfer_task_get_filename() (transfer
+ none) without leaking memory.
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-08-03 Victor Toso <victortoso@redhat.com>
+
+ channel-main: avoid race around file-transfer flush
+ This patch avoids a race condition. The race happens when we mark the
+ xfer-task as completed by receiving VD_AGENT_FILE_XFER_STATUS_SUCCESS
+ message while the flush callback was not yet called.
+
+ The flush callback is file_xfer_data_flushed_cb() and it might not be
+ called immediately after data is flushed.
+
+ The race can be verified while transferring several small files at
+ once. I can see it often with more then 50 files in one transfer
+ operation.
+
+ This fix implies that SpiceMainChannel should check in its async
+ callbacks if given SpiceFileTransferTask is completed.
+
+ This patch introduces spice_file_transfer_task_is_completed (internal)
+ to help check if spice_file_transfer_task_completed() was called or
+ not.
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-08-03 Christophe Fergeau <cfergeau@redhat.com>
+
+ file-transfer: avoid potential leaks
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-08-03 Victor Toso <victortoso@redhat.com>
+
+ file-transfer: Fix SpiceFileTransferTask::error leak
+ The self->error is the error set for the file-transfer and it will be
+ propagated with the "finish" signal. As this is transfer none pointer,
+ we should not lose its reference on g_task_return_error and we should
+ clear it out afterwards.
+
+ 40 (16 direct, 24 indirect) bytes in 1 blocks are definitely lost in
+ loss record 7,489 of 14,298
+ at 0x4C2BBAD: malloc (vg_replace_malloc.c:299)
+ by 0xB5090E8: g_malloc (gmem.c:94)
+ by 0xB51F8A2: g_slice_alloc (gslice.c:1025)
+ by 0xB4EFCC5: g_error_new_literal (gerror.c:471)
+ by 0xB4EFFAD: g_set_error_literal (gerror.c:619)
+ by 0xAF13397: g_cancellable_set_error_if_cancelled (gcancellable.c:314)
+ by 0xAF630C8: g_task_propagate_error (gtask.c:1519)
+ by 0xAF63CD8: g_task_propagate_int (gtask.c:1652)
+ by 0x50863F5: spice_file_transfer_task_read_finish (spice-file-transfer-task.c:477)
+ by 0x5093239: file_xfer_read_async_cb (channel-main.c:1811)
+ by 0xAF62F38: g_task_return_now (gtask.c:1121)
+ by 0xAF63775: g_task_return (gtask.c:1179)
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-08-03 Christophe Fergeau <cfergeau@redhat.com>
+
+ file-transfer: Fix SpiceFileTransferTask::file_stream leak
+ g_file_read_finish() is (transfer full) so we must release the ref
+ we got in _dispose() as it's not done anywhere else in the code.
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ file-transfer: Fix GTask leaks
+ The file transfer code calls g_*_async() methods with a GTask as the
+ user_data argument. It needs to own a reference to the GTask for the
+ duration of the async call to keep the GTask alive, however it was never
+ releasing it when it no longer needs it (that is, after calling
+ g_task_return_*).
+
+ Some of the leaks fixed by this patch are:
+
+ * GTask leak after flush
+ 11,232 bytes in 54 blocks are definitely lost in
+ loss record 14,018 of 14,071
+ at 0x4C2BBAD: malloc (vg_replace_malloc.c:299)
+ by 0xC14A0E8: g_malloc (gmem.c:94)
+ by 0xC1608A2: g_slice_alloc (gslice.c:1025)
+ by 0xC160ECD: g_slice_alloc0 (gslice.c:1051)
+ by 0xBEDBD11: g_type_create_instance (gtype.c:1857)
+ by 0xBEBD7DA: g_object_new_internal (gobject.c:1781)
+ by 0xBEBF11C: g_object_newv (gobject.c:1928)
+ by 0xBEBF89B: g_object_new (gobject.c:1621)
+ by 0xBBA4424: g_task_new (gtask.c:693)
+ by 0x6F8C3C0: file_xfer_flush_async (channel-main.c:899)
+ by 0x6F8C3C0: file_xfer_read_async_cb (channel-main.c:1826)
+ by 0xBBA3F38: g_task_return_now (gtask.c:1121)
+ by 0xBBA4775: g_task_return (gtask.c:1179)
+
+ * GTask leak from spice_main_file_copy_async()
+ 208 bytes in 1 blocks are definitely lost in
+ loss record 13,708 of 15,093
+ at 0x4C2BBAD: malloc (vg_replace_malloc.c:299)
+ by 0xC14A0E8: g_malloc (gmem.c:94)
+ by 0xC1608A2: g_slice_alloc (gslice.c:1025)
+ by 0xC160ECD: g_slice_alloc0 (gslice.c:1051)
+ by 0xBEDBD11: g_type_create_instance (gtype.c:1857)
+ by 0xBEBD7DA: g_object_new_internal (gobject.c:1781)
+ by 0xBEBF11C: g_object_newv (gobject.c:1928)
+ by 0xBEBF89B: g_object_new (gobject.c:1621)
+ by 0xBBA4424: g_task_new (gtask.c:693)
+ by 0x6F8EF55: spice_main_file_copy_async (channel-main.c:3084)
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ test-file-transfer: Don't leak GError
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ test-file-transfer: Don't leak GFileInfo
+ The GFileInfo returned by spice_file_transfer_task_init_task_finish()
+ must be unref'ed when no longer needed.
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-07-30 Victor Toso <victortoso@redhat.com>
+
+ file-transfer: remove unused function for debug
+ This is here due bad rebase. It was removed and replaced by patch
+ f6072e678ea5 but not removed from 1af22e9652ddcbdd426cd "file-xfer:
+ move to spice-file-transfer-task.c", so the function is there, unused.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-07-29 Pavel Grunt <pgrunt@redhat.com>
+
+ session: Fix IPv6 by using g_network_address_parse
+ It supports quoting the address with []
+
+ Regression since ea37f06eaa11b6307c797895aeb85d87d142625a
+
+ Fixes:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1361478
+
+2016-07-29 Christophe Fergeau <cfergeau@redhat.com>
+
+ vmc: Fix leak in spice_vmc_output_stream_write_finish()
+ We own a reference on the GAsyncResult returned by
+ g_task_propage_pointer() so we have to g_object_unref() it when we no
+ longer need it.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+2016-07-29 Fabiano Fidêncio <fidencio@redhat.com>
+
+ vmcstream: set the right result for the task
+ This bogus code was introduced when switching to GTask API. Seems that
+ while writing those patches I just overlooked this part and set the wrong
+ result for the task. As part of the problems introduced (and now fixed)
+ you can notice that no output stream was being sent to the guest.
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-07-28 Pavel Grunt <pgrunt@redhat.com>
+
+ webdav: Do not reuse cancellable
+ Create it on SPICE_PORT_EVENT_OPENED
+
+ From g_cancellable_reset documentation:
+ Note that it is generally not a good idea to reuse an existing
+ cancellable for more operations after it has been cancelled once,
+ as this function might tempt you to do. The recommended practice is
+ to drop the reference to a cancellable after cancelling it, and let it
+ die with the outstanding async operations. You should create a fresh
+ cancellable for further async operations
+
+ In our case reusing the cancellable leads to a crash:
+ #0 0x00007ffff1662940 in g_task_return_error () at /lib64/libgio-2.0.so.0
+ #1 0x00007ffff1662b60 in g_task_return_new_error () at /lib64/libgio-2.0.so.0
+ #2 0x00007ffff57916e0 in read_cancelled (cancellable=<optimized out>, user_data=<optimized out>) at vmcstream.c:182
+ #3 0x00007ffff1391555 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
+ #4 0x00007ffff13a4062 in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
+ #5 0x00007ffff13acf5f in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
+ #6 0x00007ffff13ad33f in g_signal_emit () at /lib64/libgobject-2.0.so.0
+ #7 0x00007ffff16100d8 in g_cancellable_cancel () at /lib64/libgio-2.0.so.0
+ #8 0x00007ffff5775c01 in port_event (self=0xc7af60, event=1) at channel-webdav.c:512
+ #9 0x00007ffff1391555 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
+ #10 0x00007ffff13a445d in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
+ #11 0x00007ffff13acf5f in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
+ #12 0x00007ffff577479a in emit_main_context (opaque=0x7fffa5fff8d0) at gio-coroutine.c:200
+ #13 0x00007ffff10b7847 in g_idle_dispatch () at /lib64/libglib-2.0.so.0
+ #14 0x00007ffff10bade2 in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
+ #15 0x00007ffff10bb160 in g_main_context_iterate.isra () at /lib64/libglib-2.0.so.0
+ #16 0x00007ffff10bb20c in g_main_context_iteration () at /lib64/libglib-2.0.so.0
+ #17 0x00007ffff1677d2d in g_application_run () at /lib64/libgio-2.0.so.0
+ #18 0x000000000041031a in main (argc=2, argv=0x7fffffffd928) at remote-viewer-main.c:42
+
+ Fixes:
+ https://bugs.freedesktop.org/show_bug.cgi?id=97113
+
+2016-07-28 Lukas Venhoda <lvenhoda@redhat.com>
+
+ spice-widget: init egl only after first gl_scanout
+ When using GtkDrawingArea and EGL was not used, it was still initialized.
+ This produced warning messages on systems where EGL is not supported.
+
+ Move spice_egl_init from drawing_area_realize to gl_scanout.
+
+ Fixes:
+ https://bugs.freedesktop.org/show_bug.cgi?id=95254
+
+2016-07-28 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ misc: code style
+ Brace on new line for functions, 4 spaces indent, seperate end block
+
+ usbredir: fix leaks introduced by lz4 patch
+ While reviewing lz4 patch, I found that there are potential leaks. This
+ is untested, fyi. It would be nice if someone could confirm with running
+ ASAN for example.
+
+ Reviewed-by: Snir Sheriber <ssheribe@redhat.com>
+
+2016-07-27 Frediano Ziglio <fziglio@redhat.com>
+
+ Handle pause key correctly
+ Windows does not like Pause key sent with same scancodes as Break.
+ Although is the same physical key the two functions send two completely
+ different set of codes. On key press a E1 1D 45 sequence is generated
+ while on key release a E1 9D C5 is generated. Also some hardware
+ keyboards send press+release at the same time on key press (nothing on
+ release).
+ Tested with Linux and Windows clients.
+ Tested with Linux, Windows and DOS guests.
+ On Windows guest VK_PAUSE was not arriving correctly.
+
+ An additional send_pause function was added to avoid to change the
+ normal flow too much. This as the keymap table (generated from
+ src/keymaps.csv) can hold only one scancode while this key generate two
+ scancodes (ie E1-1D and 45) for each event.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-07-26 Frediano Ziglio <fziglio@redhat.com>
+
+ Support more extension codes
+ Not only E0 prefix but also E1 and E2.
+ They are used in some special cases, one is the pause key.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-07-14 Jonathon Jongsma <jjongsma@redhat.com>
+
+ SpiceWidget: limit scope of 'area' variable
+ 'area' was being set within the 'else' branch, but was not actually
+ used. So just move the declaration of 'area' within the if statement
+ where it is actually used. This potentially avoids "set-but-not-used"
+ warnings when GDK_WINDOWING_X11 is not defined.
+
+2016-07-14 Eduardo Lima (Etrunko) <etrunko@redhat.com>
+
+ configure: Add ${top_builddir}/spice-common to COMMON_CFLAGS
+ This fixes the build when done out of the tree, because of recent commit
+ in spice-common with auto-generated files.
+
+2016-07-13 Eduardo Lima (Etrunko) <etrunko@redhat.com>
+
+ Use correct variable to print if LZ4 support is to be built.
+
+2016-07-11 Snir Sheriber <ssheribe@redhat.com>
+
+ Usbredir: enable lz4 compression
+ Compressed message type is CompressedData which contains compression
+ type (1 byte) followed by the uncompressed data size (4 bytes-exists
+ only if data was compressed) followed by the compressed data
+
+ If SPICE_SPICEVMC_CAP_DATA_COMPRESS_LZ4 capability is available &&
+ data_size > COMPRESS_THRESHOLD && !AF_LOCAL data will be sent
+ compressed otherwise data will be sent uncompressed (as well if
+ compression has failed)
+
+ Update required spice-protocol to 0.12.12
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-07-11 Victor Toso <victortoso@redhat.com>
+
+ Update spice-common submodule
+
+2016-07-07 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ util: fix off-by-one array access
+ Thanks to ASAN, I found this off-by-one memory access in the unix2dos
+ code:
+
+ /util/unix2dos: =================================================================
+ ==23589==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000dd2f at pc 0x00000040428e bp 0x7ffd6fc31b90 sp 0x7ffd6fc31b80
+ READ of size 1 at 0x60200000dd2f thread T0
+ #0 0x40428d in spice_convert_newlines /home/elmarco/src/spice/spice-gtk/src/spice-util.c:355
+ #1 0x40443a in spice_unix2dos /home/elmarco/src/spice/spice-gtk/src/spice-util.c:382
+ #2 0x401eae in test_unix2dos /home/elmarco/src/spice/spice-gtk/tests/util.c:69
+ #3 0x7fb8bcd81983 (/lib64/libglib-2.0.so.0+0x6e983)
+ #4 0x7fb8bcd81b4e (/lib64/libglib-2.0.so.0+0x6eb4e)
+ #5 0x7fb8bcd81d5d in g_test_run_suite (/lib64/libglib-2.0.so.0+0x6ed5d)
+ #6 0x7fb8bcd81d80 in g_test_run (/lib64/libglib-2.0.so.0+0x6ed80)
+ #7 0x402cce in main /home/elmarco/src/spice/spice-gtk/tests/util.c:207
+ #8 0x7fb8bc755730 in __libc_start_main (/lib64/libc.so.6+0x20730)
+ #9 0x401818 in _start (/home/elmarco/src/spice/spice-gtk/tests/util+0x401818)
+
+ 0x60200000dd2f is located 1 bytes to the left of 4-byte region [0x60200000dd30,0x60200000dd34)
+ allocated by thread T0 here:
+ #0 0x7fb8c10421d0 in realloc (/lib64/libasan.so.3+0xc71d0)
+ #1 0x7fb8bcd61f1f in g_realloc (/lib64/libglib-2.0.so.0+0x4ef1f)
+
+ SUMMARY: AddressSanitizer: heap-buffer-overflow /home/elmarco/src/spice/spice-gtk/src/spice-util.c:355 in spice_convert_newlines
+
+ doc: fix unused warning
+ Fix gtk-doc warning by ignoring the new private header.
+
+ ./spice-gtk-unused.txt:1: warning: 12 unused declarations.They should be
+ added to spice-gtk-sections.txt in the appropriate place.
+
+ While at it, fix grabsequence header incorrect file name.
+
+2016-07-07 Victor Toso <victortoso@redhat.com>
+
+ tests: file-transfer agent cancel
+ Agent only can only send error or cancel from a transfer operation
+ after it was initialized. From SpiceFileTransferTask point of view,
+ error and cancellation is an GError with different code so testing
+ only cancel seems enough.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ tests: file-transfer cancel on read async
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ tests: file-transfer cancel on task init
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ tests: file-transfer include simple tests
+ This only includes a simple test for file-transfer with a small
+ summary of the possible situations of the test.
+
+ As the test is specifically for SpiceFileTransferTask, we don't create
+ a SpiceMainChannel.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: move to spice-file-transfer-task.c
+ This patch moves:
+ * GObject boilerplate
+ * External API related to SpiceFileTransferTask
+ * Internal API needed by channel-main
+ * Helpers that belong to this object
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ main: use xfer_task instead of task or self
+ Another patch to rename variable and keep consistency across
+ channel-main. Let's avoid task which is common for GTask and self for
+ non SpiceMainChannel objects
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: move debug to SpiceFileTransferTask
+ This debug information is simple way to check that the file-transfer
+ is not stalled. Now that we are using the read-async functions, we can
+ move this debug info there and avoid accessing object internals in
+ channel-main.c
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: Keep namespace of private function
+ Rename:
+ * file_xfer_close_cb -> spice_file_transfer_task_close_stream_cb
+
+ As this will be private to SpiceFileTransferTask
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: call user callback once per operation
+ SpiceFileTransferTask has a callback to be called when operation
+ ended. Til this patch, we were setting the user callback which means
+ that in multiple file-transfers, we were calling the user callback
+ several times.
+
+ Following the same logic pointed from 113093dd00a1cf10f6d3c3589b7 this
+ is a SpiceMainChannel operation and it should only call the user
+ callback when this operation is over (FileTransferOperation now).
+
+ Highlights:
+ * Now using GTask to set user callback and callback_data
+ * Handling error on FileTransferOperation:
+ - It is considered an error if no file was successfully transferred due
+ cancellations or any other kind of error;
+ - If any file failed due any error, we will consider the operation a
+ failure even if other files succeed.
+
+ Note also that SpiceFileTransferTask now does not have a callback and
+ callback_data. The xfer_tasks has ended after its "finish" signal is
+ emitted.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: call progress_callback per FileTransferOperation
+ Before this patch, the progress_callback is being called from
+ SpiceFileTransferTask each time that some data is flushed to the agent
+ of this given xfer-task. The progress value is computed by iterating
+ on all available xfer-tasks.
+
+ This patch intend to fix/change:
+
+ * The progress_callback should be called only with information related
+ to the FileTransferOperation of given xfer-task; This was also
+ suggested by 113093dd00a1cf10f6d3c3589b7589a184cec081;
+
+ * In case a SpiceFileTransferTask is cancelled or has an error, we
+ remove the remaining bytes (not sent) of this file from the
+ transfer_size;
+
+ * The progress_callback should not be done from SpiceFileTransferTask
+ context by (proposed) design. As the transfer operation starts in
+ spice_main_file_copy_async(), FileTransferOperation should handle
+ these calls.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: inform agent of errors only when task finished
+ No need to inform of a problem under
+ spice_file_transfer_task_completed() as the task will be finalized and
+ we can send the error to the agent there.
+
+ This change is related to split SpiceFileTransferTask from
+ channel-main.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: a FileTransferOperation per transfer call
+ Each call to spice_main_file_copy_async will now create a
+ FileTransferOperation which groups all SpiceFileTransferTasks of the
+ copy operation in a GHashTable.
+
+ To ease the review process, this first patch introduces the structure
+ and organize the logic around the four following helpers:
+
+ * spice_main_channel_reset_all_xfer_operations
+ * spice_main_channel_find_xfer_task_by_task_id
+ * file_transfer_operation_free
+ * file_transfer_operation_task_finished
+
+ The _task_finished function is the new callback for "finished" signal
+ from SpiceFileTransferTask.
+
+ The file_xfer_tasks GHashTable is now mapped as:
+ (key) SpiceFileTransferTask ID -> (value) FileTransferOperation
+
+ This patch leaves a FIXME regarding progress_callback which will be
+ addressed in a later patch in this series.
+
+ This change is related to split SpiceFileTransferTask from
+ channel-main.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: create helper function to send progress
+ This is an intermediary step for the following patches to make the
+ changes more clear and easy to follow.
+
+ In file_xfer_send_progress(), I've renamed the variable self to
+ xfer_task as this is not SpiceFileTransferTask function.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: improve helper function to queue agent message
+ This patch changes:
+ * rename function: file_xfer_queue -> file_xfer_queue_msg_to_agent
+ As it makes more clear what this helper function does;
+ * Use buffer provided by spice_file_transfer_task_read_finish()
+ instead of accessing SpiceFileTransferTask's private structure
+
+ This change is related to split SpiceFileTransferTask from
+ channel-main.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ main: do not check for xfer-task errors
+ The errors related to SpiceFileTransferTask can be present:
+ * before the flush happens, on spice_file_transfer_task_read_async()
+ * during the async flush:
+ - cancel from user which is handled by file_xfer_flush_async
+ - cancel/error from agent, handled on main_agent_handle_xfer_status()
+
+ file_xfer_flush_finish() should not check internal errors of
+ SpiceFileTransferTask and only be worried about errors regarding the
+ flush itself.
+
+ Note that with or without this patch, in case of errors from agent, we
+ don't stop the flushing; it is only cancelled from user cancellation.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ main: let channel-main handle file-xfer messages
+ By separating SpiceFileTransferTask from channel-main, we could choose
+ where to put the handler for messages. With the approach based on
+ spice_file_transfer_task_read_async(), we cannot have it under
+ spice-file-transfer-task.c due the need of callback and userdata on
+ _read_async.
+
+ It is much easier to keep this in channel-main and do not move any
+ VDAgent.
+
+ This patch reverts 349a52ca2d6af4b31a4f51c38a3292c04460953c changes
+ but it does rename:
+ - function file_xfer_handle_status -> main_agent_handle_xfer_status
+ - variables task to xfer_task
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ main: to let SpiceFileTransferTask handle errors
+ * on VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA, if the file-transfer is
+ on pending state, spice_file_transfer_task_read_async() will call the
+ callback with error set.
+
+ * on VD_AGENT_FILE_XFER_STATUS_SUCCESS, if the file-transfer is on
+ pending state, spice_file_transfer_task_completed() will set the
+ error for this task.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: introduce functions to read file async
+ Introduced functions (private):
+ * void spice_file_transfer_task_read_async()
+ * gssize spice_file_transfer_task_read_finish()
+
+ For a better abstraction of how to read from SpiceFileTransferTask and
+ handle its data, following the design of other objects like GFile and
+ GInputStream.
+
+ Due to the logic changes involved, some functions were created or
+ renamed to better address or match its place and purpose:
+
+ * spice_file_transfer_task_read_stream_cb
+ Callback for the actual read from GInpustStream; This is handling
+ the SpiceFileTransferTask bits only;
+
+ * file_xfer_read_cb -> file_xfer_read_async_cb
+ Renamed to match _read_async() function; This is handling the data
+ from reading the file by flushing it to the agent.
+
+ As the _read_async() uses GTask, the error handling is done on the
+ channel-main's callback, after _read_finish() is called.
+
+ This change is related to split SpiceFileTransferTask from
+ channel-main.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: introduce functions to init task async
+ Introduced functions (private):
+ * void spice_file_transfer_task_init_task_async()
+ * GFileInfo *spice_file_transfer_task_init_task_finish()
+
+ The init process of SpiceFileTransferTask does initialize its
+ GFileInputStream (for reading the file) and also its GFileInfo
+ (necessary to protocol in order to start the file-transfer with agent)
+
+ Due the logic changed involved, some functions were renamed to better
+ match its place and purpose:
+
+ * file_xfer_info_async_cb -> file_xfer_init_task_async_cb
+ It is channel-main's callback for each _init_task_async()
+
+ * file_xfer_read_async_cb -> spice_file_transfer_task_read_file_cb
+ * file_xfer_info_async_cb -> spice_file_transfer_task_query_info_cb
+ Both should be private to SpiceFileTransferTask now.
+
+ As the _init_task_async() uses GTask, some error handling was moved to
+ channel-main's after _init_task_finish() is called.
+
+ This change is related to split SpiceFileTransferTask from
+ channel-main.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: introduce _create_tasks()
+ We can split from file_xfer_send_start_msg_async() the logic in
+ creating the SpiceFileTransferTasks; The rest of the function can be
+ handled at spice_main_file_copy_async().
+
+ The new function, spice_file_transfer_task_create_tasks() returns a
+ GHashTable to optimize the access to a SpiceFileTransferTask from its
+ task-id, which is what we receive from the agent.
+
+ This change is related to split SpiceFileTransferTask from
+ channel-main.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: get functions for SpiceFileTransferTask
+ In order for channel-main to interact with each SpiceFileTransferTask
+ for the file-transfer operation, the following functions are
+ introduced:
+ * spice_file_transfer_task_get_id
+ * spice_file_transfer_task_get_channel
+ * spice_file_transfer_task_get_cancellable
+
+ Note that "id" property is public and could be acquired by
+ g_object_get but having the helper function is more practical.
+
+ This change is related to split SpiceFileTransferTask from
+ channel-main.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ file-xfer: task-id to start with 1
+ As this is unsigned, we can let 0 be in case of error
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+2016-06-30 Christophe Fergeau <cfergeau@redhat.com>
+
+ usb-device-manager: Avoid USB event thread leak
+ This is a follow-up of the previous commit ('usb-channel: Really stop
+ listening for USB events on disconnection').
+
+ Since the USB event thread has to be stopped when we destroy the
+ associated SpiceUsbDeviceManager, spice_usb_device_manager_dispose()
+ should force event_thread_run to FALSE even if
+ spice_usb_device_manager_stop_event_listening() was not enough. When
+ this happens, this means that there is a bug in the internal users of
+ spice_usb_device_manager_start_event_listening(), but with this change,
+ we'll at least warn about it, and avoid a thread leak/potential future
+ crash.
+
+ usb-channel: Really stop listening for USB events on disconnection
+ When using USB redirection, it's fairly easy to leak the thread handling
+ USB events, which will eventually cause problems in long lived apps.
+ In particular, in virt-manager, one can:
+ - start a VM
+ - connect to it with SPICE
+ - open the USB redirection window
+ - redirect a device
+ - close the SPICE window
+ -> the SpiceUsbDeviceManager instance will be destroyed (including the
+ USB context it owns), but the associated event thread will keep running.
+ Since it's running a loop blocking on libusb_handle_events(priv->context),
+ the loop will eventually try to use the USB context we just destroyed
+ causing a crash.
+
+ We can get in this situation when redirecting a USB device because we
+ will call spice_usb_device_manager_start_event_listening() in
+ spice_usbredir_channel_open_device(). The matching
+ spice_usb_device_manager_stop_event_listening() call is supposed to
+ happen in spice_usbredir_channel_disconnect_device(), however by the
+ time it's called in the scenario described above, the session associated
+ with the channel will already have been set to NULL in
+ spice_session_channel_destroy().
+
+ The session is only needed in order to get the SpiceUsbDeviceManager
+ instance we need to call spice_usb_device_manager_stop_event_listening()
+ on. This patch stores it in SpiceChannelUsbredir instead, this way we
+ don't need SpiceChannel::session to be non-NULL during device
+ disconnection.
+
+ This should fix the issues described in
+ https://bugzilla.redhat.com/show_bug.cgi?id=1217202
+ (virt-manager) and most
+ likely https://bugzilla.redhat.com/show_bug.cgi?id=1337007 (gnome-boxes)
+ as well.
+
+ usb: Update outdated GSimpleAsyncResult comment
+ It's still true after the switch to GTask.
+
+ usbredir: Use atomic for UsbDeviceManager::event_thread_run
+ This variable is accessed from 2 different threads (main thread and USB
+ event thread), so some care must be taken to read/write it.
+
+2016-06-30 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ usbredir: mark some functions as internal
+ For the sake of making clear those are not exported.
+
+2016-06-30 Christophe Fergeau <cfergeau@redhat.com>
+
+ usbredir: Fix GTask leak
+ spice_usbredir_channel_disconnect_device_async() creates a GTask and
+ then calls g_task_run_in_thread(). This method will take the reference
+ it needs on the GTask, it does not take ownership of the passed-in
+ GTask. This means we need to unref the GTask we created after calling
+ g_task_run_in_thread(), otherwise we are going to leak the GTask, as
+ well as the channel it's associated with.
+ Since it's an USB redir channel, this also causes some USB device
+ manager/USB event thread leaks.
+
+2016-06-21 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ Update NEWS for 0.32 release
+
+2016-06-21 Pavel Grunt <pgrunt@redhat.com>
+
+ session: Keep brackets around ipv6 hostname
+ According to rfc2732:
+ "To use a literal IPv6 address in a URL, the literal address should be
+ enclosed in "[" and "]" characters."
+
+ Resolves: rhbz#1331777
+
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+ session: Removed write-only variable
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+2016-06-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ mailmap: fix my name
+
+2016-06-21 Victor Toso <victortoso@redhat.com>
+
+ main: channel-main to increase file-transfer reference
+ This is a minor fix in the logic as in both situations (with or
+ without the patch) the reference count for the SpiceFileTransferTask
+ object is the same.
+
+ The change is interesting as SpiceFileTransferTask is created but on
+ g_file_read_async() it increases its reference count while
+ c->file_xfer_tasks keeps the original one.
+
+ It should be the other way around.
+ Acked-by: Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ main: assign variable after check for null
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-06-20 Christophe Fergeau <cfergeau@redhat.com>
+
+ build: Fix _DEPENDENCIES use
+ We want to trigger rebuild of libspice-client-gtk-3.0.la or
+ libspice-client-glib-2.0.la whenever the corresponding symbol file
+ changes.
+ However _DEPENDENCIES is not the right way of handling that as it will
+ disable automatic automake dependency generation.
+ This was not causing issues mainly because _DEPENDENCIES was mispelt as
+ _DEPEDENCIES.
+
+ Quoting automake manual:
+ https://www.gnu.org/software/automake/manual/automake.html#index-EXTRA_005fmaude_005fDEPENDENCIES-1
+ « The EXTRA_*_DEPENDENCIES variable may be useful for cases where you
+ merely want to augment the automake-generated _DEPENDENCIES variable
+ rather than replacing it. »
+
+ So this commit switches to use EXTRA_*_DEPENDENCIES rather than
+ *_DEPENDENCIES.
+
+2016-06-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: fix win32 build
+ Commit 0fafbe3 broke the build on win32, because it accesses
+ d->egl.enabled. Add a helper function and fix the build.
+
+ Reported-by: Frediano Ziglio <fziglio@redhat.com>
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+ vncdisplaykeymap: fix -Werror=tautological-compare
+ vncdisplaykeymap.c: In function 'vnc_display_keymap_gdk2xtkbd_table':
+ vncdisplaykeymap.c:223:14: error: self-comparison always evaluates to true [-Werror=tautological-compare]
+ if (GDK_IS_WIN32_WINDOW(window)) {
+
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+2016-06-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ widget: fix keyboard ungrab after click
+ Since the switch to a container widget (gtkstack then gtkeventbox), the
+ grab may be lost when clicking on the display. Since events are treated
+ at the top level container, set widget "above-child" to trap all of them
+ to solve this.
+
+ Fixes:
+ https://bugs.freedesktop.org/show_bug.cgi?id=96595
+
+ Reported-by: Frediano Ziglio <fziglio@redhat.com>
+ Tested-by: Frediano Ziglio <fziglio@redhat.com>
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+2016-06-20 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ widget: use scanout offset when using virgl
+ Ignoring the display area offset doesn't work nicely with virgl. Imho,
+ this condition is wrong even in QXL case.
+
+2016-06-17 Alexandru Visarion <viorel.visarion@gmail.com>
+
+ channel-main: Fix spice_main_file_copy_async annotation
+ Without (array zero-terminated=1), one null terminated array
+ parameter is translated into a single element, so its binding
+ isn't usable.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-06-16 Frediano Ziglio <fziglio@redhat.com>
+
+ widget: Disable IME context on display widget
+ This prevent Windows to handle IME on the widget which cause the
+ application to not receive keyboard events.
+
+ To test this issue set keyboard layout to Japanese and Microsoft
+ IME (the default one). Set the input method to full katakana, assure
+ your remote-viewer is using this method and start pressing
+ alphabetical keys. On the guest (open a terminal, an editor or
+ a word processor to make easier) you won't see any character.
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-06-15 Christophe Fergeau <cfergeau@redhat.com>
+
+ main: Don't delay update_display_timer(0) for up to 1 second
+ When using remote-viewer --full-screen with a VM/client with multiple
+ monitors, a race can be observed during auto-configuration. First, the
+ client monitors config is sent to the guest:
+ (remote-viewer:19480): GSpice-DEBUG: channel-main.c:1166 main-1:0: sending new monitors config to guest
+ (remote-viewer:19480): GSpice-DEBUG: channel-main.c:1183 main-1:0: monitor #0: 1920x1080+0+0 @ 32 bpp
+ (remote-viewer:19480): GSpice-DEBUG: channel-main.c:1183 main-1:0: monitor #1: 1920x1080+1920+0 @ 32 bpp
+
+ Then we receive messages from the agent which trigger a call to
+ update_display_timer(0)
+
+ This should cause the current monitors state to be sent to the server
+ very soon after this call. However, in the racy case, this is delayed
+ for nearly a second, and timer_set_display() ends up being called at the
+ wrong time, when information about the first display channel have been
+ received from the server, but not the second one.
+
+ When this happens, we inform the server that only one monitor is active,
+ then the server sends a MonitorsConfig message with 2 monitors (first
+ request we sent), and then with just 1 monitor (second request we sent).
+
+ This causes remote-viewer to show one fullscreen black window indicating
+ "Connected to server" on one monitor and a working fullscreen window on
+ the second monitor.
+
+ update_display_timer(0) schedules a timeout to be run with
+ g_timeout_add_seconds(0). However, g_timeout_add_seconds() schedules
+ timers with a granularity of a second, so the timeout we scheduled with
+ g_timeout_add_seconds() may fire up to 1 second later than when we
+ called it, while we really wanted it to fire as soon as possible.
+ Special-casing update_display_timer(0) and using g_timeout_add() in that
+ case avoid this issue. In theory, the race could probably still happen
+ with a very very bad timing, but in practice I don't think it will be
+ possible to trigger it after this change.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=1323092
+
+2016-06-15 Alexander Bokovoy <abokovoy@redhat.com>
+
+ sasl: fix SASL GSSAPI by allowing NULL username
+ SASL GSSAPI module will try to negotiate authentication based on the
+ credentials in the default credentials cache. It does not matter if
+ SPICE knows username or not as SASL negotiation will pass through the
+ discovered name from the GSSAPI module.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+2016-06-13 Frediano Ziglio <fziglio@redhat.com>
+
+ Remove some warnings compiling for Windows
+ GetLastError returns a DWORD which is a "unsigned long" on Windows
+ so use "%lu" formatting instead of "%u".
+
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+2016-06-13 Pavel Grunt <pgrunt@redhat.com>
+
+ channel-display: Remove deprecated init functions
+ They are called at the construct time since spice-common commit:
+ 5b6be16b37370bb774aa3c2a7d5c41791fdc3a1e
+
+ tests-uri: Define g_assert_nonnull
+ It is available since Glib 2.40
+
+ Require gtk+ 3.12
+ Allow to use gtk_stack_get_child_by_name
+
+2016-06-13 Frediano Ziglio <fziglio@redhat.com>
+
+ widget: Do not mix function linkage
+ This prevents a possible crash on windows 32 bit.
+ The linkage of UnhookWindowsHookEx is WINAPI which is __stdcall while
+ callback for g_clear_pointer is C. This could cause stack pointer
+ corruption depending on compiler flags.
+ On __stdcall linkage function change the stack pointer while returning
+ from a function removing the parameters. On C linkage function leave
+ the stack pointer unchanged. So if the compiler call a __stdcall
+ function as a C function it expect the stack pointer to be unchanged
+ causing the pointer to be inconsistent by an offset.
+
+2016-06-09 Frediano Ziglio <fziglio@redhat.com>
+
+ widget: Do not ignore unsupported keys from keyboard
+ If Windows layout does not support a given key the resulting virtual code
+ is set to 0xFF. To avoid losing this raw key (causing the key not been
+ sent to remote machine) detect this condition and handle the key.
+ The check for raw scancode is there to understand if we can handle
+ correctly the key in following code.
+ This problem can happen for instance using a 106 key Japanese keyboard
+ while the layout is set in English; in this case keys like CONVERT not
+ forwarded correctly.
+
+ Some note on how to reproduce and test this problem.
+
+ Physical way:
+ 1- get a 106 key Japanese keyboard for your Windows client machine;
+ 2- setup your client to English keyboard layout;
+ 3- connect to a Linux machine (no matter the distro or version or
+ keyboard configuration);
+ 4- open "xinput test-xi2 <device>" command on Linux (device is
+ the "AT" device in this case);
+ 5- press CONVERT or other keys not present on an English keyboard.
+
+ Virtual way (Windows machine on a VM):
+ - set machine remote to VNC;
+ - assure Qmeu has lock-key-sync=off option to vnc;
+ - connect to Windows machine with a VNC client (I suggest TigerVNC
+ as remote-viewer do some keyboard insertion);
+ - do steps 2, 3, 4 above
+ - press the CONVERT key. If you don't have you can simulate, either
+ - change VNC client code to insert scancode 0x70 instead of another
+ key and press this key;
+ - disconnect main VNC client and use some tool to inject keys
+ (I use a modifier version of vncdotool).
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-06-06 Francois Gouget <fgouget@codeweavers.com>
+
+ streaming: Use the frame dimensions reported by the video decoder
+ The dimensions sent by the remote end are redundant and should not be
+ trusted.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-06-06 Pavel Grunt <pgrunt@redhat.com>
+
+ widget: Avoid using GDK_GRAB_FAILED defined in Gtk 3.16.
+ The returned value from do_pointer_grab() is treated as a boolean - grab
+ was successful or not. Change the function to return a boolean value.
+
+ Reported-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+ Acked-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+
+ mingw: Fix -Werror format & missing-prototypes
+ -Wmissing prototypes were enabled in d5e3a4a5c34fc4408298e824872c4ed511b4bb3c
+ format warnings were added in da8ecf1f95382e8c12fd14915f471a3e76e4b178
+
+2016-06-03 Pavel Grunt <pgrunt@redhat.com>
+
+ spicy: Do not show underscore in label
+ Acked-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+
+2016-06-02 Pavel Grunt <pgrunt@redhat.com>
+
+ spice-uri: Add ipv6 support
+ Just basic support - http://user:password@[host]:port
+
+ Resolves: rhbz#1335239
+
+ spice-uri: Validate uri scheme
+ Related: rhbz#1335239
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ spice-uri: Check if port is in allowed range
+ Use g_ascii_strtoll because it helps to detect overflow.
+
+ Related: rhbz#1335239
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ spice-uri: Do not allow empty port string
+ Related: rhbz#1335239
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ spice-uri: Reset SpiceURI before parsing
+ Avoid using old values after parsing a new uri.
+
+ Related: rhbz#1335239
+
+ tests: Add test for SpiceURI
+ Related: rhbz#1335239
+
+2016-06-01 Francois Gouget <fgouget@codeweavers.com>
+
+ streaming: Tweak the GStreamer decoder to avoid a compiler warning
+ We check that there is a matching frame in the queue before popping the
+ old ones. So we know the inner loop will find a match and thus that
+ frame will not be NULL. But figuring that out is too hard for the
+ compiler.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+ Reported-by: Marc-André Lureau <marcandre.lureau@gmail.com>
+
+2016-06-01 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ build-sys: update manywarnings.m4
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ build-sys: -Wshift-overflow=2
+ manywarnings.m4 update will bring new flags that fail with some
+ glib/gst headers.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ Fix many -Werror=format warnings
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ build-sys: remove -Wmissing-declarations
+ The warning doesn't show up anymore.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-06-01 Victor Toso <victortoso@redhat.com>
+
+ channel: avoid crash on spice_channel_wakeup due NULL channel
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ tests: fix build with smartcard enabled
+ In file included from
+ ../spice-common/common/client_marshallers.h:29:0,
+ from ../src/spice-channel-priv.h:35,
+ from ../src/spice-file-transfer-task-priv.h:28,
+ from file-transfer.c:3:
+ ../spice-common/common/messages.h:45:23: fatal error: libcacard.h: No such file or directory
+ compilation terminated.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-05-31 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ doc: fix unused declarations
+ Fix all the gtk-doc: "unused declarations. They should be added to
+ spice-gtk-sections.txt in the appropriate place."
+
+ doc: add some missing block comments
+
+ Fix non gtk-doc comments
+ Fixes the following warning:
+ ../../src/vmcstream.c:124: warning: Symbol name not found at the start of the comment block.
+ ../../src/win-usb-driver-install.c:347: warning: Symbol name not found at the start of the comment block.
+
+ build-sys: remove some gtk+ 2.0 warnings flags
+ As we dropped gtk+ 2.0 anyway.
+
+ build-sys: enable -Wmissing-prototypes
+ Turns out it is possible to fix the warnings now.
+
+2016-05-31 Pavel Grunt <pgrunt@redhat.com>
+
+ Update README
+ Remove gtk2 related stuff.
+ Recommend dnf for installing dependencies.
+
+ spice-uri: Mark parameter as unused
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-05-28 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ main: remove unneeded gtk-doc comments
+ They are no longer in the doc, and not really useful anyway
+
+ main: remove SpiceFileTransferTaskPrivate
+ The struct is already private
+
+2016-05-27 Victor Toso <victortoso@redhat.com>
+
+ file-xfer: make handle_status agnostic of channel-main
+ This make possible to rename the function to
+ spice_file_transfer_task_handle_status as a handler for
+ VDAgentFileXferStatusMessage for a specific task.
+
+ This change is related to split SpiceFileTransferTask from
+ channel-main.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+2016-05-25 Francois Gouget <fgouget@codeweavers.com>
+
+ streaming: Constify the video stream's dest and clip parameters
+ They are only supposed to be changed when receiving the relevant server
+ message.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-05-25 Pavel Grunt <pgrunt@redhat.com>
+
+ file-transfer-task: Hide internals of SpiceFileTransferTask
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+ file-trasfer-task: Protect header include
+ As stated in the commit d2f33178c40ac51b1c8b1bf796a328631d9869c7 Glib
+ applications should only include "spice-client.h".
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+2016-05-25 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ egl: fix delayed widget realize
+ When the display is not yet realized, spice_display_widget_gl_scanout()
+ will fail because the egl context is not ready. The display is never
+ marked ready because the egl.image (and egl.scanout) is not set, and
+ some clients, such as virt-viewer will not realize the widget until the
+ display is ready.
+
+ Deal with gl scanout updates when the widget is not yet realized, and
+ mark the display as ready when egl is enabled (when last display draw
+ signal is from gl).
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ gtk: remove unneeded check
+ spice_cairo_draw_event() can deal with d->canvas.surface == NULL.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ gtk: rename spicex_* functions
+ spice-gtk used to have x11/shm backend, now it's only cairo
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ gtk: move canvas related data in its own structure
+ Group canvas related data to a sub-structure.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ egl: bind the scanout texture
+ glEGLImageTargetTexture2DOES() changes the current bound texture. If
+ the last texture bound is the cursor, update_scanout() will modify the
+ cursor texture, instead of the display.
+
+ Fix regression from commit 3539ac6212d506128bd38aad032e0363e78cb4f6.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ display: lower to debug gstreamer codec support
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-05-25 Pavel Grunt <pgrunt@redhat.com>
+
+ spice-widget: Use correct enum value
+ GDK_GRAB_BROKEN is not GdkGrabStatus value, but GdkEventType
+
+2016-05-24 Pavel Grunt <pgrunt@redhat.com>
+
+ Update spice-common submodule
+ Fixes lz decompression crash:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1285469
+
+ Christophe Fergeau (5):
+ Remove 2 unused vfuncs from client_marshallers.h
+ tests: Fix glib version check
+ log: Clamp SPICE_DEBUG_LEVEL if it's too high
+ log: Use SPICE_CONSTRUCTOR_FUNC
+ log: Make sure glib threading is initialized
+
+ Eduardo Lima (Etrunko) (2):
+ Fix build in systems with Glib version older than 2.38
+ 2/2] Add check for openssl
+
+ Fabiano Fidêncio (7):
+ coverity: avoid use after free
+ coverity: avoid resource leak
+ coverity: avoid dereference after null check
+ coverity: avoid division or modulo by zero
+ coverity: remove unused value
+ coverity: remove structurally dead code
+ Use g_getenv() instead of getenv()
+
+ Frediano Ziglio (6):
+ Cap logging level to the valid bounds
+ tests: exit on SIGABRT
+ define SPICE_CONSTRUCTOR_FUNC and SPICE_DESTRUCTOR_FUNC macros
+ use macro to define constructor function
+ fix 16 bpp LZ image decompression
+ Explicitly specify size of SpiceMsgSmartcardData
+
+ Lin Ma (1):
+ build-sys: Define opengl GL_LIBS and GL_CFLAGS in generated Makefile.in
+
+ Pavel Grunt (3):
+ Define canvas_fix_alignment when is used
+ test-logging: Include stdlib.h for _Exit()
+ Remove GL support
+
+ Update .mailmap
+
+2016-05-23 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ egl: set current context, fix multiple display
+ On X11, each widget has its own context. Make sure we are using the
+ widget associated context when using gl.
+
+ With gtk 3.16, glEGLImageTargetTexture2DOES() can be called during
+ update scanout, since we can call gtk_gl_area_make_current(). On < 3.16,
+ do it before drawing.
+
+ Fixes:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1337721
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ egl: don't terminate display
+ This is global to the display connection: all egl resources will be
+ released, including those from other widgets or from the application.
+
+ Fix spice/virgl display being rendered black after another widget
+ display is destroyed.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ egl: don't destroy wayland egl context
+ The egl context is from Gtk on Wayland. Destroy it only on X11.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ egl: only swap buffers on x11
+ Gtk does it for us already with GtkGlArea.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ channel: check if channel has a session
+ Since 8943d2329, the channel may be disconnected from the session
+ before it's destroyed. In this case, session is NULL.
+
+ Fixes some critical with virt-manager when closing a display:
+
+ (virt-manager:20451): GSpice-CRITICAL **: spice_session_is_for_migration: assertion 'SPICE_IS_SESSION(session)' failed
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ util: remove STATIC_MUTEX macros
+ They are no longer needed since 0a9ec4ec0.
+
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+2016-05-19 Frediano Ziglio <fziglio@redhat.com>
+
+ Spice-widget: Use new gdk_event_get_scancode if available
+ This new Gdk API allows in Windows to retrieve the raw scancodes sent
+ by Windows.
+ This allows us to do some translations getting the right value without
+ many hacks and supporting all possible layouts.
+ Windows convert the scancodes into virtual key codes. The translation is
+ 1 -> N based on different condition. Also a single virtual key code can
+ be originated from different scancodes. This make quite complicated
+ (if not impossible) to get the original scancode from the hardware_keycode
+ field (which in Windows is the virtual key).
+ The additional check for native_scancode after calling this function
+ allows to support key injection.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-05-18 Francois Gouget <fgouget@codeweavers.com>
+
+ streaming: Use decodebin as a fallback for the GStreamer video decoder
+ This means future video codecs may be supported automatically.
+ One can also force usage of decodebin by setting $SPICE_GSTVIDEO_AUTO.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ streaming: Probe GStreamer before advertising support for a codec
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ streaming: Allow disabling support for the builtin MJPEG video decoder
+ This makes it possible to test the GStreamer video decoder with MJPEG
+ streams.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ streaming: Add a GStreamer video decoder for MJPEG, VP8 and h264
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ streaming: Let the video decoder queue, schedule and drop the frames
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-05-16 Victor Toso <victortoso@redhat.com>
+
+ file-xfer: fix segfault on agent disconnection
+ We are checking self->priv->error but accessing the argument GError *
+ which is NULL and leads to a segfault.
+
+ Program received signal SIGSEGV, Segmentation fault.
+ spice_file_transfer_task_completed (self=self@entry=0x7fffd0006f00, error=0x0) at channel-main.c:2963
+ 2963 VDAgentFileXferStatusMessage msg = {
+ (gdb) bt
+ #0 spice_file_transfer_task_completed (self=self@entry=0x7fffd0006f00, error=0x0) at channel-main.c:2963
+ #1 in file_xfer_data_flushed_cb (source_object=0x7cc1d0, res=0x953390, user_data=user_data@entry=0x7fffd0006f00) at channel-main.c:1857
+ #2 in g_task_return_now (task=0x953390) at gtask.c:1108
+ #3 in g_task_return (task=0x953390, type=<optimized out>) at gtask.c:1166
+ #4 in flush_foreach_remove (key=<optimized out>, value=<optimized out>, user_data=<optimized out>) at channel-main.c:928
+ #5 in g_hash_table_foreach_remove_or_steal (hash_table=0x70cea0, func=func@entry=0x7ffff5616f10 <flush_foreach_remove>, user_data=user_data@entry=0x0, notify=notify@entry=1) at ghash.c:1492
+ #6 in g_hash_table_foreach_remove (hash_table=<optimized out>, func=func@entry=0x7ffff5616f10 <flush_foreach_remove>, user_data=user_data@entry=0x0) at ghash.c:1538
+ #7 in file_xfer_flushed (success=0, channel=0x7cc1d0) at channel-main.c:936
+ #8 spice_main_channel_reset_agent (channel=0x7cc1d0) at channel-main.c:466
+ #9 set_agent_connected (channel=0x7cc1d0, connected=connected@entry=0) at channel-main.c:1572
+ #10 in spice_main_channel_reset (channel=0x7cc1d0, migrating=0) at channel-main.c:485
+ #11 in spice_channel_coroutine (data=0x7cc1d0) at spice-channel.c:2564
+ #12 in coroutine_trampoline (cc=0x7cb860) at coroutine_ucontext.c:63
+ #13 in continuation_trampoline (i0=<optimized out>, i1=<optimized out>) at continuation.c:55
+ #14 in ?? () from /lib64/libc.so.6
+ #15 in ?? ()
+ #16 in ?? ()
+ Backtrace stopped: Cannot access memory at address
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+2016-05-13 Victor Toso <victortoso@redhat.com>
+
+ file-xfer: fix file path leak
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+2016-05-13 Pavel Grunt <pgrunt@redhat.com>
+
+ doc, gir: Clarify availability of skip spice_get_option_group
+ Commit c288627110bbec1aba48b0bf91ce7ab4b12f70b3 made the function
+ available for other languages through gobject introspections. Mention
+ the change in the function description.
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-05-12 Pavel Grunt <pgrunt@redhat.com>
+
+ spicy: Add option to control syncing modifiers
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+ spice-gtk-session: Add sync modifiers property
+ It will help in cases where syncing modifiers keys is complicated:
+ * not working leds for modifiers keys
+ * different keyboard layout on the guest side
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+2016-05-10 Victor Toso <victortoso@redhat.com>
+
+ spicy: fix leak of transfer hash table
+ 184 (88 direct, 96 indirect) bytes in 1 blocks are definitely lost in
+ loss record 10,025 of 11,515 at 0x4C28BF6: malloc
+ (vg_replace_malloc.c:299)
+ by 0x9D33218: g_malloc (gmem.c:94)
+ by 0x9D49D02: g_slice_alloc (gslice.c:1025)
+ by 0x9D1CCBD: g_hash_table_new_full (ghash.c:711)
+ by 0x406196: connection_new (spicy.c:1693)
+ by 0x405BFE: main (spicy.c:1852)
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-05-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ spicy: add toggle mouse mode menu
+ This is just for testing, the UI could be different in better clients.
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ main: do not always request client mouse mode
+ Whenever the mouse mode changed on the server, spice-gtk was requesting
+ client mode. Instead keep the last requested mode and request it
+ whenever it's possible.
+
+ Reviewed-by: Victor Toso <victortoso@redhat.com>
+
+ gtk: add spice_main_request_mouse_mode()
+ Send a SpiceMsgcMainMouseModeRequest message to request a mouse mode.
+
+ This allows to switch between client/absolute and server/relative mouse
+ modes.
+
+ This is necessary for some applications that require pointer
+ re-positioning, which we can't provide through a remote protocol easily
+ with client pointer (no such hardware-level message exists afaik).
+
+ Reviewed-by: Victor Toso <victortoso@redhat.com>
+
+2016-05-09 Francois Gouget <fgouget@codeweavers.com>
+
+ streaming: Rename num_drops_on_receive to arrive_late_count
+ The frame may not get dropped once that's left up to video decoders.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ streaming: Optimize handling of the decoded frame buffer
+ The MJPEG decoder does not need a zero-filled buffer.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ streaming: Enable adding alternative video decoders
+ This replaces the original channel-display-mjpeg API with a VideoDecoder
+ base class which can be reimplemented by other decoders.
+ Furthermore this moves the MJPEG-specific state information from the
+ display_stream struct to a derived class of VideoDecoder.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-05-04 Visarion-Mingopol Alexandru <viorel.visarion@gmail.com>
+
+ doc,gir: Don't skip spice_get_option_group()
+ There is no reason to not include the spice_get_option_group
+ method in the generated bindings, as it can be useful.
+
+ It was removed in the commit 2db9b8dd037e22d2b04e8e2aeecfd685524b7fef,
+ for the reason of causing warnings, but no warnings show up now.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+2016-05-04 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ gtk: fix server-mode mouse
+ Since switching to gtkstack, server-side mouse mode has some issues with
+ grabs. There seems to be some grab gtk+ issue, but it seems to fall
+ under the API user responsability to have its own window when dealing
+ with pointer grabs. And gtk+ commit 9d0e8401c (Turn stack into no-window
+ widget) made things worse.
+
+ Making the widget an eventbox solves the grab issue.
+
+ Fixes:
+ https://bugs.freedesktop.org/show_bug.cgi?id=94764
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-05-03 Victor Toso <victortoso@redhat.com>
+
+ spice-channel: fix small leak
+ 182 bytes in 1 blocks are definitely lost in loss record 9,048 of 9,889
+ at 0x4C2A988: calloc (vg_replace_malloc.c:711)
+ by 0xB5F4270: g_malloc0 (gmem.c:124)
+ by 0x7320678: spice_channel_recv_link_hdr (spice-channel.c:1312)
+ by 0x7320678: spice_channel_coroutine (spice-channel.c:2543)
+ by 0x7355A4E: coroutine_trampoline (coroutine_ucontext.c:63)
+ by 0x7355802: continuation_trampoline (continuation.c:55)
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+ spicevmc: don't disconnect on "cancel"
+ spicevmc was designed so its _finish functions should always be called;
+ With the gtask integration both _finish functions are trying to
+ disconnect the GCancellable even in the 'cancel' context which leads to
+ a deadlock as explained in the documentation.
+
+ Resolves: https://bugs.freedesktop.org/show_bug.cgi?id=95032
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+2016-05-02 Pavel Grunt <pgrunt@redhat.com>
+
+ channel: Abort migration in delayed unref
+ When channel is unref'ed during migration migrate_channel_event_cb
+ is called causing a crash by coroutine yielding to nonexistent channel.
+
+ The delayed_unref happens for the target host channel and will only occur
+ when the migration process fails.
+
+ As comment in spice_channel_coroutine says:
+ Co-routine exits now - the SpiceChannel object may no longer exist,
+ so don't do anything else now unless you like SEGVs
+
+ Related: rhbz#1318574
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ Do not use deprecated GtkStock
+ Use labels or named icons
+
+ Deprecated since Gtk 3.10
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-05-02 Fabiano Fidêncio <fidencio@redhat.com>
+
+ coverity: identical code for different branches
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ coverity: avoid out of bounds access
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-04-27 Pavel Grunt <pgrunt@redhat.com>
+
+ channel-main: Use CHANNEL_DEBUG for migration events
+ To show which channel got an error or an unhandled event
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-04-22 Javier Celaya <javier.celaya@flexvdi.com>
+
+ Spice-widget: Allow smaller widget with scaling enabled
+ When resize-guest-to-match-window-size is disabled, the size request
+ (minimum size) of the spice widget is set to the current guest
+ resolution. The client window cannot be made smaller, even with
+ scale-display enabled.
+
+ This patch sets a size request of 640x480 when either
+ resize-guest-to-match-window-size OR scale-display are enabled, making
+ it posible to shrink the window and scale down the display.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-04-18 Takao Fujiwara <tfujiwar@redhat.com>
+
+ Send Hangul key in KR keyboard
+ Korean keyboard assigns Hangul key on the position of Right Alt and
+ Left Alt and Hangul keys have the different scancodes but MapVirtualKey()
+ returned the same scancode and could not use Hangul key on Linux desktop.
+
+ The fix is to send the right scancode of VK_HANGUL.
+
+ Send key release event for some keys in JP keyboard
+ With the previous fix, WM_KEYDOWN of Alt+Zenkaku_Hankaku (VK_KANJI) can
+ be sent with spice-gtk but Alt+Zenkaku_Hankaku does not send the WM_KEYUP
+ event in Windows and it caused Linux desktop freeze with unlimited key
+ press events.
+
+ The proposed fix is to send the key release event in spice-gtk.
+
+ VK_DBE_ALPHANUMERIC, VK_DBE_HIRAGANA, VK_DBE_ROMAN are applied the
+ similar fixes.
+
+ Send Zenkaku_Hankaku key in JP keyboard
+ Zenkaku_Hankaku key has the different virtual-key codes between WM_KEYDOWN
+ and WM_KEYUP and MapVirtualKey() cannot get the scancode from virtual-key
+ code of WM_KEYDOWN (VK_DBE_DBCSCHAR) and spice-gtk didn't send the key
+ press events and caused the desktop freeze with unlimited key release
+ events.
+
+ The fix is to get the scancode from virtual-key code of WM_KEYUP
+ (VK_DBE_SBCSCHAR) and Zenkaku_Hankaku key works fine.
+
+ Alt + Zenkaku_Hankaku key also has the different virtual-key code and
+ MapVirtualKey() cannot get the scancode from the virtual-key and
+ spice-gtk didn't send the key press events and Alt+Zenkaku_Hankaku
+ could not be used.
+
+ The fix is to get the scancode from virtual-key code of Zenkaku_Hankaku key
+ (VK_DBE_SBCSCHAR).
+
+ VK_CAPITAL, VK_DBE_ROMAN are also applied the similar fixes.
+
+2016-04-15 Pavel Grunt <pgrunt@redhat.com>
+
+ channel-main: Move variable to block where is needed
+
+ channel-main: Add helper function for getting audio
+ Avoid repeating the same code and having a SpiceSession variable
+ defined when is not really needed.
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-04-08 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Ensure that file transfers get cancelled
+ When canceling a file transfer task in spicy, the client would often
+ stop sending additional data, but it would not send a "CANCELLED"
+ message to the guest. Because of this, the partial file would remain in
+ the guest's downloads folder until the spice client disconnected, at
+ which point the vdagent would remove the unfinshed file.
+
+ This CANCELLED status message was only being sent if the task was
+ canceled during the async file read operation. If you cancel a task,
+ it's quite likely that it will happen during other operations
+ (e.g. file_xfer_flush_async(), etc). In order to handle these scenarios
+ (and make sure that the file gets canceled properly), send the
+ FILE_XFER_STATUS message in spice_file_transfer_task_completed().
+
+2016-04-07 Pavel Grunt <pgrunt@redhat.com>
+
+ Do not call spice_egl_cursor_set when egl is disabled
+ Fix memory leaks of cursor:
+
+ 240 bytes in 1 blocks are possibly lost in loss record 10,786 of 12,521
+ at 0x4C2FA60: calloc (vg_replace_malloc.c:711)
+ by 0x3700F861: ralloc_size (ralloc.c:113)
+ by 0x36FD2D68: UnknownInlinedFun (list.h:83)
+ by 0x36FD2D68: (anonymous namespace)::builtin_variable_generator::add_const(char const*, int) (builtin_variables.cpp:578)
+ by 0x36FD4775: generate_constants (builtin_variables.cpp:725)
+ by 0x36FD4775: _mesa_glsl_initialize_variables(exec_list*, _mesa_glsl_parse_state*) (builtin_variables.cpp:1303)
+ by 0x36E03D26: create_new_program (ff_fragment_shader.cpp:1225)
+ by 0x36E03D26: _mesa_get_fixed_func_fragment_program (ff_fragment_shader.cpp:1295)
+ by 0x36E9A577: update_program (state.c:157)
+ by 0x36E9A577: _mesa_update_state_locked (state.c:473)
+ by 0x36E9A6A0: _mesa_update_state (state.c:504)
+ by 0x36EB05E4: teximage (teximage.c:2947)
+ by 0x36EB211F: _mesa_TexImage2D (teximage.c:3009)
+ by 0x4E5024F: spice_egl_cursor_set (spice-widget-egl.c:497)
+ by 0x4E4BFD7: cursor_set (spice-widget.c:2346)
+ by 0x50D6245: g_cclosure_user_marshal_VOID__INT_INT_INT_INT_POINTER (spice-marshal.c:245)
+
+ Use g_clear_pointer if possible
+ Acked-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+
+ Use g_clear_object if possible
+ Acked-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+
+ Use g_object_unref instead of gdk_cursor_unref
+ GdkCursor is GObject and gdk_cursor_unref has been deprecated since 3.0
+
+ Acked-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+
+ Use GMutex instead of GStaticMutex
+ Since GLib 2.32 GMutex can be statically allocated, so GStaticMutex has
+ been deprecated.
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+ Use GDK_VERSION_MAX_ALLOWED
+ In order to avoid using a too new Gtk API.
+
+ Taken from virt-viewer 4c4a43c61db60ac815c0bc66730fa0a9a1571103
+
+ Acked-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+
+ Use GLIB_VERSION_MAX_ALLOWED
+ In order to avoid using a too new GLib API.
+
+ Taken from virt-viewer 96d120903f0b95d49642e58d4f796b4f62aa8b20
+
+ Acked-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+
+2016-04-02 Pavel Grunt <pgrunt@redhat.com>
+
+ widget-egl: Define label only if can be used
+ The label can be used only with GDK_WINDOWING_WAYLAND
+
+ Silence -Wunused-label
+
+2016-03-30 Pavel Grunt <pgrunt@redhat.com>
+
+ doc: Add description for spice_display_get_gl_scanout()
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+ doc: Ignore spicy-connect
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+ spice-file-transfer-task: Fix docstring
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+ doc: channel stability should be Stable
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+ doc: Remove private structs
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+ usb-device-manager: Fix docstring
+ Add description, "Since" and change the parameter name in the docstring
+ to match parameter name in the function definition.
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-03-30 Christophe Fergeau <cfergeau@redhat.com>
+
+ build-sys: Update symbol files
+ The OSX-specific symbol files were not updated after the recent API
+ additions/removals, and some removed symbols were still listed in
+ map-file.
+
+2016-03-30 Victor Toso <victortoso@redhat.com>
+
+ egl: fix leak when display is unrealize
+ eglTerminate should be called on unrealize. This not yet fix all the
+ leaks but reduces it significantly from 318kb to 74kb as definitely lost
+ and around 1mb to 8kb as indirectly lost.
+
+ 4,096 bytes in 1 blocks are definitely lost in loss record
+ 9,762 of 9,882
+ at 0x35B19E40: drm_intel_gem_bo_map (intel_bufmgr_gem.c:1454)
+ by 0x35688320: can_write_oacontrol (intel_extensions.c:121)
+ by 0x35688320: intelInitExtensions (intel_extensions.c:279)
+ by 0x35651380: brwCreateContext (brw_context.c:875)
+ by 0x35602720: driCreateContextAttribs (dri_util.c:426)
+ by 0xF0C48B1: dri2_create_context (egl_dri2.c:1072)
+ by 0xF0BE727: eglCreateContext (eglapi.c:638)
+ by 0x5461D27: spice_egl_init (spice-widget-egl.c:256)
+ by 0x545B885: drawing_area_realize (spice-widget.c:581)
+ by 0xB431784: g_closure_invoke (gclosure.c:804)
+ by 0xB443A40: signal_emit_unlocked_R (gsignal.c:3629)
+ by 0xB44C92E: g_signal_emit_valist (gsignal.c:3385)
+ by 0xB44CC51: g_signal_emit (gsignal.c:3441)
+
+ 4,856 (32 direct, 4,824 indirect) bytes in 1 blocks are definitely lost
+ in loss record 9,779 of 9,882
+ at 0x4C2A988: calloc (vg_replace_malloc.c:711)
+ by 0xF0BEEF7: _eglCreateArray (eglarray.c:71)
+ by 0xF0BF420: _eglLinkConfig (eglconfig.c:90)
+ by 0xF0C4F8D: dri2_add_config (egl_dri2.c:307)
+ by 0xF0C66EE: dri2_x11_add_configs_for_visuals (platform_x11.c:766)
+ by 0xF0C80EC: dri2_initialize_x11_dri3 (platform_x11.c:1319)
+ by 0xF0C80EC: dri2_initialize_x11 (platform_x11.c:1464)
+ by 0xF0C18FE: _eglMatchAndInitialize (egldriver.c:261)
+ by 0xF0C19B8: _eglMatchDriver (egldriver.c:292)
+ by 0xF0BDD31: eglInitialize (eglapi.c:482)
+ by 0x5461A76: spice_egl_init (spice-widget-egl.c:226)
+ by 0x545B885: drawing_area_realize (spice-widget.c:581)
+ by 0xB431784: g_closure_invoke (gclosure.c:804)
+
+ 5,921 (472 direct, 5,449 indirect) bytes in 1 blocks are definitely lost
+ in loss record 9,794 of 9,882
+ at 0x4C2A988: calloc (vg_replace_malloc.c:711)
+ by 0xF0C7E0E: dri2_initialize_x11_dri3 (platform_x11.c:1267)
+ by 0xF0C7E0E: dri2_initialize_x11 (platform_x11.c:1464)
+ by 0xF0C18FE: _eglMatchAndInitialize (egldriver.c:261)
+ by 0xF0C19B8: _eglMatchDriver (egldriver.c:292)
+ by 0xF0BDD31: eglInitialize (eglapi.c:482)
+ by 0x5461A76: spice_egl_init (spice-widget-egl.c:226)
+ by 0x545B885: drawing_area_realize (spice-widget.c:581)
+ by 0xB431784: g_closure_invoke (gclosure.c:804)
+ by 0xB443A40: signal_emit_unlocked_R (gsignal.c:3629)
+ by 0xB44C92E: g_signal_emit_valist (gsignal.c:3385)
+ by 0xB44CC51: g_signal_emit (gsignal.c:3441)
+ by 0x5D2C9DB: gtk_widget_realize (gtkwidget.c:5454)
+
+ 16,384 bytes in 4 blocks are definitely lost in loss record 9,854 of 9,882
+ at 0x35B19E40: drm_intel_gem_bo_map (intel_bufmgr_gem.c:1454)
+ by 0x3568AB30: intel_miptree_map_raw (intel_mipmap_tree.c:2149)
+ by 0x3568CEE6: intel_miptree_map_gtt (intel_mipmap_tree.c:2182)
+ by 0x3568CEE6: intel_miptree_map (intel_mipmap_tree.c:2774)
+ by 0x35692851: intel_map_texture_image (intel_tex.c:227)
+ by 0x35447C3B: store_texsubimage (texstore.c:1069)
+ by 0x35447E9F: _mesa_store_teximage (texstore.c:1125)
+ by 0x3543D9BA: _mesa_get_fallback_texture (texobj.c:1056)
+ by 0x35443E1E: UnknownInlinedFun (texstate.c:562)
+ by 0x35443E1E: update_program_texture_state (texstate.c:587)
+ by 0x35443E1E: UnknownInlinedFun (texstate.c:726)
+ by 0x35443E1E: _mesa_update_texture (texstate.c:757)
+ by 0x35420809: _mesa_update_state_locked (state.c:430)
+ by 0x35420ED0: _mesa_update_state (state.c:504)
+ by 0x3535BF87: _mesa_Clear (clear.c:172)
+ by 0x546214F: spice_egl_update_display (spice-widget-egl.c:514)
+
+ 32,768 bytes in 1 blocks are definitely lost in loss record 9,864 of 9,882
+ at 0x35B19E40: drm_intel_gem_bo_map (intel_bufmgr_gem.c:1454)
+ by 0x35683E3C: intel_batchbuffer_reset (intel_batchbuffer.c:68)
+ by 0x35684052: brw_new_batch (intel_batchbuffer.c:164)
+ by 0x35684052: _intel_batchbuffer_flush.part.2 (intel_batchbuffer.c:397)
+ by 0x3568853B: can_write_oacontrol (intel_extensions.c:153)
+ by 0x3568853B: intelInitExtensions (intel_extensions.c:279)
+ by 0x35651380: brwCreateContext (brw_context.c:875)
+ by 0x35602720: driCreateContextAttribs (dri_util.c:426)
+ by 0xF0C48B1: dri2_create_context (egl_dri2.c:1072)
+ by 0xF0BE727: eglCreateContext (eglapi.c:638)
+ by 0x5461D27: spice_egl_init (spice-widget-egl.c:256)
+ by 0x545B885: drawing_area_realize (spice-widget.c:581)
+ by 0xB431784: g_closure_invoke (gclosure.c:804)
+ by 0xB443A40: signal_emit_unlocked_R (gsignal.c:3629)
+
+ 32,768 bytes in 1 blocks are definitely lost in loss record 9,865 of 9,882
+ at 0x35B19E40: drm_intel_gem_bo_map (intel_bufmgr_gem.c:1454)
+ by 0x35683E3C: intel_batchbuffer_reset (intel_batchbuffer.c:68)
+ by 0x35684052: brw_new_batch (intel_batchbuffer.c:164)
+ by 0x35684052: _intel_batchbuffer_flush.part.2 (intel_batchbuffer.c:397)
+ by 0x356887F3: can_do_pipelined_register_writes (intel_extensions.c:88)
+ by 0x356887F3: intelInitExtensions (intel_extensions.c:338)
+ by 0x35651380: brwCreateContext (brw_context.c:875)
+ by 0x35602720: driCreateContextAttribs (dri_util.c:426)
+ by 0xF0C48B1: dri2_create_context (egl_dri2.c:1072)
+ by 0xF0BE727: eglCreateContext (eglapi.c:638)
+ by 0x5461D27: spice_egl_init (spice-widget-egl.c:256)
+ by 0x545B885: drawing_area_realize (spice-widget.c:581)
+ by 0xB431784: g_closure_invoke (gclosure.c:804)
+ by 0xB443A40: signal_emit_unlocked_R (gsignal.c:3629)
+
+ 98,304 bytes in 3 blocks are definitely lost in loss record 9,872 of 9,882
+ at 0x35B19E40: drm_intel_gem_bo_map (intel_bufmgr_gem.c:1454)
+ by 0x35683E3C: intel_batchbuffer_reset (intel_batchbuffer.c:68)
+ by 0x35684052: brw_new_batch (intel_batchbuffer.c:164)
+ by 0x35684052: _intel_batchbuffer_flush.part.2 (intel_batchbuffer.c:397)
+ by 0x3564F834: intel_glFlush (brw_context.c:259)
+ by 0xF0C3DA0: dri2_make_current (egl_dri2.c:1189)
+ by 0xF0BAB1B: eglMakeCurrent (eglapi.c:703)
+ by 0x546274E: spice_widget_init_egl_win (spice-widget-egl.c:316)
+ by 0x546274E: spice_egl_realize_display (spice-widget-egl.c:333)
+ by 0x545B89F: drawing_area_realize (spice-widget.c:586)
+ by 0xB431784: g_closure_invoke (gclosure.c:804)
+ by 0xB443A40: signal_emit_unlocked_R (gsignal.c:3629)
+ by 0xB44C92E: g_signal_emit_valist (gsignal.c:3385)
+ by 0xB44CC51: g_signal_emit (gsignal.c:3441)
+
+ 131,072 bytes in 4 blocks are definitely lost in loss record 9,874 of 9,882
+ at 0x35B19E40: drm_intel_gem_bo_map (intel_bufmgr_gem.c:1454)
+ by 0x35683E3C: intel_batchbuffer_reset (intel_batchbuffer.c:68)
+ by 0x356848E8: intel_batchbuffer_init (intel_batchbuffer.c:45)
+ by 0x35651337: brwCreateContext (brw_context.c:848)
+ by 0x35602720: driCreateContextAttribs (dri_util.c:426)
+ by 0xF0C48B1: dri2_create_context (egl_dri2.c:1072)
+ by 0xF0BE727: eglCreateContext (eglapi.c:638)
+ by 0x5461D27: spice_egl_init (spice-widget-egl.c:256)
+ by 0x545B885: drawing_area_realize (spice-widget.c:581)
+ by 0xB431784: g_closure_invoke (gclosure.c:804)
+ by 0xB443A40: signal_emit_unlocked_R (gsignal.c:3629)
+ by 0xB44C92E: g_signal_emit_valist (gsignal.c:3385)
+
+ 1,080,655 (284 direct, 1,080,371 indirect) bytes in 1 blocks are
+ definitely lost in loss record 9,881 of 9,882
+ at 0x4C2A988: calloc (vg_replace_malloc.c:711)
+ by 0x355A2221: ralloc_size (ralloc.c:113)
+ by 0x355A227D: rzalloc_size (ralloc.c:134)
+ by 0x355A2BEE: ra_alloc_reg_set (register_allocate.c:196)
+ by 0x356D79AA: brw_alloc_reg_set(brw_compiler*, int) (brw_fs_reg_allocate.cpp:159)
+ by 0x356D817D: brw_fs_alloc_reg_sets (brw_fs_reg_allocate.cpp:305)
+ by 0x356FDACC: brw_compiler_create (brw_shader.cpp:84)
+ by 0x35691995: intelInitScreen2 (intel_screen.c:1495)
+ by 0x35602A5E: driCreateNewScreen2 (dri_util.c:144)
+ by 0xF0C547B: dri2_create_screen (egl_dri2.c:674)
+ by 0xF0C808F: dri2_initialize_x11_dri3 (platform_x11.c:1303)
+ by 0xF0C808F: dri2_initialize_x11 (platform_x11.c:1464)
+ by 0xF0C18FE: _eglMatchAndInitialize (egldriver.c:261)
+
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+2016-03-29 Pavel Grunt <pgrunt@redhat.com>
+
+ doc: Remove dropped functions
+ Dropped in 70a00b8fcc2ca85d3601f6ac4895f906f9032e77
+
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+ widget: Avoid combining ternary with another operators
+ Logical operators like "&&" has higher precedency than "?:".
+ Readiness of SpiceDisplay was wrongly determined due to missing
+ parentheses around the ternary operator.
+
+ Fixes:
+ https://bugs.freedesktop.org/show_bug.cgi?id=94738
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-03-29 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ usb: fix build, missing ')'
+
+2016-03-25 Jonathon Jongsma <jjongsma@redhat.com>
+
+ usb device widget: don't try to disconnect on failed connect
+ When you try to redirect a usb device to the guest and it fails, we
+ uncheck the checkbox for this device. This causes the 'clicked' signal
+ to be emitted, which causes us to try to disconnect the device (which is
+ not currently connected, since the connect operation failed).
+
+ When we try to disconnect an unconnected device, the device manager
+ leaks memory and gets left in an inconsistent state because we allocate
+ the task data, call _set_redirecting(self, TRUE) and then return early
+ with the following warning printed to the terminal:
+
+ (lt-spicy:4638): GSpice-CRITICAL **: spice_usbredir_channel_disconnect_device_async: assertion 'channel != NULL' failed
+
+ To avoid this, disable signal handlers for the checkbox 'clicked'
+ signal while we're changing the checkbox state in response to a
+ connection error. In addition, add an additional check to
+ spice_usb_device_manager_disconnect_device_async() to ensure that the
+ passed device is actually connected.
+
+ SpiceUsbDeviceManager: propagate errors from sub-tasks
+ _connect_device_async_cb() just turned TRUE unconditionally even if the
+ sub-task had failed. Instead, introduce a
+ _spice_usb_device_manager_connect_device_finish() function which passes
+ up the result of the subtask.
+
+2016-03-24 Dmitry Fleytman <dfleytma@redhat.com>
+
+ UsbDeviceManager: Deprecate synchronous disconnection method
+ Asynchronous disconnection should be used instead.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+2016-03-24 Kirill Moizik <kmoizik@redhat.com>
+
+ UsbDeviceWidget: Use asynchronous disconnect API
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ UsbDeviceWidget: Consider asynchronous redirection flows
+ Gray out redirection controls while there are
+ asynchronous redirection flows in progress.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ UsbDeviceWidget: Show info bar during redirection flows
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ usbredir: Disconnect USB device asynchronously
+ Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ UsbDeviceManager: Track device disconnection operations in progress
+ During device disconnection, unwanted hotplug events may happen.
+ We need to ignore those therefore we track disconnection operations
+ in progress.
+
+ See also comment to commit
+ "Do not process USB hotplug events while redirection is in progress"
+ that introduces corresponding filtering out logic.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ UsbDeviceManager: Implement asynchronous disconnect device flow
+ This commit introduces functions for asynchronous disconnection flows.
+ Following commits will make use of those.
+
+ Thread safety is ensured the same way it was done for connection
+ flow in previous commits. Disconnect logic is protected by the same
+ locks that protect connect/usbredir/channel management logic.
+
+ UsbDeviceManager: Track device redirection operations in progress
+ During device connection, unwanted hotplug events may happen.
+ We need to ignore those therefore we track redirection operations
+ in progress.
+
+ See also comment to commit
+ "Do not process USB hotplug events while redirection is in progress"
+ that introduces corresponding filtering out logic.
+
+ usbredir: Spawn a different thread for device redirection flow
+ On Windows when using usbdk, opening and closing USB device handle,
+ i.e. calling libusb_open()/libusb_unref_device() can block for a few
+ seconds (3-5 second more specifically on patch author's HW).
+
+ libusb_open() is called by spice_usbredir_channel_open_device().
+
+ libusb_unref_device() is called implicitly via
+ usbredirhost_set_device(..., NULL) from
+ spice_usbredir_channel_disconnect_device().
+
+ Both these calls happen on the main thread. If it blocks,
+ this causes the UI to freeze.
+
+ This commit makes sure libusb_open() is called from a different
+ thread to avoid blocking the mainloop when usbdk is used.
+
+ Following commits also move usbredirhost_set_device(..., NULL) call
+ to separate threads.
+
+ Since this commit introduces additional execution contexts running in
+ parallel to the main thread there are thread safety concerns to be secured.
+ Mainly there are 3 types of objects accessed by newly introduced threads:
+ 1. libusb contexts
+ 2. usbredir context
+ 3. redirection channels
+
+ Fortunately libusb accesses are either thread safe or already
+ performed by a separate thread and protected by locks as needed.
+
+ As for channels and usbredir, in order to achieve thread safety
+ additional locks were introduced by previous patches
+ in preparation to adding asynchronous contexts:
+
+ 1. Channel objects data accesses from different threads protected with a
+ new lock (device_connect_mutex);
+ 2. Handling usbredir messages protected by the same new lock in order to
+ ensure there are no messages processing flows in progress when device gets
+ connected or disconnected.
+
+ usbredir: Protect data accessed by asynchronous redirection flows
+ This commit adds locking to ensure thread safety required
+ after start/stop redirection flows moved to separate threads.
+ This is done in preparation to following commits that
+ will introduce actual multithreaded access to corresponding
+ routines.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ GUdevClient: Do not process USB hotplug events while redirection is in progress
+ USB redirection flow on Windows includes a number of reset requests issued
+ to the port that hosts the device deing redirected.
+
+ Each port reset emulates device removal and reinsertion and produces
+ corresponding hotplug events and a number of device list updates on
+ different levels of USB stack and USB redirection engine.
+
+ As a result, queriyng USB device list performed by spice-gtk's hotplug
+ event handler may return inconsistent results if performed in parallel
+ to redirection flow.
+
+ This patch suppresses handling of USB hotplug events during redirection
+ and injects a simulated hotplug event after redirection completion
+ in order to properly process real device list changes in case they
+ happened during the redirection flow.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ win-usb-dev: Track device redirection operations in progress
+ This commit introduces redirecting property of GUdevClient
+
+ This property indicates when a redirection operation
+ is in progress on a device. It's set back to FALSE
+ once the device is fully redirected to the guest.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ usbredir: Introduce mutex for device (dis)connection
+ This commit introduces channel mutex to allow usage of
+ channel objects in mutithreaded environments.
+
+ This mutex will be used by future commits to protect
+ thread unsafe usbredir functions and data structures.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+2016-03-24 Dmitry Fleytman <dmitry@daynix.com>
+
+ win-usb-dev: Fix device (un)plug notification handler
+ This patch fixes device list change notification handing
+ logic for cases when more than one device being plugged
+ or unplugged simultaneously.
+
+ The simplest way to reproduce the problematic scenario
+ is (un)plugging of a usb HUB with a few devices inserted.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ usb-dev-manager: Fix cbinfo leak in case of abnormal return
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ win-usbredir: Use UsbDk backend when available
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ win-usbredir: Do not use UsbClerk for non-WinUsb backends
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ win-usbredir: Move installer interaction logic to separate functions
+ This is a refactoring done in preparation for the next commits.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ usbdk: Load hide rules for auto-redirected devices
+ Hide rules order UsbDk to avoid showing specific USB
+ devices to Windows PnP manager.
+
+ Spice-gtk loads hide rules for devices that should be
+ automatically redirected on connection to prevent Windows
+ from showing "New Hardware Found" wizard window for USB
+ devices that do not have driver on the local system.
+
+ win-usbredir: Only match USB devices by VID:PID when WinUsb used
+ In other cases match devices by BUS:ADDR.
+
+ This commit introduces use_usbclerk flag which is set TRUE
+ unconditionally for Windows builds for now. Next patches
+ will introduce UsbDk backend integrartion which will set
+ this flag in accordance to UsbDk presence on the system.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+2016-03-24 Christophe Fergeau <cfergeau@redhat.com>
+
+ Add SpiceUsbDeviceManager parameter to device comparison functions
+ This additional parameter is currently unused, but this is in
+ preparation for the next commits.
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+2016-03-24 Dmitry Fleytman <dmitry@daynix.com>
+
+ win-usbredir: Introduce UsbDk wrapper
+ Introduce UsbDk API definitions and binding code.
+
+ UsbDk API DLL is loaded dynamically and wrapped by
+ a thin glue code layer. This approach was chosen in
+ order to make spice-gtk functional without UsbDk
+ installed.
+
+ Next patches will introduce dynamic backend selection
+ logic, i.e. spice-gtk will try to use UsbDk by
+ default and fallback to the old WinUsb/usbclerk
+ scheme in case UsbDk is not available.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+2016-03-24 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ widget: modify update-area to not require primary surface
+ If egl display is enabled, use GL scanout geometry to check intersection
+ with the monitor area. This solves displaying GL display without
+ software canvas (currently d->area is empty and gl drawing fails)
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ main: don't update display timer for unchanged config
+ With virgl, set_monitor_ready() may be called each time the scanout is
+ updated to set the monitor area. This will call
+ spice_main_update_display(), and keep the timer postponed even if the
+ monitor configuration didn't change. Treat unchanged configuration as a
+ no-op and keep configuration timer unchanged. This fixes monitor
+ autoconfig with virgl (when the display is regularly updated).
+
+ It also solves/avoids problems with a guest running on wayland when the
+ "resize-guest" property is TRUE.
+
+ Fixes:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1266484
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ widget: update d->ready based on scanout image available
+ d->ready is updated based on monitor area & canvas. In case of GL
+ rendering, update it based on monitor area & scanout and add check
+ before drawing update.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ egl: check and update scanout after egl init
+ Once the egl/GL context are initialized, check if there is a scanout to
+ associate to display widget. This solves races when scanout update is
+ happening before the egl/GL context is ready.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ widget: make gl-scanout and update-monitor-area privately exported
+ The following changes will call these functions from spice-widget-egl.c
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ display: return NULL in spice_display_get_gl_scanout()
+ If there is no valid scanout, return NULL.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ widget: enable egl before updating scanout
+ The GLArea is realized lazily, when it is made visible in
+ set_egl_enabled(). The egl context is initialized once the GLArea is
+ realized. Enable egl before updating the scanout.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ egl: check context is ready
+ Add a new GL status field to check if the GL context is ready. This
+ helps debugging races where GL is called before the context is ready.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ widget: remove superflous WIN32 check
+ The egl call is already inside a X11 conditional block.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-03-24 Victor Toso <victortoso@redhat.com>
+
+ channel-main: fix leak on volume-sync
+ 7 bytes in 1 blocks are definitely lost in loss record 128 of 10,009
+ at 0x4C2A988: calloc (vg_replace_malloc.c:711)
+ by 0xB6C3200: g_malloc0 (gmem.c:124)
+ by 0x740BD5F: audio_playback_volume_info_cb (channel-main.c:1216)
+ by 0xB11D488: g_task_return_now (gtask.c:1107)
+ by 0xB11DCBD: g_task_return (gtask.c:1165)
+ by 0x742D1F5: spice_pulse_complete_all_async_tasks (spice-pulse.c:1034)
+ by 0x8B6B57C: ext_stream_restore_read_cb (ext-stream-restore.c:141)
+ by 0x10BA63C0: run_action (pdispatch.c:284)
+ by 0x10BA6722: pa_pdispatch_run (pdispatch.c:337)
+ by 0x8B6520D: pstream_packet_callback (context.c:338)
+ by 0x10BA8D7E: do_read (pstream.c:879)
+ by 0x10BAB39A: do_pstream_read_write (pstream.c:189)
+
+ 7 bytes in 1 blocks are definitely lost in loss record 129 of 10,009
+ at 0x4C2A988: calloc (vg_replace_malloc.c:711)
+ by 0xB6C3200: g_malloc0 (gmem.c:124)
+ by 0x740BFBF: audio_record_volume_info_cb (channel-main.c:1273)
+ by 0xB11D488: g_task_return_now (gtask.c:1107)
+ by 0xB11DCBD: g_task_return (gtask.c:1165)
+ by 0x742D1F5: spice_pulse_complete_all_async_tasks (spice-pulse.c:1034)
+ by 0x8B6B57C: ext_stream_restore_read_cb (ext-stream-restore.c:141)
+ by 0x10BA63C0: run_action (pdispatch.c:284)
+ by 0x10BA6722: pa_pdispatch_run (pdispatch.c:337)
+ by 0x8B6520D: pstream_packet_callback (context.c:338)
+ by 0x10BA8D7E: do_read (pstream.c:879)
+ by 0x10BAB39A: do_pstream_read_write (pstream.c:189)
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2016-03-23 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ widget: use allocation instead of window size
+ Since spice-gtk 57df040cc, the SpiceDisplay no longer forces its own
+ window. Get allocation instead of window size. This fixes a "top
+ border" issue in spicy with gtk+ >= 3.19.8.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ widget: offset draw updates by widget allocation if necessary
+ According to gtk_widget_queue_draw_area() documentation:
+
+ "The region here is specified in widget coordinates. Widget coordinates
+ are a bit odd; for historical reasons, they are defined as
+ widget->window coordinates for widgets that return TRUE for
+ gtk_widget_get_has_window(), and are relative to widget->allocation.x ,
+ widget->allocation.y otherwise."
+
+ Since spice-gtk 57df040cc, the SpiceDisplay no longer forces its own
+ window. During gtk+ 3.19.8, gtk stack also no longer use its own
+ window (commit 9d0e8401). In order to make drawing update resilient to
+ such changes, add a function applying offset if necessary.
+
+ This solves drawing glitches and perceived slowness with spice-gtk git
+ and gtk+ >= 3.19.8.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-03-23 Pavel Grunt <pgrunt@redhat.com>
+
+ spicy: Remove configure-event callback
+ It is a leftover - see "Remove GnomeRR code"
+ commit 30986505ba6041c293c38cb4b7f4b618a59f4716
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+2016-03-23 Frediano Ziglio <fziglio@redhat.com>
+
+ Avoid to access array with negative numbers
+
+2016-03-23 Fabiano Fidêncio <fidencio@redhat.com>
+
+ vmcstream,gtask: Do idle ourself instead of leaving it to GTask's heuristic
+ Seems that GTask heuristic only makes sense in a non-coroutine case.
+ After opening a bug[0] on spice-gtk and a few discussions in the mailing
+ list, seems that is completely fine for coroutine code to deal with the
+ idle explicitly.
+
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+ vmcstream,gtask: Fix crash when trying to use webdav
+ Don't try to get the cancellable from a task that is, for sure (ensured
+ by us), NULL. See the backtrace:
+
+ #0 0x00007ffff29cf250 in g_task_get_cancellable () at /lib64/libgio-2.0.so.0
+ #1 0x00007ffff78a9012 in spice_vmc_input_stream_read_all_async (stream=<optimized out>, buffer=0x7070f8, count=8, io_priority=<optimized out>, cancellable=0x7fffcc00a470, callback=0x7ffff788c190 <client_read_cb>, user_data=0x707b30) at vmcstream.c:187
+ #2 0x00007ffff788c0ab in start_demux (self=0x707b30) at channel-webdav.c:498
+ #3 0x00007ffff2700578 in g_closure_invoke () at /lib64/libgobject-2.0.so.0
+ #4 0x00007ffff27135f0 in signal_emit_unlocked_R () at /lib64/libgobject-2.0.so.0
+ #5 0x00007ffff271c43c in g_signal_emit_valist () at /lib64/libgobject-2.0.so.0
+ #6 0x00007ffff788acca in emit_main_context (opaque=0x7fffbfffe880) at gio-coroutine.c:200
+ #7 0x00007ffff242bab3 in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
+ #8 0x00007ffff242be60 in g_main_context_iterate.isra () at /lib64/libglib-2.0.so.0
+ #9 0x00007ffff242c182 in g_main_loop_run () at /lib64/libglib-2.0.so.0
+ #10 0x0000000000405df6 in main (argc=<optimized out>, argv=<optimized out>) at spicy.c:1897
+
+ It was pointed out during the review and, somehow, missed :-\
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-03-22 Jeremy White <jwhite@codeweavers.com>
+
+ Include gdk/gdkwayland.h anytime GDK_WINDOWING_WAYLAND is defined.
+ A specific GTK version check is not appropriate for this particular include.
+ This fixes compilation on Debian Jessie.
+
+2016-03-22 Pavel Grunt <pgrunt@redhat.com>
+
+ Remove extra checks before g_cancellable_disconnect()
+ If cancellable is NULL or handler_id is 0 the function does nothing.
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ usb-device-manager: Remove invalid return annotation
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-03-22 snir sheriber <ssheribe@redhat.com>
+
+ usbredir_handle_msg: rename data to err_data
+ To better reflect what this variable is used for and change the declare
+ location such that it will be declared only if it should
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-03-21 Fabiano Fidêncio <fidencio@redhat.com>
+
+ mingw: Fix build failure due to epoxy/egl.h header
+ epoxy/egl.h header is not provided by mingw-epoxy package.
+ Let's avoid egl usage when building using mingw then.
+
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+ channel-usbredir: Fix crash due to a Task returning earlier than expected
+ g_task_return_error() has been completing the task immediately, not
+ cleaning up/setting up the device state to STATE_DISCONNECTED. It's been
+ causing a double free when trying to redirect a device without having
+ the ACL permissions for doing it. See the backtrace:
+
+ #0 0x00007ffff24dc07d in g_type_check_instance_is_fundamentally_a (type_instance=type_instance@entry=0x14779d0, fundamental_type=fundamental_type@entry=80) at gtype.c:4032
+ #1 0x00007ffff24bc447 in g_object_unref (_object=0x14779d0) at gobject.c:3076
+ #2 0x00007ffff7bafc2a in connect_cb (gobject=0x87d9a0 [SpiceUsbDeviceManager], res=0x96f830, user_data=0x143e0e0)
+ at usb-device-widget.c:485
+ #3 0x00007ffff277f5a3 in g_task_return_now (task=0x96f830 [GTask]) at gtask.c:1106
+ #4 0x00007ffff277fc4e in g_task_return (task=0x96f830 [GTask], type=<optimized out>) at gtask.c:1164
+ #5 0x00007ffff786c277 in spice_usb_device_manager_channel_connect_cb (gobject=0x917940 [SpiceUsbredirChannel], channel_res=0x96f900, user_data=0x96f830) at usb-device-manager.c:1094
+ #6 0x00007ffff277f5a3 in g_task_return_now (task=0x96f900 [GTask]) at gtask.c:1106
+ #7 0x00007ffff277fc4e in g_task_return (task=0x96f900 [GTask], type=<optimized out>) at gtask.c:1164
+ #8 0x00007ffff786699c in spice_usbredir_channel_open_acl_cb (gobject=0xa73b00 [SpiceUsbAclHelper], acl_res=0x96f9d0, user_data=0x917940) at channel-usbredir.c:300
+ #9 0x00007ffff277f5a3 in g_task_return_now (task=0x96f9d0 [GTask]) at gtask.c:1106
+ #10 0x00007ffff277fc4e in g_task_return (task=0x96f9d0 [GTask], type=<optimized out>) at gtask.c:1164
+ #11 0x00007ffff27804d0 in g_task_return_new_error (task=0x96f9d0 [GTask], domain=<optimized out>, code=<optimized out>, format=<optimized out>) at gtask.c:1744
+ #12 0x00007ffff786eade in cb_out_watch (channel=0x1488740, cond=G_IO_IN, user_data=0xa73b00) at usb-acl-helper.c:128
+ #13 0x00007ffff21b8e3a in g_main_context_dispatch (context=0x647390) at gmain.c:3154
+ #14 0x00007ffff21b8e3a in g_main_context_dispatch (context=context@entry=0x647390) at gmain.c:3769
+ #15 0x00007ffff21b91d0 in g_main_context_iterate (context=0x647390, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3840
+ #16 0x00007ffff21b94f2 in g_main_loop_run (loop=0x13d1ae0) at gmain.c:4034
+ #17 0x00007ffff3ca5440 in gtk_dialog_run () at /lib64/libgtk-3.so.0
+ #18 0x0000000000406a18 in menu_cb_select_usb_devices (action=0x9d62f0 [GtkAction], data=0x69aef0) at spicy.c:394
+ #22 0x00007ffff24d28ff in <emit signal ??? on instance 0x9d62f0 [GtkAction]> (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3439
+ #19 0x00007ffff24b77a5 in g_closure_invoke (closure=0xa0d0c0, return_value=return_value@entry=0x0, n_param_values=1, param_values=param_values@entry=0x7fffffffcf70, invocation_hint=invocation_hint@entry=0x7fffffffcef0) at gclosure.c:801
+ #20 0x00007ffff24c9851 in signal_emit_unlocked_R (node=node@entry=0x63fc10, detail=detail@entry=0, instance=instance@entry=0x9d62f0, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffcf70) at gsignal.c:3627
+ #21 0x00007ffff24d2530 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffd130) at gsignal.c:3383
+ #23 0x00007ffff3bc23b0 in _gtk_action_emit_activate () at /lib64/libgtk-3.so.0
+ #27 0x00007ffff24d28ff in <emit signal ??? on instance 0x9a8730 [GtkImageMenuItem]> (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3439
+ #24 0x00007ffff24b77a5 in g_closure_invoke (closure=closure@entry=0x6607d0, return_value=return_value@entry=0x0, n_param_values=1, param_values=param_values@entry=0x7fffffffd3f0, invocation_hint=invocation_hint@entry=0x7fffffffd370) at gclosure.c:801
+ #25 0x00007ffff24c938c in signal_emit_unlocked_R (node=node@entry=0x661050, detail=detail@entry=0, instance=instance@entry=0x9a8730, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffd3f0) at gsignal.c:3557
+ #26 0x00007ffff24d2530 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffd5b0) at gsignal.c:3383
+ #28 0x00007ffff3e7094e in gtk_widget_activate () at /lib64/libgtk-3.so.0
+ #29 0x00007ffff3d4e4f6 in gtk_menu_shell_activate_item () at /lib64/libgtk-3.so.0
+ #30 0x00007ffff3d4e824 in gtk_menu_shell_button_release () at /lib64/libgtk-3.so.0
+ #31 0x00007ffff3d30fda in _gtk_marshal_BOOLEAN__BOXEDv () at /lib64/libgtk-3.so.0
+ #32 0x00007ffff24b79d4 in _g_closure_invoke_va (closure=closure@entry=0x644d10, return_value=return_value@entry=0x7fffffffd900, instance=instance@entry=0x80faa0, args=args@entry=0x7fffffffd9d0, n_params=<optimized out>, param_types=0x644d40) at gclosure.c:864
+ #33 0x00007ffff24d1dd3 in g_signal_emit_valist (instance=0x80faa0, signal_id=<optimized out>, detail=0, var_args=var_args@entry=0x7fffffffd9d0) at gsignal.c:3292
+ #34 0x00007ffff24d28ff in g_signal_emit (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3439
+ #35 0x00007ffff3e6e4bc in gtk_widget_event_internal () at /lib64/libgtk-3.so.0
+ #36 0x00007ffff3d2e34e in propagate_event () at /lib64/libgtk-3.so.0
+ #37 0x00007ffff3d300fc in gtk_main_do_event () at /lib64/libgtk-3.so.0
+ #38 0x00007ffff38a8e92 in gdk_event_source_dispatch () at /lib64/libgdk-3.so.0
+ #39 0x00007ffff21b8e3a in g_main_context_dispatch (context=0x647390) at gmain.c:3154
+ #40 0x00007ffff21b8e3a in g_main_context_dispatch (context=context@entry=0x647390) at gmain.c:3769
+ #41 0x00007ffff21b91d0 in g_main_context_iterate (context=0x647390, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3840
+ #42 0x00007ffff21b94f2 in g_main_loop_run (loop=0x6e2730) at gmain.c:4034
+ #43 0x000000000040b2f9 in main (argc=1, argv=0x7fffffffde48) at spicy.c:1920
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-03-18 Pavel Grunt <pgrunt@redhat.com>
+
+ Adjust to Gtk+ 3.10
+ Dependency since f9a1aad85fcc76dd76c454b51fbce5e07c9b145f
+
+ Remove unneeded GTK_CHECK_VERSION guards
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ Adjust to GLib 2.36
+ Dependency since 8693e7d3f7de1ff102082212fa6e35fb1a252ef7
+
+ Remove glib-compat files and most of GLIB_CHECK_VERSION guards
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ Move strtok_r from glib-compat to spice-uri
+ It is not glib specific and it is only used in spice-uri
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ spice-util: Fix alignment
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+ usb-acl-helper: Remove extra check for NULL
+ g_cancellable_cancel() and g_clear_object() can handle it
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-03-17 Pavel Grunt <pgrunt@redhat.com>
+
+ spicy: s/Automagic/Automatic/
+ Acked-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+
+ spice-display: Remove auto-clipboard notify
+ It was used to notify the (deprecated) auto-clipboard property of
+ the SpiceDisplay everytime the SpiceGtkSession emits its auto-clipboard
+ notify.
+
+ The commit 70a00b8fcc2ca85d3601f6ac4895f906f9032e77 removed the property
+ from SpiceDisplay causing a runtime warning:
+
+ GLib-GObject-WARNING **: g_object_notify: object class 'SpiceDisplay' has no property named 'auto-clipboard'
+ Acked-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+
+ display: Lower level of warning for empty monitor config
+ It is a valid case when a guest requests to turn off monitors, eg:
+ xrandr --output Virtual-0 --off
+
+ Related:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1061942
+
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+2016-03-15 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ build-sys: fix 'Only <spice-client.h> can be included directly' warning
+ Tests should be allowed to include directly private headers. Set
+ __SPICE_CLIENT_H_INSIDE__ where necessary or include spice-client.h
+ where possible.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+ Lower gtk+ requirement to 3.10
+ Make GtkGlArea optional allows to lower gtk+ requirement to
+ 3.10 (required for GtkStack). However, gl display is unsupported on
+ wayland with gtk+ < 3.16.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+ build-sys: remove epoxy from pc requires
+ libepoxy doesn't need to figure in spice-gtk pkg-config requires, it's a
+ private dependency.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+2016-03-15 Fabiano Fidêncio <fidencio@redhat.com>
+
+ wocky-http-proxy: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ win-usb-driver-install: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ vmcstream: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ usb-device-manager: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ usb-acl-helper: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ spice-pulse: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ spice-gstaudio: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ spice-channel: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ smartcard-manager: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ channel-usbredir: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ channel-port: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ channel-main: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+ channel-base: Use GTask instead of GSimpleAsyncResult
+ Instead of using GSimpleAsyncResult, use the new GTask API, which is
+ much more straightforward.
+ For using the new GTask API, let's bump GIO (part of GLib) dependency
+ version to 2.36, which is safe based on major distro support:
+ - Debian Jessie: glib-2.42
+ - RHEL-7.1: glib-2.40
+ - SLES12: glib-2.38
+ - Ubuntu LTS 14.04: glib-2.40
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+2016-03-14 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ gtk: add GtkGLArea
+ GtkGLArea is the proper modern way to have opengl in an gtk+
+ application. Unfortunately, it may use various backends and interfaces
+ to initialize it, but dmabuf image sharing requires egl atm.
+
+ This patch keeps using our egl setup on X11, while it uses gtkglarea on
+ known gdk backend based on egl, such as the wayland one. This brings
+ wayland support for local gl to spice-gtk.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+ gtk: use GtkStack
+ Move the GtkDrawingArea in a GtkStack, so other widgets can be switched
+ to for the display: the next patch adds a GtkGLArea for an opengl
+ rendering. One can imagine other display widgets to show text etc..
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+ gtk: require gtk+ 3.16
+ 3.16 is the minimal version for GtkGLArea widget, used in following
+ patches.
+
+ Drop conditional epoxy support, as it is now required by gtk+.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+ gtk: drop deprecated stuff from spice-gtk
+ Breaking ABI is a good time to remove deprecated code.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+ Drop GTK+ 2.0
+ Not so many systems require gtk+ 2.0 these days, let's move on.
+
+ This drops the old python bindings (non-gir based), and the
+ unsteady/experimental gtk2-only XShm support.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+ gtk: make SpiceGrabSequence private
+ Do not leak internals of SpiceGrabSequence in public headers. This makes also
+ the class final, which let us extend more easily without fear of breaking ABI.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+ gtk: make SpiceUsbDeviceWidget private
+ Do not leak internals of SpiceUsbDeviceWidget in public headers. This makes also
+ the class final, which let us extend more easily without fear of breaking ABI.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+ gtk: make SpiceGtkSession private
+ Do not leak internals of SpiceGtkSession in our headers. This makes also
+ the class final, which let us extend more easily without fear of
+ breaking ABI.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+ gtk: make SpiceDisplay private
+ Do not leak internals of SpiceDisplay in our headers. This makes also
+ the class final, which let us extend more easily without fear of
+ breaking ABI.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+ build-sys: bump spice-gtk current version info
+ The following patches need to break the ABI (in particular the parent of the
+ SpiceDisplay widget).
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+2016-03-11 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ build-sys: fix make check when polkit not available
+ acl-helper needs polkit (and unix atm) to build.
+
+ doc: add a bunch of Since: 0.31
+
+ Prepare for v0.31 release
+
+ logging: use more idiomatic spice-gtk logging
+ spice-gtk uses SPICE_DEBUG for debug lines (for now), and prefer direct
+ glib glog/g_warning.
+
+ session: use debug message for optional key value
+ This fixes make check failing because of recent spice-common logging
+ switch to glib.
+
+2016-03-11 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Update POTFILES.skip
+ spicy.desktop.in no longer exists.
+
+ Add tests for usb-acl-helper
+
+ usb-acl-helper: add env var for specifying acl helper binary
+ Setting SPICE_USB_ACL_BINARY allows us to execute a custom mock acl
+ helper binary for testing purposes.
+
+ Rename spice_usb_acl_helper_open_acl() to _open_acl_async()
+ Follow established practice and make the function's behavior more
+ explicit.
+
+ Remove spice_usb_acl_helper_close_acl()
+ This function is now only called after the open_acl() task completes,
+ and in that scenario it basically does the same thing that the
+ SpiceUsbAclHelper destructor does, so it's pointless. Remove it.
+
+ usb-acl-helper: Avoid deadlock when cancelled
+ cancelled_cb() (which is triggered when the GCancellable's "cancelled"
+ signal is emitted) called spice_usb_acl_helper_close_acl(), which calls
+ spice_usb_acl_helper_cleanup(), which in turn calls
+ g_cancellable_disconnect(). Calling g_cancellable_disconnect() from
+ within a "cancelled" handler results in a dealock, as mentioned in the
+ documentation. Instead of closing the acl here, simply cancel the task
+ here. The cleanup() call will happen when the SpiceUsbAclHelper object
+ is destroyed.
+
+ Introduce spice_usb_acl_helper_cancel()
+ This function explicitly cancels a open_acl() task. It is similar to
+ close_acl(), but its behavior is more explicit. This function is very
+ similar to the existing close_acl() function but it requires that the
+ task has not already been completed. Also, although it releases its
+ reference on priv->result to avoid circular references, it doesn't call
+ cleanup(), preferring instead to wait for the destructor to clean up.
+ This makes the close_acl() function essentially pointless and will be
+ removed in the following commit.
+
+2016-03-10 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ Update spice-common submodule
+ Pick codegen build fix
+
+2016-02-23 Francois Gouget <fgouget@codeweavers.com>
+
+ spice-gtk: Fix the signedness of a couple of mm-time traces
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+2016-02-23 Ignacio Casal Quinteiro <icq@gnome.org>
+
+ namedpipelistener: do not leak the error message
+
+2016-02-18 Christophe Fergeau <cfergeau@redhat.com>
+
+ Simplify spice_usb_device_manager_device_to_libdev()
+ The Windows-specific version duplicates some code from
+ spice_usb_device_equal_libdev(), this commit
+ switches to using that helper instead.
+
+ Simplify spice_usb_device_equal_libdev()
+ The Windows-specific version duplicates some code from
+ spice_usb_device_manager_libdev_match(), this commit
+ switches to using that helper instead.
+
+2016-02-16 Marc-André Lureau <mlureau@redhat.com>
+
+ gtk: add spice-widget GL scanout support
+ Hook to spice-glib events to show the GL scanout.
+
+ The opengl context is created with egl, and is currently
+ x11-only (supporting wayland with bare-egl doesn't seem trivial).
+
+ Using GtkGLArea is left for a future series, since SpiceDisplay widget
+ is a GtkDrawingArea and can't be replaced without breaking
+ ABI. Furthermore, GtkGLArea won't work on non-egl contexts, so this
+ approach is necessary on gtk+ < 3.16 or X11 (because gdk/x11 uses glx).
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2016-02-13 Marc-André Lureau <mlureau@redhat.com>
+
+ glib: add local GL scanout support
+ Add spice-glib support for gl scanout messages.
+
+ A note about SpiceGlScanout: it is struct with scanout details,
+ registered as a boxed type, with associated gl-scanout property. That
+ way, it doesn't need a seperate signal for change notification and the
+ current scanout can be retrieve with gobject getter. Since boxed
+ property are always duplicated by g_object_get(), an additional
+ spice_display_get_gl_scanout() method returns the current scanout
+ without duplication (that's what spice-gtk display widget will use).
+
+2016-02-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: check for epoxy-egl support
+ The following code requires epoxy with egl support. Check for pkg-config
+ and egl headers.
+
+ Add spice_channel_unix_read_fd()
+ Utility function used in the messages with socket ancillary fd.
+
+2016-02-13 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ build-sys: bump to spice-protocol 0.12.11
+ Needed for GL messages
+
+2016-02-12 Fabiano Fidêncio <fidencio@redhat.com>
+
+ typo: s/GTask/GSimpleAsyncResult
+ Seems that I messed up with cd0c1008316e90bce925e1448ffcabb366e88f8f
+ while rebasing my GTask series on top of this patch, causing a build
+ breakage due to non-intentional insertion of a GTask replacing a
+ GSimpleAsyncResult.
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ Use #ifdef {HAVE,USE}_FOO instead of #if {HAVE,USE}_FOO
+ While "#if USE_FOO" checks for the value of the variable USE_FOO,
+ "#ifdef" checks whether USE_FOO is defined or not.
+
+ It means, if we had something like: #define USE_FOO 0, we would have:
+ #if USE_FOO
+ /* Any code in here would NOT be compiled */
+ #endif
+
+ #ifdef USE_FOO
+ /* Any code in here would be compiled */
+ #endif
+
+ No problem was faced on spice-gtk till now because either USE_FOO is not
+ defined or defined as 1, but let's try to have it standardized.
+
+ Acked-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+
+2016-02-03 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ gtk: replace configure-event for size-allocate
+ For size-allocate, it's simpler to connect to the signal rather than
+ override the default signal handler since there is no automatic chaining
+ to parent handler otherwise. Doing this removes the need to have a
+ window.
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2016-01-22 Fabiano Fidêncio <fidencio@redhat.com>
+
+ usb-device-{manager,widget}: Add counter of free channels
+ As the message showed when the last usbredir channel is taken can be a
+ bit confusing, let's add a counter of free channels to the widget's
+ label.
+ In order to add the counter, a new property for SpiceUsbDeviceManager
+ was introduced ("free-channels").
+
+ Related: rhbz#1298772
+
+ Remove GSLice usage
+ It's being slowly deprecated in glib
+ https://bugzilla.gnome.org/show_bug.cgi?id=754687
+
+2016-01-19 Victor Toso <victortoso@redhat.com>
+
+ gstaudio: set output parameter to NULL on error
+ This is not really triggered in the current code but this is usually
+ expected in case of errors; Also, the same function on record side
+ already does this.
+
+ Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
+
+2016-01-14 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ build-sys: silence vala deprecated function usage warnings
+ This silence usage of deprecated glib declarations from vala generated code.
+
+ Acked-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+2016-01-14 Marc-Andre Lureau <marcandre.lureau@gmail.com>
+
+ Update spice-common
+ This is an update to fix build issues with spice-protocol.git.
+ generated_server_demarshallers.c: In function
+ ‘parse_msgc_display_gl_draw_done’:
+ generated_server_demarshallers.c:767:23: error:
+ ‘SpiceMsgcDisplayGlDrawDone’ undeclared (first use in this function)
+ mem_size = sizeof(SpiceMsgcDisplayGlDrawDone);
+ ...
+
+ Also needed for upcoming gl-scanout messages.
+
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+2016-01-07 Victor Toso <victortoso@redhat.com>
+
+ channel-main: remove unused header rect.h
+ It was included in be8ff99571478deb5c8d116134f65ed2b788dbd3 but with no
+ use.
+
+ Acked-by: Marc-André Lureau <mlureau@redhat.com>
+
+2016-01-04 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: remove xrandr
+ Not needed anymore (probably since gnome-rr was removed in 30986505b)
+
+2015-12-21 snir sheriber <ssheribe@redhat.com>
+
+ Grab keyboard based on session focus.
+ When using multiple monitors moving mouse between monitors releases
+ keyboard grab.
+
+ Reproduce bug
+ -Open multiple monitors remote-viewer session
+ -Click on one of the monitors to get focus & keyboard-grab
+ -Move mouse to another monitor and try keyboard command (do not click)
+ At this point all keyboard commands are being executed on the client
+ machine instead of the remote machine
+
+ I added keyboard_has_focus and mouse_has_pointer variables at the
+ session and now these properties are being tested for the session
+ instead for the current widget (works also when using alt-tab).
+
+ Resolves: rhbz#1275231
+
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2015-12-21 Lukas Venhoda <lvenhoda@redhat.com>
+
+ ppc: Fix spicy-screenshot colors on BE machines
+ Save screenshot in proper endianess
+ xRGB on LE machine and BGRx on BE machine
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+ ppc: Fix colors on ppc when using GLZ
+ Fixes color order on PowerPC when using GLZ image compression.
+ Acked-by: Pavel Grunt <pgrunt@redhat.com>
+
+2015-12-21 Fabiano Fidêncio <fidencio@redhat.com>
+
+ ppc: Fix message endianess
+
+ ppc: Fix header endianess
+
+2015-12-18 Pavel Grunt <pgrunt@redhat.com>
+
+ build-sys: Use sasl check from spice-common
+ Support only libsasl2 providing libsasl2.pc file
+
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2015-12-10 Javier Celaya <javier.celaya@flexvdi.com>
+
+ Call spice_marshaller_flush on message write
+ spice_marshaller_flush must be called before writing a message to
+ calculate pointer offsets.
+
+ This is only an issue when ptr submarshallers are used, which currently
+ is only used by Tunnel::service_add. Since this is disabled by default,
+ this buug is not going to be hit by the current codebase.
+
+2015-12-09 Christophe Fergeau <cfergeau@redhat.com>
+
+ gst: Fix typo in preprocessor symbol
+ When the GStreamer backend is used, HAVE_GSTAUDIO is defined, not
+ HAVE_GST_AUDIO.
+
+ smartcard: Fix compilation with older libcacard
+ e0c2182937 dropped some #include from channel-smartcard.c and spicy.c as
+ they were redundant with the headers already included from
+ spice-common/common/messages.h. While this is true for the newer
+ libcacard.h header, we need to include more headers to support older
+ libcacard, or compilation breaks.
+
+2015-12-09 Francois Gouget <fgouget@codeweavers.com>
+
+ spice-gtk: Recover from GStreamer audio initialization errors
+ gst_init() will terminate the program in case of a failure so it's
+ better to use gst_init_check() so we can recover from errors.
+
+2015-12-08 Francois Gouget <fgouget@codeweavers.com>
+
+ build-sys: Warn about missing GStreamer 1.0 audio runtime elements
+ Their absence should not be reported as an error since they are not
+ needed for the build, but the developer will need them to test the code
+ so it's appropriate to warn him.
+
+2015-12-08 Christophe Fergeau <cfergeau@redhat.com>
+
+ build-sys: Check for GStreamer 1.0 audio with SPICE_CHECK_GSTREAMER()
+
+2015-12-08 Francois Gouget <fgouget@codeweavers.com>
+
+ build-sys: Allow simultaneous support for Pulse and GStreamer audio
+ Rather than GStreamer/PulseAudio backend being mutually exclusive at
+ compile-time, this commit allows to enable both at the same time.
+ PulseAudio will then be favoured, with a fallback to GStreamer if it's
+ not available.
+ Note that --with-audio is kept for backward compatibility.
+
+2015-12-08 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ Use libcacard.h if possible
+ Drop unneeded includes (that are already undirectly included).
+
+ Remove unmaintained spicy.nsis
+ Remove gtkrc too, and cleanup EXTRA_DIST ($(desktop_in_files) is unused)
+
+ Update spice-common
+ For new libcacard.h usage
+
+ Fix use after free of uri
+ "path" points to "uri" memory, move free(uri) later.
+
+ Found thanks to valgrind :)
+
+2015-11-25 Christophe Fergeau <cfergeau@redhat.com>
+
+ Update spice-common submodule
+ The next commit is going to use SPICE_WARNING which was added recently
+ to spice-common
+
+ This submodule update changes:
+
+ Christophe Fergeau (5):
+ build-sys: Add gio-2.0 to SPICE_CHECK_GLIB2
+ build-sys: Fix error in SPICE_CHECK_LZ4 description
+ build-sys: Set automake conditional in SPICE_CHECK_SMARTCARD
+ build-sys: Rename SUPPORT_GL to HAVE_GL
+ build-sys: Add missing # to comment
+
+ Francois Gouget (3):
+ build-sys: Add the SPICE_WARNING() and SPICE_PRINT_MESSAGES m4 macros
+ build-sys: Add SPICE_CHECK_GSTREAMER()
+ build-sys: Add SPICE_CHECK_GSTREAMER_ELEMENTS()
+
+ Lukas Venhoda (4):
+ ssl-verify: Only check addr length when using IP addr
+ m4: Require glib version >= 2.22
+ ssl-verify: Changed IPv4 hostname to IPv6
+ canvas_base: Remove redundant switch case block
+
+2015-11-25 Francois Gouget <fgouget@codeweavers.com>
+
+ build-sys: Use SPICE_WARNING() to issue the DBus warning
+
+2015-11-24 Francois Gouget <fgouget@codeweavers.com>
+
+ build-sys: Prefix the configure audio GStreamer variables with GSTAUDIO_
+ This lets us avoid naming conflicts when using GStreamer for other
+ purposes.
+
+ Acked-by: Victor Toso <victortoso@redhat.com>
+
+2015-11-20 Jay.han <ezzzehxx@gmail.com>
+
+ file transfer: send cancel message when user cancels a transfer
+ When a user cancel's a file transfer, we should send a STATUS_CANCELED
+ message rather than an STATUS_ERROR message. The latter triggers a bug
+ in the vdagent where the file remains opened by the vdagent in the guest
+ and cannot be removed.
+
+2015-11-19 Marek Kasik <mkasik@redhat.com>
+
+ Be more specific in the case of authentication error
+ This patch adds SPICE_CLIENT_ERROR_AUTH_NEEDS_USERNAME error
+ for the case when authentication fails because of missing username.
+ This can happen when GSSAPI method is used.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=92994
+
+2015-11-18 Pavel Grunt <pgrunt@redhat.com>
+
+ spicy: Add support for changing compression
+
+ channel-display: Add spice_display_change_preferred_compression
+
+2015-11-11 Pavel Grunt <pgrunt@redhat.com>
+
+ Do not export symbol of non-existent function
+
+2015-11-10 Jonathon Jongsma <jjongsma@redhat.com>
+
+ file xfer: Fix segfault when rebooting
+ Recent changes to file transfer introduced a regression where the client
+ would crash when rebooting a guest after performing a file transfer.
+ This was caused because the SpiceFileTransferTask is freed when it is
+ completed, but is not removed from the MainChannel's hash table. When we
+ reboot the guest and lose our vdagent connection, we iterate through the
+ list of tasks in the hash table and complete them. But since we did not
+ remove the already-completed tasks from this hash table, this hash table
+ contains already-freed memory.
+
+ To fix the issue, take an extra ref for the async operations (so that
+ completing the task won't free an object that is stored in the hash table). In
+ addition, connect to the task's "finished" signal and remove it from the hash
+ table when it becomes finished.
+
+ Bug reported via email by Jay.han <ezzzehxx@gmail.com>. Valgrind report
+ below:
+
+ ==6926== Invalid read of size 8
+ ==6926== at 0x508177B: spice_file_transfer_task_completed (channel-main.c:2941)
+ ==6926== by 0x50846DC: set_agent_connected (channel-main.c:462)
+ ==6926== by 0x5073A43: spice_channel_recv_msg (spice-channel.c:1892)
+ ==6926== by 0x5073BE3: spice_channel_iterate_read (spice-channel.c:2132)
+ ==6926== by 0x5075D25: spice_channel_coroutine (spice-channel.c:2170)
+ ==6926== by 0x50A6EFE: coroutine_trampoline (coroutine_ucontext.c:63)
+ ==6926== by 0x50A6CC8: continuation_trampoline (continuation.c:55)
+ ==6926== by 0x65C2B5F: ??? (in /lib/x86_64-linux-gnu/libc-2.19.so)
+ ==6926== by 0x151331C7: ???
+ ==6926== Address 0x29971fd8 is 168 bytes inside a block of size 184 free'd
+ ==6926== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
+ ==6926== by 0x5E33142: g_type_free_instance (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4000.0)
+ ==6926== by 0x50815DA: file_xfer_close_cb (channel-main.c:1826)
+ ==6926== by 0x5AEBD5C: ??? (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.4000.0)
+ ==6926== by 0x5B0F41A: ??? (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.4000.0)
+ ==6926== by 0x5B0F438: ??? (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.4000.0)
+ ==6926== by 0x609BCE4: g_main_context_dispatch (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
+ ==6926== by 0x609C047: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
+ ==6926== by 0x609C309: g_main_loop_run (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4000.0)
+ ==6926== by 0x4058AB: main (spicy.c:1858)
+
+2015-11-10 Francois Gouget <fgouget@codeweavers.com>
+
+ build-sys: Remove some dead configure.ac DBus code
+ Acked-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2015-11-04 Francois Gouget <fgouget@codeweavers.com>
+
+ spice-gtk: Fix error handling in stream_get_current_frame()
+ *data must always be set to NULL on error.
+
+2015-10-30 Victor Toso <victortoso@redhat.com>
+
+ channel-usbredir: drop isoc packets on low bandwidth
+ When channel wants to send much more data then the wire can handle, the
+ queue grows fast. This patch does not limit the queue growth but
+ introduces an internal API to check if queue size is too big.
+
+ This internal API is used in usbredir_buffered_output_size_callback
+ which is called before any isoc pacaket is queued in usbredir. The
+ usbredir implements the logic to:
+ - only drop isoc packets
+ - while dropping packtes does still give us video frames from and above
+ 10fps streams
+
+ An easy way to test locally is sharing and webcam and with tc:
+ tc qdisc add dev lo root netem delay 100ms
+ tc qdisc change dev lo root netem delay 1000ms
+ tc qdisc del dev lo root netem
+
+ Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1264156
+
+2015-10-23 Christophe Fergeau <cfergeau@redhat.com>
+
+ build-sys: Remove unused conditional
+
+ Adjust to spice-common spice-deps.m4 changes
+ This commit updates spice-common to latest git master.
+ Since the argument to the SPICE_CHECK_xxx macros is now unused, it's
+ cleaner to remove it.
+
+ Christophe Fergeau (3):
+ Add marshaller test case
+ build-sys: Use ${PKG_CONFIG} rather than pkg-config
+ build-sys: Rework SPICE_CHECK_* m4 macros
+
+ Frediano Ziglio (1):
+ common: Fix typo in comment
+
+ Javier Celaya (1):
+ Fix linearization of several marshallers with one item
+
+2015-10-22 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Remove noisy debug statement
+ This isn't terribly useful for general debugging and makes the log
+ pretty noisy when transferring large files.
+
+ Don't print error message on successful file transfer
+ In certain circumstances we were printing an error message even though
+ the file transfer had completed successfully. It didn't cause any
+ problems, but it pointed out an issue in the handling of outgoing agent
+ messages.
+
+ The described behavior was generally only encountered when there were multiple
+ files being transferred at once, and most often when one or two files were
+ significantly smaller than another file being transferred. For example, two
+ 20kB files and another 3MB file. The failure mechanism is basically as follows:
+
+ For each file transfer, we read a chunk for the file and then we queue a series
+ of messages to the guest and wait for them to be flushed before continuing to
+ read a new chunk of the file. (Since the maximum agent message size is 2kB, each
+ 64kB chunk of file being read can generate up to 32 messages at a time). The
+ file transfer task remains in "pending" state until the flush operation is
+ complete. Since all agent messages go into a single channel-wide queue, waiting
+ for the messages to be flushed meant waiting for *all* outgoing messages to be
+ flushed, including those that were queued after we called flush_async().
+
+ Since agent messages can only be sent if the client has enough agent tokens, it
+ can take a little while for all queued messages to be sent. This means that
+ even if a file transfer task has sent out all of its data to the guest, it can
+ be kept in "pending" state for some time if other file transfer tasks or other
+ agent messages are added to the queue. In this situation, The guest might
+ notice that it has received all of the data for a file transfer task and send a
+ XFER_STATUS_SUCCESS message while we're still in "pending" state.
+
+ This patch changes to code so that flush_async() only waits for the
+ currently-queued messages to be sent. This means that it is not affected by any
+ new messages that get added to the outgoing queue after we've called
+ flush_async(). This means that the task will exit "pending" state immediately
+ after sending out our last data packet.
+
+ Fixes: rhbz#1265562
+
+ MainChannel: move task free from finalize to dispose
+ In order to avoid reference cycles, you're supposed to release
+ references in dispose, especially to those objects that can hold
+ references to yourself. This probably wasn't causing any leaks, since
+ the file transfer tasks generally are not alive when the main channel is
+ destroyed, but it's more proper.
+
+2015-10-16 Jonathon Jongsma <jjongsma@redhat.com>
+
+ FileTransferTask: ensure we emit 'finished' signal
+ In the case where a file cannot be opened for reading, we were not
+ emitting a 'finished' signal to communicate the error to the client.
+
+ I was intending to further fix this issue by 'rejecting' the drop (in
+ SpiceDisplay) when the URI list contains invalid files (e.g.
+ directories). This would prevent a 'new-file-transfer' signal from even
+ being emitted for these invalid files. But this turns out to be not very
+ useful since there's no real feedback given to the user to indicate why
+ the drop failed. So it's probably better for client applications to get
+ the 'new-file-transfer' and 'finished' signals so that they can present
+ the error to the user to explain why the attempted transfer did not
+ work.
+
+2015-10-14 Christophe Fergeau <cfergeau@redhat.com>
+
+ Free display_cache in cache_unref
+ Otherwise it will be leaked. There is no cache_ref function, or helper
+ increasing a refcount/taking a reference so cache_unref really is a
+ cache_free method.
+
+ This fixes:
+
+ ==27687== 64 bytes in 4 blocks are definitely lost in loss record 250 of 435
+ ==27687== at 0x4C28C50: malloc (vg_replace_malloc.c:299)
+ ==27687== by 0xA6AF058: g_malloc (gmem.c:94)
+ ==27687== by 0xA6C5982: g_slice_alloc (gslice.c:1007)
+ ==27687== by 0x40F112: cache_new (spice-channel-cache.h:54)
+ ==27687== by 0x40F112: cache_image_new (spice-channel-cache.h:64)
+ ==27687== by 0x40F112: spice_session_init (spice-session.c:294)
+ ==27687== by 0xA239B4A: g_type_create_instance (gtype.c:1870)
+ ==27687== by 0xA21C31A: g_object_new_internal (gobject.c:1779)
+ ==27687== by 0xA21DB10: g_object_newv (gobject.c:1926)
+ ==27687== by 0xA21E3FB: g_object_new (gobject.c:1619)
+ ==27687== by 0x40FF4D: spice_session_new (spice-session.c:1479)
+ ==27687== by 0x40E678: test_session_uri (session.c:35)
+ ==27687== by 0xA6CE47A: test_case_run (gtestutils.c:2158)
+ ==27687== by 0xA6CE47A: g_test_run_suite_internal (gtestutils.c:2241)
+ ==27687== by 0xA6CE642: g_test_run_suite_internal (gtestutils.c:2253)
+
+ Rename display_cache::cache_unref to cache_free
+ display_cache is no longer refcounted since commit c9d4773, but this is
+ not an issue as even before, the fact that it was refcounted was not
+ used as there was no corresponding cache_ref() call (and
+ g_hash_table_ref() was not called directly either).
+ As the next commit will free memory from cache_unref() rather than just
+ releasing a reference, it's better to make it obvious that this method
+ is a _free() method rather than an _unref() one.
+
+2015-10-10 Jonathon Jongsma <jjongsma@redhat.com>
+
+ New file transfer API
+ There were several shortcomings to the existing file transfer API,
+ particularly in terms of monitoring ongoing file transfers. The major
+ issue is that spice_main_file_copy_async() allows you to pass an array
+ of files, but the progress callback does not provide a way to
+ identify which file the callback is associated with. This makes it
+ nearly impossible for an application to monitor file transfers.
+
+ In addition, the SpiceDisplay widget automatically handles drag-and-drop
+ actions on the widget, and initiates file transfers without allowing the
+ application to specify a progress callback. So there's no way for an app
+ to monitor file transfers that are initiated via drag and drop.
+
+ http://lists.freedesktop.org/archives/spice-devel/2015-September/021931.html
+ has a more detailed explanation of the issues.
+
+ This change doesn't break the existing API, but adds some new API that
+ will allow an application to monitor file transfer progress, even for
+ transfers that are initiated within spice-gtk itself.
+
+ - A new public SpiceFileTransferTask object is added.
+ - The SpiceMainChannel object gains a "new-file-transfer" signal that is
+ emitted whenever a new file transfer is initiated. The
+ SpiceFileTransferTask object is passed to the signal handler.
+ - The application can retain this object and monitor its 'progress'
+ property to be notified when the progress of the file transfer
+ changes. The SpiceFileTransferTask::finished signal indicates when the
+ given file transfer has completed. The application can also cancel the
+ file transfer by calling the _cancel() method.
+
+ The 'spicy' test application has been updated to use this new API and
+ display a simple dialog showing the progress of individual files.
+
+2015-10-09 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Fix progress monitoring in spice_main_file_copy_async
+ spice_main_file_copy_async() allows you to pass a NULL-terminated array
+ of files to transfer to the guest. It also allows you to pass a
+ progress_callback function to monitor the progress of the transfer, but
+ this progress callback is called separately for each file that is
+ transferred, and there are no parameters that allow the caller to
+ determine which file a given callback corresponds to. This makes it very
+ difficult to monitor the progress.
+
+ To make this more usable, I've changed it so that the progress callback
+ doesn't simply report the number of bytes read and total size of the
+ current file. Instead, we add up the status of all current transfers and
+ report that value to the callback.
+
+ Don't wrap included headers in G_BEGIN|END_DECLS
+ Only the local declarations should be declared extern "C", otherwise it
+ can result in unexpected errors such as this (encountered while re-ordering
+ some include statements for a different patch):
+
+ CC channel-inputs.lo
+ In file included from /usr/include/glib-2.0/glib/gmacros.h:38:0,
+ from /usr/lib64/glib-2.0/include/glibconfig.h:9,
+ from /usr/include/glib-2.0/glib/gtypes.h:32,
+ from /usr/include/glib-2.0/glib/galloca.h:32,
+ from /usr/include/glib-2.0/glib.h:30,
+ from /usr/include/glib-2.0/gobject/gbinding.h:28,
+ from /usr/include/glib-2.0/glib-object.h:23,
+ from /usr/include/glib-2.0/gio/gioenums.h:28,
+ from /usr/include/glib-2.0/gio/giotypes.h:28,
+ from /usr/include/glib-2.0/gio/gio.h:26,
+ from ../../src/spice-channel.h:27,
+ from ../../src/channel-inputs.h:25,
+ from ../../src/channel-inputs.c:20:
+ /usr/lib/gcc/x86_64-redhat-linux/4.9.2/include/stddef.h:147:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'typedef'
+ typedef __PTRDIFF_TYPE__ ptrdiff_t;
+ ^
+
+ Gtk applications should only include spice-client-gtk.h
+ This header is the single include needed for all gtk-related
+ functionality, similar to spice-client.h. Generate a compiler warning if
+ a different header is included.
+
+ Glib applications should only include spice-client.h
+ Generate a compiler warning if an application attempts to include a
+ different header.
+
+2015-09-28 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Fix documentation for spice_main_file_copy_async()
+ 'sources' should be a NULL-terminated array, but the parameter
+ documentation treats it as if it is a single file object.
+
+2015-09-25 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Update NEWS for 0.30 release
+
+ Move glib-compat.c to POTFILES.skip
+ Since these messages are only used for terminal debug output, let's not
+ waste time translating them.
+
+2015-09-25 Pavel Grunt <pgrunt@redhat.com>
+
+ docs: Fix typos
+
+ docs: Add missing symbol description strings
+
+ docs: Description should be above 'Return'
+
+ docs: Add missing parameter/field descriptions
+
+ docs: Move SPICE_TYPE_USB_DEVICE to standard subsection
+
+ docs: Add Version Information section
+
+ docs: Update for missing symbols
+
+ channel-main: Rename parameter to match docs
+
+ channel-record: Use correct nick name for property
+
+2015-09-23 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Add glib-compat.c to POTFILES.in
+ Some translatable strings were added in commit 8c37a340.
+
+2015-09-18 sstuts <sstutsma@redhat.com>
+
+ Add "monitors config position" capability.
+ This will allow Windows guests to determine if the client supports a
+ monitors_config message from a multi-monitor guest that is not
+ multi-headed, i.e., that has one monitor per driver.
+
+ It keeps commit:8b0cd321d5a4d08ccba5845c5f2206e6f8032c1d
+ from breaking if an updated win-qxl driver is paired with an older client.
+
+ This resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1248189
+ ---
+ Changed from v1: Removed a local commit that preceded this one.
+ ---
+ Changed from v2: Changed name to "monitors config position"
+ ---
+
+2015-09-15 Christophe Fergeau <cfergeau@redhat.com>
+
+ build-sys: Fix spice-protocol requirements in .pc file
+ Commit d0ae58a8 added spice-protocol >= 0.12.10 to the Requires.private
+ field in spice-client-glib.pc. However it's already present in the
+ Requires field without a version check. Once spice-gtk is built and
+ installed, building a program against spice-gtk needs spice-protocol,
+ but no specific version of it, so we can drop the duplicate
+ Requires.private requirement, and keep the unversioned one in Requires.
+
+2015-09-11 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Don't send monitors config when Display widget is created
+ When a display channel is associated with a particular SpiceDisplay
+ widget, it previously set the display to 'enabled' unconditionally.
+ There is a couple of problems with this behavior.
+
+ First, simply because a display widget has an associated display
+ channel, it doesn't necessarily mean that the display is enabled. On
+ linux guests, for instance, a display channel can have up to 4 displays
+ for one channel, and perhaps only one of them is enabled. So, we
+ shouldn't set the display to 'enabled' until we actually receive a
+ monitors configuration message indicating that this display is enabled.
+
+ The second problem is that this was triggering the client to send down a
+ new monitors-config message to the server. This message is completely
+ unnecessary since it is triggered by a message from the server. We
+ should only be sending down new monitor configurations in response to
+ changes from the client, not from the server.
+
+ Add spice_main_update_display_enabled()
+ This is a new function that allows the caller to decide whether to send
+ the new status down to the server or not (analogous to the difference
+ between spice_main_set_display() vs spice_man_update_display()).
+
+ This new function is needed to reduce unnecessary MonitorsConfig
+ messages from being sent to the server. Because spice-gtk does not
+ maintain any display state internally, it depends on the application to
+ maintain that state. Some state changes come from the server itself
+ (e.g. the guest has changed resolution due to some activity within the
+ guest), and some come from the application (e.g. the user has resized
+ the window of the client). Changes that come from server updates do not
+ need to be sent back down to the server, whereas those that originate
+ from the application *do* need to be sent to the server.
+
+2015-09-09 Pavel Grunt <pgrunt@redhat.com>
+
+ file-xfer: Simplify time handling
+ Use g_get_monotonic_time() instead of g_date_time_new_now_local().
+ g_get_monotonic_time doesn't suffer discontinuities and it is sufficient
+ for our purposes. There is no need for the complexity of GDateTime.
+
+2015-09-08 Victor Toso <victortoso@redhat.com>
+
+ audio: Do not volume-sync without audio
+ In case audio backend is not initialized correctly or there isn't audio
+ in the VM, we should not try to volume-sync.
+
+ Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1257210
+
+2015-08-25 Pavel Grunt <pgrunt@redhat.com>
+
+ file-xfer: Add debug messages about a file transfer progress
+ During the file transfer debug messages about the progress are printed
+ every 20 seconds for each of the file transfer tasks.
+
+ Fixes:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1140512
+
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+ glib-compat: Add g_format_size
+ g_format_size_for_display is deprecated since glib 2.30. See glib commit
+ afd1e3697065c1bd23fe9a1cacf43d8744d0bc9b
+
+ g_format_size will be used in the following commit
+
+ Acked-by: Frediano Ziglio <fziglio@redhat.com>
+
+2015-08-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: update spice_session_connect() doc
+ Update the documentation about the return value, and how to watch for
+ connection success.
+
+ Releated to:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1253848
+
+2015-08-14 Christophe Fergeau <cfergeau@redhat.com>
+
+ Adjust to new SpiceImageCompress name
+ This has been renamed to SpiceImageCompression in order to avoid clashes
+ with older spice-server in the SPICE_IMAGE_COMPRESS_ namespace. This
+ commit is a straight rename of SpiceImageCompress to
+ SpiceImageCompression and SPICE_IMAGE_COMPRESS_ to
+ SPICE_IMAGE_COMPRESSION_
+
+ build-sys: Remove spice-protocol submodule
+ It's seeing regular releases and is API stable, so we don't need to
+ bundle it with spice-gtk
+
+2015-08-05 Christophe Fergeau <cfergeau@redhat.com>
+
+ usbredir: Add a few debug logs
+ Currently, spice-gtk debugging logs contain no traces of the
+ values of the auto-redir/redir-on-connect filter, and it does not tell
+ you about the vid/pid of the devices being connected/redirected.
+ This commit adds the appropriate SPICE_DEBUG/CHANNEL_DEBUG calls so that
+ this data is logged.
+
+ channel: Don't warn when no CA is set
+ Since v0.22~19 "Use system-wide trust certificate store", when neither
+ SpiceSession::ca-file nor SpiceSession::ca are set, the system-wide
+ CA store will be used to validate the SPICE certificates.
+ However, there is still a g_warn_if_fail() checking that either ca or
+ ca-file are set, which causes a runtime warning when trying to use the
+ system-wide store. This commit removes it.
+
+2015-08-03 Pavel Grunt <pgrunt@redhat.com>
+
+ Notify about existence of monitor for all display channels
+ Windows guest can have disabled display on the display chanel #0, in
+ that case it will not be listed in virt-viewer's "View->Displays" menu
+
+ Resolves:
+ https://bugs.freedesktop.org/show_bug.cgi?id=91489
+
+2015-07-29 Sandy Stutsman <sstutsma@redhat.com>
+
+ Handle single headed monitors that have a non-zero x, y config
+ Each monitor on a Windows guest is represented as a separate, single-headed
+ device with its own framebuffer. When there are multiple monitors, all
+ monitors but one will have a non-zero xy config position. But even in
+ these cases the whole area (frame-buffer) of each monitor should be
+ updated.
+
+ Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1202419
+
+2015-07-28 Jeremy White <jwhite@codeweavers.com>
+
+ Add the gtk libraries to the gtk-scandoc link line.
+ This prevents a compile error on Debian Jessie, when building from git.
+
+ This is fairly subtle, and Debian specific. It only happens when you use
+ autoreconf to generate a new libtool script. Debian patches that script
+ to require an explicit setting to link with all dependent libraries.
+
+ It should be harmless on other distros, and it does save us Debian guys some
+ hassle.
+
+2015-07-14 Pavel Grunt <pgrunt@redhat.com>
+
+ Use g_return_val_if_fail instead of wrong g_return_if_fail
+ The commit 4b5e6ec2114e1250c81027ebeac9cfe8d059153f introduced a function
+ returning gboolean, g_return_val_if_fail() should be used instead of
+ g_return_if_fail().
+
+2015-07-13 Pavel Grunt <pgrunt@redhat.com>
+
+ Send monitor config if at least one monitor has dimensions
+ If a client (virt-manager, spicy) is not setting display dimensions
+ and the "resize-guest" property is disabled, spice-gtk sends a wrong
+ monitor config message where all the monitors have width = heigh = 0
+ when the agent connects. This message can confuse the guest, in that
+ case the guest will change the resolution of its monitor.
+
+ Regression since 28312b8d1e287a320851e8828825f2ca138d8b0b
+
+ Resolves:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1240721
+
+2015-07-10 Sandy Stutsman <sstutsma@redhat.com>
+
+ This adds reference counting to cached images.
+ Windows guests with multi-monitors will often send down the same image
+ via different channels. If these instances are not counted, one channel
+ can delete an image before all the rest of the channels are finished with
+ it. In this case, the client will hang.
+
+ This can happen, for instance, when the Windows guest is updating the
+ monitor's wallpaper. There is a driver instance for each monitor, so each
+ one is sending down its own copy of the same image with the same id. As
+ one channel may be busier than another, the order that the client executes
+ commands may not be the same order as the server issued them. Here's what
+ can happen:
+
+ On the server side:
+ Monitor 1 sends image A
+ Monitor 1 sends multiple rendering commands for image A
+ Monitor 1 removes image A
+ Monitor 2 sends image A
+ Monitor 2 sends rendering commands for image A
+ On the client side:
+ Monitor 1 adds image A to the cache
+ Monitor 1 starts rendering with image A
+ Monitor 2 adds image A to the cache - has same id, so image is replaced
+ Monitor 1 removes image A - image A is completely removed from cache
+ Monitor 2 render command hangs waiting for image A
+
+ Addresses bug: https://bugzilla.redhat.com/show_bug.cgi?id=1194354
+
+2015-07-06 Christophe Fergeau <cfergeau@redhat.com>
+
+ Update spice-protocol
+ This will fix EL6 builds.
+
+ Christophe Fergeau (1):
+ m4: Add compat AS_VAR_APPEND for older autoconf
+
+ Lukas Venhoda (3):
+ ppc: Fix quic decode endianess
+ ppc: Fix lz magic endianess
+ ppc: Fix quic magic endianess
+
+2015-06-30 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Make monitors config debug output more clear
+ Indicate whether the monitors config debug output is from sending or
+ receiving new monitors configuration. You can tell this by looking at
+ which channel is involved (main vs display), but making it more explicit
+ is helpful for glancing through logs.
+
+2015-06-29 Javier Celaya <javier.celaya@flexvdi.com>
+
+ Display: Send a preferred compression message on init.
+ If the user prefers a specific compression algorithm, report it when
+ setting up the display channel.
+
+ Add a preferred-compression program option
+
+ Spice-session: Add preferred-compression property.
+ Also, depend on the spice-common commit that introduces the
+ SpiceImageCompress enum.
+
+2015-06-26 Christophe Fergeau <cfergeau@redhat.com>
+
+ build-sys: Fix build with automake < 1.13
+ AC_CONFIG_MACRO_DIRS is not available with older automake versions,
+ which causes autogen.sh failures on RHEL6. m4_include() can be used
+ instead.
+
+2015-06-25 Pavel Grunt <pgrunt@redhat.com>
+
+ Send monitor config if guest supports sparse monitors
+ It is ok to send monitor configuration even for displays which are not
+ disabled or enabled. Because the guest having support for the sparse
+ monitor configuration (VD_AGENT_CAP_SPARSE_MONITORS_CONFIG) will not
+ resize the monitor which is disabled / undefined.
+
+ Fixes:
+ https://bugs.freedesktop.org/show_bug.cgi?id=90914
+
+ channel-main: Use enum to describe display state
+
+2015-06-22 Christophe Fergeau <cfergeau@redhat.com>
+
+ build-sys: Use SPICE_CHECK_LZ4
+ spice-common now has an m4 macro adding a --enable-lz4 option and
+ doing the needed checks, so we can use it in configure.ac rather than
+ duplicating it here.
+
+ build-sys: Use SPICE_CHECK_SMARTCARD
+ spice-common has an m4 macro adding a --enable-smartcard option and
+ doing the needed checks, so we can use it in configure.ac rather than
+ duplicating it here.
+
+2015-06-19 Christophe Fergeau <cfergeau@redhat.com>
+
+ spicy-*: Remove translation support
+ These are only meant to be test tools so they don't need to be
+ translated.
+
+2015-06-18 Lukas Venhoda <lvenhoda@redhat.com>
+
+ spicy: Enable recent chooser on windows
+ Recent chooser is working correctly in windows.
+
+ spicy: Replace duplicated code with a for loop
+ Changed piece of code working with fixed size array into a for loop.
+
+ spicy: Host and port (or tls) are now required
+ Connect button is now non-sensitive when host and port (or tls) entry is empty.
+ Pressing enter will now also NOT connect, when the entries are empty.
+
+ spicy: Fixed reselecting in recent chooser
+ Selecting an entry in the recent connections list, and then modifying
+ the host/port/TLS port, and double-clicking on that same entry in the
+ list would cause spicy to connect to the edited address rather than
+ the one which was picked in the recent chooser.
+
+ After this commit, the selection will be cleared from the recent
+ chooser, and double-clicking on an entry after editing it will always
+ trigger a 'selection-changed' signal, which will properly set the
+ address to connect to.
+
+ spicy: Changed the dialog into a window
+ Changed connect dialog from GtkDialog to GtkWindow.
+
+ Added the necessary signals and buttons, to keep then
+ behaviour of a dialog (ESC to close, ENTER to submit).
+
+ spicy_connect_dialog now returns TRUE and FALSE instead of 0 and -1.
+
+ spicy: Move connect dialog to its own file
+ Connect dialog from spicy is now in its own file.
+
+ Renamed connect_dialog to spicy_connect_dialog.
+
+ Added new file for translation.
+
+2015-06-18 Victor Toso <victortoso@redhat.com>
+
+ spice-widget: keypress-delay set by env var
+
+2015-06-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Prepare for 0.29 release
+
+ channel: check too long password
+ Make sure that the password length is under the maximum lenght. If not
+ report it as an authentication failure with an adapted message.
+
+2015-06-15 Pavel Grunt <pgrunt@redhat.com>
+
+ configure: Try gstreamer audio backend if pulse is not available
+ Disable audio if no backend is available and configure is used with
+ the option '--with-audio=auto'
+
+2015-06-09 Victor Toso <victortoso@redhat.com>
+
+ webdav: keep phodav requirements inside USE_PHODAV
+ Commit 33d4016228798108250b0ef9173f2c4c719a5065 uses
+ g_output_stream_write_all_async/finish which is on gio 2.44 version.
+ This breaks the build on older systems even if --disable-webdav is used.
+
+ Using #USE_PHODAV to wrap those functions that will not be called
+ without --enable-webdav.
+
+2015-06-09 Fabiano Fidêncio <fidencio@redhat.com>
+
+ spice-widget: Do not update display when resize-guest is disabled
+ Updating the display causes weird behaviors in virt-viewer, like
+ re-resizing to a previous monitor config when, after changing the
+ display resolution (through System > PReferences > Displays). the agent
+ reconnects.
+ It is not perfect yet, because when the agent reconnects the guest
+ resizes to the previous config and switch to the proper one, but this
+ seems more like an agent bug than a spice-gtk one.
+
+2015-06-08 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ channel: use class private handlers field
+ Since spice-gtk requires glib 2.28, we can now fix a small FIXME.
+
+ Since G_TYPE_CLASS_GET_PRIVATE is a bit expensive, it's still worth to
+ cache it in klass->priv. However, there is no good place I can think of
+ to put this. (channel_class_init() is called only once, and not per
+ each subclass)
+
+ Move gtk/ -> src/
+ For historical reasons, the code was placed under gtk/ subdirectory.
+ If it was always bugging you, bug no more!
+
+ TODO: update
+ Remove outdated items:
+ - ChannelBaseAudio?,
+ - GDI backend wouldn't work well with scaling (moved to fdo bug)
+
+ Fix fdo link
+
+2015-06-08 Pavel Grunt <pgrunt@redhat.com>
+
+ usb-device-manager: Avoid error when compiling with --disable-usbredir
+
+2015-06-05 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ usb: remove useless assignments
+ The struct is g_new0() already.
+
+ win-usb: try to connect to usbclerk during init
+ Fail early during initialization if the usbclerk service can't be
+ reached.
+
+ This changes the current behaviour that would retry to connect to
+ usbclerk every time to perform an operation. Now, it will try each time
+ the UsbDeviceManager is initialized.
+
+ usb: do not return GError on programmer pre-condition checks
+ Use regular g_return precondition checks.
+
+ win-usb: remove useless function
+
+ usb: misc code formatting
+
+ usb: call win_usb_driver_new() during initable_init()
+ Throw an error when initialization failed.
+
+ usb: use SPICE_CLIENT_ERROR_ prefix
+ To be consistent with GLib idioms, the code should use a common prefix for errors.
+
+ usb: unref the device when it is no longer needed
+ The current code unref() the device too early, it must be unref
+ after it is no longer needed.
+
+ win-usb: get rid of status code return in async ops
+
+ win-usb: throw an error if reply.status == 0
+
+ usb: use win-usb uninstall_finish()
+
+ win-usb: rename async functions
+
+ win-usb: introduce a spice_win_usb_driver_op_finish
+ We want the exported functions to follow the gio async idom. Currently,
+ both install() and uninstall() are paired with install_finish(). In the
+ following patch we introduce uninstall_async() uninstall_finish() using
+ that common internal op_finish() function. Then we correctly pair
+ associated async/finish() calls.
+
+ usb: remove useless declaration
+
+2015-06-05 Victor Toso <victortoso@redhat.com>
+
+ tests: add test to check for zombie GSources
+ Using g_pollable_input_stream_create_source to generage several dummy
+ GSources in order to check if giopipe sets all of them to be dispatched.
+
+ This test check for zombie GSources during a write_all/read_chunk
+ operation.
+
+ tests: add test to concurrent write to pipe
+ Concurrent write is not supported and should fail. The GIO error is
+ G_IO_ERROR_PENDING
+
+ tests: pipe using _write_all_async function
+
+ tests: remove read8_cb to use generic read_cb
+ Both functions are basic the same so let's keep the generic one.
+
+ webdav: write all buffer to client webdav
+ Client's webdav can request less data (8192) then the amount sent by
+ guest's webdav. Using g_output_stream_write_all_async in order to avoid
+ losing data.
+
+ giopipe: don't fail on create_source
+ PipeInputStream and PipeOutputStream should not fail when creating
+ GPollableStream source as this currently does not work with default
+ write_all and read_all functions;
+
+ In order to avoid creating zombie GSource in create_source of both
+ PipeInputStream and PipeOutputStream, we track all created GSources and
+ set them to be dispatched when data is available to read/write. It is
+ worth to mention that concurrent write/read is not possible with current
+ giopipe and only the last created GSource will read the data as it is
+ dispatched first.
+
+2015-06-03 Pavel Grunt <pgrunt@redhat.com>
+
+ session: Enable proxy when requested
+ Disabling the proxy avoids usage of GProxyResolver to determine
+ the necessary proxy protocol and to do the proxy negotiation.
+
+2015-05-28 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: disable default socket proxy
+ GSocketClient uses the system proxy by default, and it may end up using
+ the system HTTP proxy with bad results if CONNECT is not
+ supported. spice-gtk uses it's own SPICE_PROXY instead, and doesn't rely
+ on GSocketClient default proxy but GProxyAddress instead. Disabling the
+ default proxy solve a wrong proxy from being used.
+
+ It may be worth to revisit this change if GSocketClient can be told to
+ ignore proxies that are not eligible for Spice connections. (HTTP could
+ be though, in which case it would be a user configuration issue)
+
+ Fixes:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1040679
+
+2015-05-21 Benjamin Gilbert <bgilbert@cs.cmu.edu>
+
+ Drop expansions of removed CFLAGS/LIBS variables
+
+2015-05-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ iopipe: fix leak of streams
+ g_simple_io_stream_new() do not steal references from us, unref the
+ streams to avoid the leaks.
+
+ Leak found by Victor Toso.
+
+ ==30787== 2,808 (648 direct, 2,160 indirect) bytes in 9 blocks are definitely lost in loss record 479 of 482
+ ==30787== at 0x93AEBFD: g_type_create_instance (gtype.c:1849)
+ ==30787== by 0x939128A: g_object_new_internal (gobject.c:1774)
+ ==30787== by 0x9392AA0: g_object_newv (gobject.c:1921)
+ ==30787== by 0x939338B: g_object_new (gobject.c:1614)
+ ==30787== by 0x403B30: make_gio_pipe (giopipe.c:441)
+ ==30787== by 0x403C8E: spice_make_pipe (giopipe.c:465)
+ ==30787== by 0x4029B5: fixture_set_up (pipe.c:42)
+ ==30787== by 0x9844EC8: test_case_run (gtestutils.c:2123)
+ ==30787== by 0x9844EC8: g_test_run_suite_internal (gtestutils.c:2185)
+ ==30787== by 0x984509A: g_test_run_suite_internal (gtestutils.c:2196)
+ ==30787== by 0x98453FA: g_test_run_suite (gtestutils.c:2249)
+ ==30787== by 0x9845430: g_test_run (gtestutils.c:1553)
+ ==30787== by 0x402012: main (pipe.c:312)
+
+2015-05-12 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ spicy: remove useless signal handlers
+ There is no strong reason to have signal handlers in spicy (a test
+ tool). Clean quit can be achieved through the File/Quit menu.
+
+ Fixes:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1197175
+
+2015-05-12 Lukas Venhoda <lvenhoda@redhat.com>
+
+ spice-gtk: Fixed build when using audio gstreamer
+ Commit No. 63bf00275769928850113b4df205df08d6303b45 changed number of
+ arguments of function playback_stop(), and didn't change call of this
+ function on line 628.
+
+ This would break building when using --with-audio=gstreamer
+
+2015-05-07 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ webdav: check g_output_stream_write_all() return value
+ Check g_output_stream_write_all() return value to silence a coverity
+ CHECKED_RETURN warning
+
+ usb: channel-new handler to be after default handlers
+ Client usually connect to channel-new to connect their
+ handlers, such as open-fd.
+
+ The usbmanager channel-new handler will call channel_connect() on usbredir
+ channels, which may call open-fd.
+
+ However, open-fd can be emitted before the client had a chance to
+ connect their handlers (from the channel-new callback).
+
+ Connecting after the default handler solves this case.
+
+ Fixes:
+ https://bugzilla.gnome.org/show_bug.cgi?id=748665
+
+ session: do not attempt to open_host if session changed
+ Since channel can become session-less, let's check they still have the
+ expected session when running the open-host idle.
+
+ audio: stop playback on channel destroyed
+ Ensure playback is stopped when the channel is destroyed.
+
+ audio: use swapped channel handler for stop
+ We are going to reuse playback_stop() in following commit.
+
+ record: do not crash after record is stopped
+ If spice_record_send_data() after a reset, last_frame is NULL and memcpy
+ will crash. Check if the recording was started if last_frame != NULL
+ instead.
+
+ Program received signal SIGSEGV, Segmentation fault.
+ __memcpy_avx_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S:204
+ 204 vmovdqa %ymm0, (%rdi)
+ (gdb) bt
+ #0 __memcpy_avx_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S:204
+ #1 0x00007ffff44f57b5 in spice_record_send_data (channel=0x1228640, data=0x7fff9ad0f000, bytes=960, time=0) at channel-record.c:349
+ #2 0x00007ffff45162f0 in stream_read_callback (s=0xad8c00, length=960, data=<optimized out>) at spice-pulse.c:485
+ #3 0x00007ffff2ea0c76 in pstream_memblock_callback (p=<optimized out>, channel=<optimized out>, offset=0, seek=PA_SEEK_RELATIVE, chunk=0x7fffffffcf70, userdata=0x11e71c0) at pulse/context.c:411
+ #4 0x00007fffe8da8b4f in do_read (p=p@entry=0x123a050, re=re@entry=0x123a1d0) at pulsecore/pstream.c:906
+ #5 0x00007fffe8daae87 in do_pstream_read_write (p=0x123a050) at pulsecore/pstream.c:193
+ #6 0x00007ffff30e1bea in dispatch_func (source=0x1111e50, callback=<optimized out>, userdata=<optimized out>) at pulse/glib-mainloop.c:584
+ #7 0x00007fffed76b93b in g_main_dispatch (context=0x816ea0) at gmain.c:3122
+
+ Fixes:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1215343
+
+ playback: do not set mm time when session-less
+ Channels do not hold a strong reference on the session (because session
+ can be recycled after disconnect), do not print a warning if the channel
+ is session-less when updating the delay.
+
+ audio: emit stop when the channels are reset
+ Ensure a hint is given to the client that the channel is reset.
+
+ Unfortunately, since the handle may be asynchronous due to coroutine,
+ the channel functions should be tolerant to a playback/record calls
+ functions when the channel is stopped.
+
+ audio: channel-new handler to be after default handlers
+ Client usually connect to channel-new to connect their
+ handlers, such as open-fd.
+
+ The audio channel-new handler will call channel_connect() on audio
+ channels, which may call open-fd.
+
+ However, open-fd can be emitted before the client had a chance to
+ connect their handlers (from the channel-new callback).
+
+ Connecting after the default handler solves this case.
+
+ Fixes:
+ https://bugzilla.gnome.org/show_bug.cgi?id=747649
+
+2015-04-30 Victor Toso <victortoso@redhat.com>
+
+ spice-pulse: compatibility with old pulse version
+ The commit 37ba949716ebf441110330 breaks compatibility with old versions
+ of libpulse as the volume and mute data in pa_source_output_info were
+ available only from version 1.0.0 onwards. Using other API function for
+ this which does not relay on audio per stream.
+
+ spice-pulse: GSimpleAsyncResult compatibility
+ Avoid breaking build with glib older then 2.32 which is when
+ g_simple_async_result_set_check_cancellable was introduced.
+
+ glib-compat: add G_SOURCE_REMOVE G_SOURCE_CONTINUE
+
+2015-04-28 Fabiano Fidêncio <fidencio@redhat.com>
+
+ session: Get the lock modifiers from GdkKeymap
+ A cleaner way to get the lock modifiers, without depend on the
+ platform/backend used (as X or Wayland), is get them through GdkKeymap
+ (and its _get{caps,num,scroll}_lock_state() functions).
+ Unfortunately, get_scroll_lock_state() will only be present for Gtk+
+ 3.18.0 and when it becomes the minimal required version we can easily
+ drop the old code.
+
+2015-04-24 Victor Toso <victortoso@redhat.com>
+
+ agent: sync guest audio with client values
+ Functions to sync volume and mute value when necessary. In this patch,
+ only one sync is allowed after agent connect.
+
+ Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1012868
+
+ audio: spice-gstaudio implements async volume-info
+ Gstaudio rely on sink/src elements to get the volume/mute.
+ (e.g. pulsesink and pulsesrc, the values are updated by PulseAudio
+ itself when requested)
+
+ audio: spice-pulse implement async volume-info
+ In case of volume-sync between client and guest, we request volume-info
+ from the availables streams and if the stream is not available we rely
+ on ext-stream-restore.
+
+ By using ext-stream-restore we can get the last stream data of the
+ application that is stored by PulseAudio.
+
+ Related: https://bugzilla.redhat.com/show_bug.cgi?id=1012868
+
+ audio: spice-audio with get mute and volume
+ Async functions to be implemented by spice-gstaudio and spice-pulse to
+ get the updated volume and mute values for playback and record stream.
+
+ Related: https://bugzilla.redhat.com/show_bug.cgi?id=1012868
+
+ Update spice-common submodule
+ This includes volume synchronization protocol;
+
+2015-04-24 Pavel Grunt <pgrunt@redhat.com>
+
+ spice-widget: Do not invalidate cursor when display is not ready
+ spice_display_get_scaling() gives wrong x, y coordinates and scaling
+ when the display is not ready. The wrong values cause runtime
+ warnings when disabling a virt-viewer's window:
+ Gtk-CRITICAL **: gtk_widget_queue_draw_area: assertion 'width >= 0' failed
+
+2015-04-16 Christophe Fergeau <cfergeau@redhat.com>
+
+ Fix GSocketAddress leak in proxy_lookup_ready()
+ g_proxy_address_new() returns a new GProxyAddress, so we must unref it
+ when no longer needed.
+
+ This fixes:
+
+ ==6481== 234 (48 direct, 186 indirect) bytes in 1 blocks are definitely lost in loss record 10,062 of 10,
+ ==6481== at 0x31FF230A58: g_type_create_instance (gtype.c:1849)
+ ==6481== by 0x31FF21501A: g_object_new_internal (gobject.c:1774)
+ ==6481== by 0x31FF216EB4: g_object_new_valist (gobject.c:2033)
+ ==6481== by 0x31FF217220: g_object_new (gobject.c:1617)
+ ==6481== by 0x3D4386F33A: g_proxy_address_new (gproxyaddress.c:325)
+ ==6481== by 0x5717440: proxy_lookup_ready (spice-session.c:2011)
+ ==6481== by 0x3D43885082: g_task_return_now (gtask.c:1088)
+ ==6481== by 0x3D438850B8: complete_in_idle_cb (gtask.c:1102)
+ ==6481== by 0x31FEE4A0B9: g_main_dispatch (gmain.c:3122)
+ ==6481== by 0x31FEE4A0B9: g_main_context_dispatch (gmain.c:3737)
+ ==6481== by 0x31FEE4A44F: g_main_context_iterate.isra.29 (gmain.c:3808)
+ ==6481== by 0x31FEE4A771: g_main_loop_run (gmain.c:4002)
+ ==6481== by 0x363AC06CC4: gtk_main (in /usr/lib64/libgtk-3.so.0.1600.1)
+
+2015-04-16 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Make update-symbol-files work when builddir != srcdir
+ rewrite the update-symbol-files rule to use dependencies and automatic
+ variables ($^) so that VPATH will allow make to find these files in the
+ srcdir as well as the builddir.
+
+2015-04-14 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ channel: HUP is not an error condition
+ On local UNIX sockets, calling close() in the server side will result in
+ a HUP condition on client side. Since this is not an error, but a normal
+ termination, let's ignore it.
+
+ A clean shutdown would involve a new message to tell the client to first
+ close its end, in order to avoid the HUP. That way the client could
+ distinguish normal termination from unexpected ones. That's a possible
+ future minor enhancement (it seems it would only work with UNIX socket
+ though)
+
+ G_IO_IN seemed to be a leftover, it is left here but shouldn't be
+ required.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=90016
+
+ channel: reset c->has_error when connected
+ Whenever the channel socket is connected, c->has_error should be reset.
+ Until now, only the regular open_host() case was reset, but client
+ client provided fd must also reset the error state.
+
+ It should be safe to move it after the "connected" label, since the
+ ssl code doesn't need c->has_error.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=1211063
+
+2015-04-01 Victor Toso <victortoso@redhat.com>
+
+ audio: keep compatibility with old pulse version
+ The commit 9ef68ecd1fd11dea626628 breaks compatibility with old versions
+ of libpulse as the source_output functions were available from version
+ 1.0.0 onwards.
+
+2015-03-27 Pavel Grunt <pgrunt@redhat.com>
+
+ channel-smartcard: Add missing USE_SMARTCARD checks
+ In order to enable build without smartcard support
+
+2015-03-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ smartcard: add reader and cards on channel up
+ The smartcard manager reports reader/card events on insertion and
+ removal. If a smartcard channel is created after those events, the
+ channel state will not be in sync with the current reader/card state.
+ Sync the state when the channel is up.
+
+ Fixes:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1205171
+
+ smartcard: connect object signal handlers with spice helper
+ The smartcard manager may outlive the smartcard channels. Make sure the
+ channel handlers are disconnected when the channel is free by using
+ spice_g_signal_connect_object() helper. This fixes crashes when
+ dispatching smartcard events on deleted channels.
+
+ Related bug:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1205171
+
+2015-03-23 Victor Toso <victortoso@redhat.com>
+
+ audio: use stream functions for pulse source
+ The functions pa_context_set_source_output_mute/volume are specifically
+ to change source stream volume/mute.
+ I changed the warnings to be compatible to sink_input ones;
+
+2015-03-23 Christophe Fergeau <cfergeau@redhat.com>
+
+ session: Tone down warning on TLS-only connections
+ 315c1a5 "session: Add more debugging logs" causes a g_warning() to be
+ shown when attempting a TLS connection without specifying a non-TLS
+ port.
+ This commit makes the message more explicit, and switches it from being
+ a warning to being a debug message.
+
+2015-03-12 Pavel Grunt <pgrunt@redhat.com>
+
+ channel-usbredir: Do not stop event listening if SpiceSession does not exist
+ Avoids Segfault when closing the connection just after the usb device redirection.
+
+2015-03-04 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: fix out-of-tree build from tarball
+ There are generated files in build directory too. Fixes:
+
+ CC util.o
+ In file included from ../../tests/session.c:3:0:
+ ../../gtk/spice-session.h:24:30: fatal error: spice-glib-enums.h:
+ No such file or directory #include "spice-glib-enums.h"
+
+ Prepare v0.28 release
+
+2015-03-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: fix required libsoup version for webdav support
+
+ Revert spice-common change
+ Commit 85ed268 shouldn't have change spice-common, my bad
+
+ session: bind path and read-only to webdav server
+ Keep the server property in sync with the session properties
+
+ session: add share-dir-ro property
+ Add a property to specify if share folder access is read-only.
+
+ webdav: use a pipe to connect to server
+ Instead of listening on TCP sockets, and proxying connections there,
+ make the webdav server accept new connections from stream. The streams
+ are user-space GIOStream pipe, one side is connected to the Spice webdav
+ channel muxer/demuxer, the other side is a SoupSocket client.
+
+ This makes the server not exposed any local public access, avoid the
+ need for server threads, or proxying the connections through system
+ sockets.
+
+ Use libphodav-2 (breaks webdav server temporarily)
+ This change breaks webdav server, since libphodav-2 no longer
+ set up a TCP service running in a thread. It's up to the client
+ to decide how best to accept and handle new connections.
+
+ This commits remove all the hacks related to proxying the incoming
+ connections to a TCP socket, and protected with a magic sequence.
+
+ The following commit will use GIOStream pipes to handle each client
+ connections.
+
+ Add GIOStream-based pipe
+ This code creates a pipe between 2 GIOStream, the input side read from
+ the peer output side, and vice-versa.
+
+ In the following patches, this will avoid the socket communication
+ to exchange with the embedded webdav server.
+
+ glib-2.0 >= 2.43.90 because GSimpleIOStream dependency.
+
+2015-02-27 Victor Toso <victortoso@redhat.com>
+
+ tests: add spice-session test
+ Checking if URIs are being parsed and generated correctly.
+
+ session: accept argument in URI without value
+ The examples below should be considered valid URIs:
+
+ e.g: spice://localhost?port=5900&tls-port=
+ e.g: spice://localhost?tls-port=&port=5900
+
+ This patch deals with arguments with empty value;
+
+2015-02-23 Pavel Grunt <pgrunt@redhat.com>
+
+ vncdisplaykeymap: Use XkbGetMap and XkbGetNames instead of XkbGetKeyboard
+ XkbGetKeyboard does not work in XWayland (bfo#89240).
+
+ Fixes https://bugs.freedesktop.org/show_bug.cgi?id=89105
+
+2015-02-18 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: reset connection_id on switch-host
+ The server expects no connection_id during link time, in order to
+ realize a full reconnection.
+
+ The alternative would be to assume that the destination server has the
+ exact same channels and attempt to recreate and to reconnect them one by
+ one. However, if the destination is slightly different (say,
+ configuration or order of channels differs), this will likely fail. It's
+ best to start with a new session without prior knowledge.
+
+ channel: remove unused ChannelClass::channel_disconnect()
+ This virtual method turns out to be unnecessary anymore, and
+ was never override. channel_reset() is enough.
+
+ channel: set c->has_error to finish coroutine
+ It's unnecessary to call channel_disconnect() to finish the coroutine
+ and disconnect. Use c->has_error instead, like the rest of channel error
+ code.
+
+ Call channel_reset() directly when finishing coroutine
+ channel_disconnect() virtual method isn't overloaded by any
+ channel, and can be replaced by the equivalent channel_reset()
+ when finishing the coroutine.
+
+ channel: reset migration state when calling channel_reset()
+ channel_reset() is called in channel_disconnect(). We can just move that
+ state change in channel_reset() in order to get rid of
+ channel_disconnect().
+
+ channel: use exisiting reconnection code when switching
+ Switching for migration reason is similar to a reconnection during
+ initial connection.
+
+ A notable difference is that new code path doesn't schedule a
+ delayed_unref callback. This is fine since the channel is still running
+ and delayed_unref is mainly used for signaling disconnections and none
+ should be emitted when switching.
+
+ channel: reset channel state to unconnected
+ After coroutine has exited, reset channel state to unconnected,
+ this allows recycling a channel for reconnection, even in "normal"
+ disconnect/reconnect cases.
+
+ channel: remove useless precondition
+ This precondition isn't useful, since the channel is already
+ dereferenced before, and I've never seen an idle callback not passing
+ the user_data correctly.
+
+ channel: emit close event when coroutine has finished
+ Move signaling of closed channel after the coroutine has exited in
+ delayed_unref callback, similarly to error events, so it's easier to
+ schedule reconnect since coroutine has terminated.
+
+2015-02-16 Javier Celaya <javier.celaya@flexvm.es>
+
+ channel-port: Remove dependency cycle
+ channel-port.h includes spice-client.h, that includes channel-webdav.h,
+ that includes channel-port.h again. It's enough if channel-port.h
+ includes spice-channel.h
+
+ Without this change, if one tries to build a source file which only
+ includes spice-port.h, the build fails with:
+
+ In file included from /usr/include/spice-client-glib-2.0/spice-client.h:46:0,
+ from /usr/include/spice-client-glib-2.0/channel-port.h:22,
+ from ./port.c:1:
+ /usr/include/spice-client-glib-2.0/channel-webdav.h:44:5: error: unknown type name 'SpicePortChannel'
+ SpicePortChannel parent;
+ ^
+ /usr/include/spice-client-glib-2.0/channel-webdav.h:58:5: error: unknown type name 'SpicePortChannelClass'
+ SpicePortChannelClass parent_class;
+
+2015-02-16 Pavel Grunt <pgrunt@redhat.com>
+
+ widget: Do not draw cursor if widget is not realized
+ Silences the runtime warning in virt-viewer and gnome-boxes (bgo#744432):
+ Gtk-CRITICAL **: gtk_widget_queue_draw_area: assertion 'width >= 0' failed
+
+2015-02-12 Pavel Grunt <pgrunt@redhat.com>
+
+ widget: Send keys to guest when keyboard grab is released
+ Keys should be sent to the guest if the widget has the focus even
+ when the keyboard grab is released.
+
+2015-02-07 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ webdav: fix checking for shared directory property
+ Trivial fix for 6163828e8cb15d539c80cc3f0bfb5008be9b2247:
+ Channel should be created if the shared-dir property is set.
+
+2015-02-06 Benjamin Gilbert <bgilbert@cs.cmu.edu>
+
+ Don't build libspice-client-gtk if configured --without-gtk
+ libspice-client-glib is useful as a client library on platforms that
+ don't support GTK.
+
+2015-02-06 Christophe Fergeau <cfergeau@redhat.com>
+
+ Update git submodule
+ This fixes build with mingw as well as lz4 support:
+
+ 3aad79d LZ4: Do not include arpa/inet.h in Windows builds
+ 9287e53 LZ4: Add support for 24bit pixman surfaces
+ d167e2e LZ4: Fix the row alignment when it is not on a 32bit boundary
+ f76fc28 LZ4: Decode the image format from the stream
+ 83c0d64 LZ4: Adjust reading the top_down flag
+ 6049db4 LZ4: Fix output buffer size
+ ac26fd7 Remove redundant #if defined(SW_CANVAS_CACHE) || defined(SW_CANVAS_IMAGE_CACHE)
+ 062bf67 Remove unused 'invers' arg from canvas_get_*
+ 619b995 common: fix build with mingw
+ 862b9b1 build-sys: Move pixman check to m4 macro
+ 137b1a5 build-sys: Move opengl check to m4 macro
+ f9e0a64 build-sys: Move opus check to m4 macro
+ dd57d05 build-sys: Move celt check to m4 macro
+ fb3fe22 build-sys: Move smartcard check to m4 macro
+ df74a17 build-sys: Move posix checks to a separate m4 macro
+ 2f1ba3b build-sys: Add fallback for AS_VAR_APPEND
+ 2195369 build-sys: Small cleanup of AM_CPPFLAGS
+ ed873a9 build-sys: Remove unused WITH_SMARTCARD conditional
+ 2da14b6 build-sys: Remove unused win32 check
+ 5bfa9ca build-sys: Remove unused X check
+ 268d3e3 Remove unused header file
+
+2015-01-29 Christophe Fergeau <cfergeau@redhat.com>
+
+ Don't set SpiceSession::cmain twice during migration
+ During migration, migrate_connect() ends with:
+ spice_session_set_main_channel(mig->session,
+ migrate_channel_connect(mig, SPICE_CHANNEL_MAIN, 0));
+
+ migrate_channel_connect() calls spice_channel_new() which will create a
+ new SpiceMainChannel instance.
+ spice_channel_constructed() will be called during this instanciation,
+ which will call spice_session_channel_new(), which will set
+ SpiceSession::cmain for SpiceMainChannel instances.
+
+ When calling spice_session_set_main_channel(), SpiceSession::cmain will
+ thus already be set, which causes a runtime warning as
+ spice_session_set_main_channel() has a precondition checking that
+ SpiceSession::cmain is not set already.
+
+ This commit removes the call to spice_session_set_main_channel() from
+ migrate_connect() as this call is not doing anything more than the call
+ to migrate_channel_connect().
+
+ Remove runtime warning when setting a NULL shared-dir
+ Now that the webdav channel can cope with a NULL shared dir (by not
+ creating the webdav server), we no longer need to reject NULL shared
+ directories with a warning.
+
+ This fixes part of https://bugzilla.redhat.com/show_bug.cgi?id=1175721
+
+ webdav: Cope with NULL SpiceSession::shared-dir
+ shared-dir default value is
+ g_get_user_special_dir(G_USER_DIRECTORY_PUBLIC_SHARE)
+ which can be NULL (for example if ~/.config/user-dirs.dirs does not
+ exist).
+ This commit makes sure we don't create a PhodavServer when this occurs
+
+ display: Fix 'exisiting' typo in debug log
+
+ display: s/dropin/dropping in debug message
+
+ session: Add more debugging logs
+ Initial SPICE connection can sometimes fail without clear indications
+ where/how it failed. This commit adds more debug logs/more accurate logs
+ in order to help narrow down such issues.
+
+ display: Improve DisplayChannel::num_drops_on_arive name
+ 'arive' has a typo, and 'num_drops_on_receive' is clearer.
+
+ Use macro to swap data in spice_session_start_migrating()
+ spice_session_start_migrating() swaps connection details between 2
+ SpiceSession instances. Instead of doing it manually, use a macro to do
+ it for us.
+
+2015-01-29 Pavel Grunt <pgrunt@redhat.com>
+
+ desktop-integration: check owner of bus name
+ It avoids calling D-Bus methods when the bus name
+ "org.gnome.SessionManager" does not exist.
+
+ Silences:
+ GSpice-WARNING **: Error calling 'org.gnome.SessionManager.Inhibit': GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.SessionManager was not provided by any .service files
+
+2015-01-27 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ spicy: deal with spice+unix:// URI
+
+ session: teach spice_uri_create() about UNIX path
+
+ session: prettify query parameters
+ Use & as parameters separators, this is more usual. Remove
+ trailing one, no further parameters are useful anyway.
+
+ session: return allocated string from spice_uri_create()
+ This allows more flexible string building.
+
+ session: parse spice+unix:// URI
+
+ session: connect to UNIX path
+
+ session: add unix-path property
+
+ channel: reset connection state on error
+ Fix regression introduced in 6b475802, to permit reconnection on error,
+ the channel state must be < STATE_CONNECTING. Since the error is
+ reported after coroutine exits and channel is reset, the state can be
+ modified before throwing the error now.
+
+ channel: reset tls state when client calls connect
+ The channel TLS state is kept during disconnection and reset, for
+ automatic reconnection and migrations reasons. However, when
+ spice_channel_connect() is called by client, it should first try
+ non-TLS connection.
+
+ channel: delay event report to after coroutine exit
+ Move to a common place error reporting, after the coroutine exits.
+
+2015-01-23 Pavel Grunt <pgrunt@redhat.com>
+
+ spice-widget: Don't return early from focus_in_event when widget is not realized
+ Otherwise SpiceDisplay might not get the keyboard grab.
+ It also silence GSpice-CRITICAL on focus out event:
+ GSpice-CRITICAL **: spice_gtk_session_request_auto_usbredir: assertion 's->auto_usbredir_reqs > 0' failed
+
+2015-01-16 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
+
+ session: Improved docs for spice_session_connect()
+ Make it clear that users of this function must provide additional
+ sockets for individual channels.
+
+2015-01-08 Benjamin Gilbert <bgilbert@cs.cmu.edu>
+
+ inputs: Correct documentation of scancode arguments
+ AT scancodes" implies AT set 2, but the SPICE protocol expects
+ AT set 1. spice-gtk additionally expects a mangled version of
+ set 1 scancodes, which are then unmangled by spice_make_scancode()
+
+2015-01-06 Fabiano Fidêncio <fidencio@redhat.com>
+
+ README: update gstreamer info
+
+ nsis: drop gst-0.10 in favour of gst-1.0
+ Based on Victor Toso's patch for virt-viewer:
+ https://git.fedorahosted.org/cgit/virt-viewer.git/commit/?id=3bbf1ded1cb01429d600b11035d5fb0d60bfe20b
+
+ audio: drop gst-0.10 in favour of gst-1.0
+ As gstreamer-1,0 support was introduced by commit d4d60c97 and
+ it works pretty much as gstreamer-0,10 used to work (tests were
+ made both on Linux and Windows clients), let's drop the old
+ gstreamer-0.10 support in favour of gstreamer-1.0.
+
+2014-12-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ usbredir: prevent crash when calling without host
+ Quite annoyingly, usbredir doesn't have public functions arguments
+ preconditions, and will weirdly run the flush callback during
+ initialization.
+
+ With 201a8c2 change, the channel state is kept as it is when calling
+ reset. This will result in the following crash that was avoided before
+ thanks to a precondition on the channel to be ready. Adding a further
+ precondition check on priv->host != NULL solves the following crash
+ during reset():
+
+ Program received signal SIGSEGV, Segmentation fault.
+ usbredirhost_write_guest_data (host=0x0) at usbredirhost.c:868
+ 868 return
+ usbredirparser_do_write(host->parser);
+ (gdb) bt
+ #0 0x00007fffb2ed24d0 in usbredirhost_write_guest_data (host=0x0) at
+ #usbredirhost.c:868
+ #1 0x00007fffc81d463b in
+ #usbredir_write_flush_callback (user_data=0x2d95250) at
+ #channel-usbredir.c:469
+ #2 0x00007fffb2ed23f9 in usbredirhost_open_full (usb_ctx=0x2baba70,
+ #usb_dev_handle=0x0, log_func=<optimized out>,
+ #read_guest_data_func=0x7fffc81d482c <usbredir_read_callback>,
+ #write_guest_data_func=0x7fffc81d4952 <usbredir_write_callback>,
+ #flush_writes_func=0x7fffc81d45c3 <usbredir_write_flush_callback>,
+ #alloc_lock_func=0x7fffc81d49f1 <usbredir_alloc_lock>,
+ #lock_func=0x7fffc81d4a41 <usbredir_lock_lock>,
+ #unlock_func=0x7fffc81d4a86 <usbredir_unlock_lock>,
+ #free_lock_func=0x7fffc81d4acb <usbredir_free_lock>,
+ #func_priv=0x2d95250, version=0x7fffc8283dcf "spice-gtk
+ #0.27.7-89db-dirty", verbose=4, flags=1) at usbredirhost.c:748
+ #3 0x00007fffc81d3b22 in
+ #spice_usbredir_channel_set_context (channel=0x2d95250
+ #[SpiceUsbredirChannel], context=0x2baba70) at channel-usbredir.c:212
+ #4 0x00007fffc81d37a9 in spice_usbredir_channel_reset (c=0x2d95250
+ #[SpiceUsbredirChannel], migrating=0)
+ at channel-usbredir.c:125
+ #5 0x00007fffc81b7f8d in spice_channel_reset (channel=0x2d95250
+ [SpiceUsbredirChannel], migrating=0)
+ at spice-channel.c:2688
+ #6 0x00007fffc81b8057 in channel_disconnect (channel=0x2d95250
+ [SpiceUsbredirChannel]) at spice-channel.c:2706
+ #7 0x00007fffc81b7559 in
+ spice_channel_coroutine (data=0x2d95250) at spice-channel.c:2490
+
+2014-12-16 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ channel: clear channel error after auth error
+ When entered authentication details are wrong, spice-gtk will reset
+ channel error, which will result in the following warning:
+
+ (remote-viewer:20753): GLib-WARNING **: GError set over the top of a
+ previous GError or uninitialized memory.
+ This indicates a bug in someone's code. You must ensure an error is NULL
+ before it's set.
+
+ Clear channel error after reporting authentication error.
+
+ channel: throw auth error when coroutine ends
+ It is common that clients attempt to reconnect during the
+ SPICE_CHANNEL_ERROR_AUTH callback. However, the channel must exit
+ the coroutine first before reconnection can happen.
+
+ channel: introduce SPICE_CHANNEL_STATE_RECONNECTING
+ Add a new state that permits reconnection, because it's < CONNECTING.
+ It also simplifies some code by removing unneeded variables in
+ spice_channel_coroutine(): the channel.tls and session.protocol version
+ properties are already modified during initial connection steps.
+
+ channel: do not enter channel iterate on early error
+ There is no need to enter channel_iterate() if we found an early
+ connection steps error.
+
+ channel: factorize failed authentication
+ There are a few things that should be common to all wrong authentication
+ cases. Let's put them all in the same function.
+
+ session: keep main channel on reconnect
+ For legacy reasons, spice-gtk should keep at least one channel in the
+ session when reconnecting (clients may decide that the session is
+ disconnected when all channels are gone). The most obvious is to
+ keep and reuse the main channel.
+
+2014-12-11 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ Prepare 0.27 release
+
+2014-12-11 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ docs: improvements for 0.27 release
+
+2014-12-06 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: update git.mk
+
+2014-12-03 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ Fix build for glib < 2.32
+ G_SOURCE_REMOVE was introduced in 2.32
+
+2014-12-02 Javier Celaya <javier.celaya@flexvm.es>
+
+ Add LZ4 compression algorithm support.
+ - Use PKG_CHECK_MODULES to find liblz4.
+ - Set LZ4 display channel capability.
+
+2014-12-01 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ usb: keep USB context alive as long as channels exist
+ It was assumed the session would remain alive as long as channel
+ existed, so USB context would be valid too. Now that channels
+ are removed from session, USB context may be destroyed before
+ channels. This produces invalid read/write on USB context.
+ Make sure the context is alive as long as USB channels are by
+ adding a reference on USB manager.
+
+ ==6939== Invalid write of size 4
+ ==6939== at 0x394B604482: libusb_set_debug (core.c:1850)
+ ==6939== by 0x3953A063D5: usbredirhost_open_full (usbredirhost.c:741)
+ ==6939== by 0x4EC7E2F:
+ spice_usbredir_channel_set_context (channel-usbredir.c:212)
+ ==6939== by 0x4EC7AB6:
+ spice_usbredir_channel_reset (channel-usbredir.c:125)
+ ==6939== by 0x4EACCDC: spice_channel_reset (spice-channel.c:2621)
+ ==6939== by 0x4EACDB4: channel_disconnect (spice-channel.c:2640)
+ ==6939== by 0x4EAC28F: spice_channel_coroutine (spice-channel.c:2423)
+ ==6939== by 0x4EE8B1C: coroutine_trampoline (coroutine_ucontext.c:63)
+ ==6939== by 0x4EE87D6: continuation_trampoline (continuation.c:55)
+ ==6939== by 0x3928247FEF: ??? (in /usr/lib64/libc-2.20.so)
+ ==6939== by 0x51E36FF: ??? (in
+ /usr/local/stow/spice-gtk/lib/libspice-client-glib-2.0.so.8.5.0)
+ ==6939== by 0xCF0C18F: ???
+ ==6939== Address 0xff15f90 is 0 bytes inside a block of size 536 free'd
+ ==6939== at 0x4A07CE9: free (in
+ /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
+ ==6939== by 0x394B606466: libusb_exit (core.c:2041)
+ ==6939== by 0x4ECC590: spice_usb_device_manager_finalize (usb-device-manager.c:371)
+
+ usb: return early if channel is not usb
+ Return early if channel is not USB, replace:
+
+ if (SPICE_IS_USBREDIR_CHANNEL(channel)) {
+ /* code */
+ }
+
+ with
+
+ if (!SPICE_IS_USBREDIR_CHANNEL(channel))
+ return;
+
+ session: disconnect in idle
+ This is a workaround for existing clients such as virt-viewer that do
+ not hold a reference to their sessions when calling
+ spice_session_disconnect() and crash now that channels are removed from
+ session during the call. They expect disconnection events to be deferred
+ instead, let's defer actual disconnection to idle time for public
+ disconnect API for compatibility reasons (it is still recommended to fix
+ client code, for eventual future iterations)
+
+ session: keep a reference on disconnect
+ It is idiomatic for client code to clean up its reference on channel
+ disconnection. Keeping a reference during disconnect helps solving
+ potential crashes if the session is unref'ed during callbacks.
+
+ session: remove sticky disconnecting flag
+ This used to help prevent double-unref when channel were considered part
+ of the session as long as they lived. Now it shouldn't be required
+ anymore
+
+ channel: deprecate spice_channel_destroy()
+ This function is somewhat useless, and dangerous since it is calling
+ g_object_unref() behind your back (although this is mentioned in the
+ doc, I consider this a bad practice).
+
+ display: don't reschedule stream if disconnected from session
+ Avoid the following critical when a channel is disconnected with a
+ pending stream (the streams are cleared on channel reset, after
+ coroutine exit)
+
+ (process:17188): GSpice-CRITICAL **: spice_session_get_mm_time: assertion 'session != NULL' failed
+
+ #0 0x00007ffff71c24e5 in spice_session_get_mm_time (session=0x0) at spice-session.c:1999
+ #1 0x00007ffff71d438c in display_stream_schedule (st=0xa33040) at channel-display.c:1014
+ #2 0x00007ffff71d4a09 in display_stream_render (st=0xa33040,
+ st@entry=<error reading variable: value has been optimized out>) at channel-display.c:1165
+ #3 0x0000003e1944a553 in g_timeout_dispatch (source=0xad64e0, callback=<optimized out>, user_data=<optimized out>) at gmain.c:4520
+ #4 0x0000003e19449aeb in g_main_context_dispatch (context=0x6a32b0) at gmain.c:3111
+ #5 0x0000003e19449aeb in g_main_context_dispatch (context=context@entry=0x6a32b0) at gmain.c:3710
+ #6 0x0000003e19449e88 in g_main_context_iterate (context=0x6a32b0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3781
+ #7 0x0000003e1944a1b2 in g_main_loop_run (loop=0x97e200) at gmain.c:3975
+ #8 0x0000003e1c9ebb35 in gtk_main () at gtkmain.c:1207
+ #9 0x0000000000430185 in main (argc=1, argv=0x7fffffffdcb8) at virt-viewer-main.c:119
+
+ session: remove channels on disconnect
+ A channel is considered to be part of a session as long as it is
+ alive. However, this model is problematic, since library user may hold
+ channel references, and thus the channel will remain in the
+ session. Calling spice_session_disconnect() several time will end up
+ calling spice_channel_destroy(), releasing references that aren't owned
+ by the session. This usually causes crashes, in particular with language
+ bindings that do not deal well with a library model where objects can't
+ be referenced at will.
+
+ session: move SpiceSessionPrivate out of headers
+ Make sure none of the SpiceSessionPrivate fields are accessed directly anymore
+
+ gtk: do not require glib session private fields
+ Use GObject object association for session helpers.
+
+ GtkSession and DesktopIntegration are in the gtk library SpiceSession is
+ in glib one. So far we had the SessionPriv structure shared between the
+ two libraries, so they could fit their pointers there. But this is no
+ longer possible when moving the private structure in .c. We could add
+ more accessors, but they would need to be in public API, and this isn't
+ supposed to be accessed by API users.
+
+ usb: move device manager initialization to session
+ Use session accessors to initialize the device manager.
+ Add missing session parameter check (public API).
+
+ webdav: move initialization to session
+ Use session accessors to initialize the webdav server
+
+ Rename display_channels_count/n_display_channels
+
+ session: add and use internal accessors
+ Avoid dereferencing session private data directly, and use accessors
+ instead.
+
+ session: set session for migration when connecting
+
+ session: rename migration_copy/for_migration
+
+ smartcard: use spice_session_is_for_migration()
+
+ smartcard: do not initialize manager for migration session
+ The migration session is temporary and shouldn't interact with system.
+
+ Add spice_session_is_for_migration()
+
+ session: protect internal functions against invalid args
+ Make sure calling an internal session function returns with an error
+ when called with a NULL pointer. This will help channel code when
+ it is removed from session before being destructed.
+
+ audio: move spice_audio_get() to session
+
+ audio: add accessor to check if audio is enabled
+
+2014-12-01 Victor Toso <victortoso@redhat.com>
+
+ audio: Avoid bad pipelines from gst_parse_launch
+ gst_parse_launch may return not NULL even when error is set.
+ This can lead to data loss when playing or recording audio.
+
+ audio: new-sample callback must return GST_FLOW_OK
+
+2014-12-01 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ build-sys: simplify autogen.sh
+
+ build-sys: fix out-of-tree autofoo
+
+2014-11-30 Pavel Grunt <pgrunt@redhat.com>
+
+ Release keyboard grab using keyboard shortcut
+ This commit adds the ability to release the keyboard grab when
+ the release keys (ctrl+alt) are pressed and released. It allows
+ to use keyboard shortcuts (eg alt+tab, alt+f4) on the client.
+
+ The keyboard is grabbed again when the release keys are pressed
+ and released or when the mouse moves.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=85331
+
+2014-11-27 Fabiano Fidêncio <fidencio@redhat.com>
+
+ spice-widget: check whether the widget is realized in focus_in_event()
+ Returning early on focus_in_event(), when widget is not realized, avoids
+ segfault when running on Windows using GTK3.
+
+ Program received signal SIGSEGV, Segmentation fault.
+ _gdk_windows_has_impl <window=window@entry=0x0> at gdkwindow.c:584
+ <gdb> bt
+ #0 _gdk_window_has_impl (window=window@entry=0x0) at gdkwindow.c:584
+ #1 0x70f02821 in gdk_win32_window_get_handle (window=0x0) at
+ gdkwindow-win32.c:3459
+ #2 0x00c759ef in update_display (display=0x1b18440) at
+ spice-widget.c:1297
+ #3 0x00c77280 in focus_in_event (widget=0x1b18440, focus=0x1b02b68) at
+ spice-widget.c:1462
+ #4 0x665727f5 in ?? () from C:\Program Files\VirtViewer
+ (GTK3)\bin\libgtk-3-0.dll
+ #5 0x00000000 in ?? ()
+
+2014-11-24 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ migration: delay switch host reconnect
+ The following critical happens on switch-host:
+
+ (remote-viewer:4617): GSpice-CRITICAL **: channel_connect: assertion
+ 'c->sock == NULL' failed
+
+ The critical happens since the main channel reset code calls
+ set_agent_connected(), which will yield to main loop, so reconnection
+ can't happen after calling spice_channel_disconnect(), and must wait
+ until the channel reset completes.
+
+2014-11-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ migration: don't check socket error
+ During migration, the original socket is closed before the coroutine
+ finishes, so it's not guaranteed that c->sock will still be set when the
+ channel is in an error state in spice_channel_iterate().
+
+ coroutine: reference object when signaling
+ Before the signal is actually emitted, the channel may be
+ released. Let's keep a reference to the object during
+ the function time, to prevent the object from being destroyed before
+ calling g_signal_emit() or g_object_notify() in main context.
+
+ migration: use spice_session_abort_migration() on error
+ Use a more complete method for the job
+
+ migration: remove unnecessary reference
+
+ migration: create the migration session earlier
+ The migration session creation may fail. Instead of delaying the session
+ creation to the main_connect() callback, do it directly from the message
+ handler context, to report failure early to server.
+
+ migration: improve debug log
+
+ migration: remove migration cleanup from dispose
+ The spice_session_disconnect() method now calls
+ spice_session_abort_migration(), so it is not necessary to do migration
+ cleanups in dispose anymore
+
+ migration: set connecting state before fd request
+ During migration, the main channel coroutine initiating the process is
+ waiting for connection completion of all
+ channels. migrate_channel_event_cb() yields back to the main channel
+ coroutine once all channels have completed connection, or it will abort
+ migration for unexpected channel events, such as SPICE_CHANNEL_CLOSED
+
+ If the migration is cancelled before connection completes, but the
+ channels state are still in the SPICE_CHANNEL_STATE_UNCONNECTED state,
+ no events will be emitted in channel_disconnect(), and the source
+ session main channel will remain frozen waiting for migration completion
+ or failure.
+
+ Currently, for client-fd channels, the channel state remains UNCONNECTED
+ until the fd is provided. But if cancellation occurs, no channel events
+ are emitted and the source session is stuck.
+
+ Before requesting the fd, set the channel state to connecting, so it
+ will emit an error if disconnect happens, and it will finish cancelling
+ the migration in source session main channel.
+
+ migration: fail with client provided fd
+ Currently the fd request is done on the migration session, which is not
+ connected with the client session, so the client has no way to provide
+ fd for the migration. And the original and migration session ends up
+ stuck. Failing early seems the best for now.
+
+ migration: set session migration during connect
+ Track the migration session earlier, so that disconnecting before
+ migration finished will abort and release it.
+
+ migration: add "connecting" state
+ Add a new migration state to track early migration step, when migration
+ session is connecting to destination
+
+ migration: abort migrate on disconnect
+ If the session has an ongoing migration, but it is disconnected,
+ abort it.
+
+ migration: add a few more pre-conditions in migration code
+ Those preconditions help to figure out several issues related to
+ migration.
+
+ usb: stop processing usb events on error
+ If libusb returned an error in the event loop, stop further event
+ handling. This avoid spinning in an error loop in error cases.
+
+ audio: use weak references to channel
+ The audio channels are currently referenced and released on channel
+ close events. However, this event may not happen if the channel never
+ was connected. Keeping channels alive also prevent session from
+ finishing.
+
+ By not holding the ref, the channel can go to dispose
+ when it is no longer needed, and the session can be disposed too.
+
+ Add missing finalize chaining
+ Finalize should chain up to the finalize method of the parent class.
+
+ Trivial fix.
+
+ Remove obsolete TODO item
+ Tunnel are long obsoleted (did they ever work)
+ Remove it from TODO list.
+
+ Pushed unreviewed as trivial
+
+2014-11-19 Fabiano Fidêncio <fidencio@redhat.com>
+
+ usb-device: Expose libusb device
+ As we only can filter USB devices by their Classes and sometimes it is
+ not enough (eg: I do not want to have Keyboard and Mouse, but I want to
+ have Joysticks, being all of them part of HID Class), let's expose the
+ libusb device associated to the SpiceUsbDevice, so the applications can
+ have access to whatever information they need, directly from the libusb
+ device, to refine their filters.
+
+2014-11-19 Christophe Fergeau <cfergeau@redhat.com>
+
+ Really fix SndCodec leaks in handle_{playback,record}_start
+ The leak fix from commit 6729c341120f was actually not doing anything at
+ all as it was setting c->codec to NULL before trying to free it. It was
+ also not fixing the exact same leak in the record channel.
+ This commit addresses these 2 issues.
+
+ Recheck clipboard size after modifying its data
+ SpiceGtkSession::clipboard_received_cb() starts by checking if the
+ clipboard is empty, or if the length of its data exceeds
+ 'max-clipboard-size'.
+
+ Later in that function, the data is modified, and can be shortened
+ (removal of trailing '\0' or of '\r' for Windows -> linux copy and
+ paste), or enlarged (addition of '\r' for linux -> Windows c&p).
+
+ This commit adds another check that the clipboard length is still valid
+ (non-0, and not bigger than 'max-clipboard-size') after making these
+ transformations.
+
+ Fix empty clipboard check
+ SpiceGtkSession::clipboard_received_cb starts by checking if the
+ length of the X selection data is not 0. However, right after this check,
+ if gtk_selection_data_get_length() returned -1, it decides it got an
+ empty clipboard, sets the selection length to 0, and does not return
+ early.
+ This commit reworks the len == 0 / len == -1 checks to make sure we
+ always return early when we get no data from the clipboard.
+
+2014-11-04 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Draw server-side pointer when the session has the grab
+ If there are several SpiceDisplay widgets, only one will have the grab,
+ but the pointer may need to be drawn on another of the displays. We
+ thus need to track the grab status on SpiceSession, not just
+ per-display.
+
+ This solves the following bug:
+ https://bugs.freedesktop.org/show_bug.cgi?id=38024
+
+ gtk-session: add pointer-grabbed property
+ Returns TRUE if the pointer is currently grabbed by this session.
+
+ Add missing G_GNUC_INTERNAL
+ Trivial fix
+
+2014-10-31 Christophe Fergeau <cfergeau@redhat.com>
+
+ Drop glib < 2.28 support
+ With el6 now shipping glib 2.28, there is no very good reason to keep
+ support for older glib versions alive, especially as it will barely be
+ tested.
+
+2014-10-31 Victor Toso <vtosodec@redhat.com>
+
+ Add GStreamer 1.0 audio support
+ Based on Christophe Fergeau's patch.
+ To enable audio with GStreamer 1.0: --with-audio=gstreamer1
+
+ There is only a few changes between those versions, worth mentioning:
+ - audio capabilities "audio/x-raw,format=..." instead of
+ "audio/x-raw-int,..."
+ - appsink signal for new data changed from "new-buffer" to "new-sample"
+
+2014-10-30 Christophe Fergeau <cfergeau@redhat.com>
+
+ Always use #include "config.h"
+ gnulib 'make syntax-check' prohibits use of #ifdef HAVE_CONFIG_H so this
+ commit removes it from where it's used. It also makes sure we always use
+ the same syntax for including config.h (#include "config.h" VS #include
+ <config.h>) as a consistent way of doing that is expected.
+
+ Remove spice-mime.xml/spicy.desktop
+ They were never translated from .in files to actual files, and now it's
+ clear we don't want to promote spicy as a first-class desktop
+ application.
+
+ Fix "can not" typo in comment
+
+ Remove redundant use of const
+ const guint16 const * has one extra 'const' which is removed by that
+ commit
+
+ Remove trailing whitespace
+
+ Remove blank lines at end of files
+
+ Add missing (C) to Red Hat copyright line
+ gnulib's make syntax-check comes with a rule enforcing that Red Hat
+ copyright lines contain both "(C)" and "Copyright".
+
+ Add quoting around AC_DEFINE* first argument
+
+ build-sys: Don't use test -a/-o
+ They are not portable, it's recommended to use test && test or test ||
+ test instead
+
+2014-10-30 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ mailmap: add Dietmar Maurer
+
+ build-sys: add some missing MAINTAINERCLEANFILES
+
+ build-sys: generate gitignore in tests dir
+
+ build-sys: change default libtool options
+ - disable-static: it's quite uncommon to use static build of gtk libraries
+ - win32-dll: the shared libs build cleanly for win32 already
+
+2014-10-29 Christophe Fergeau <cfergeau@redhat.com>
+
+ Regenerate symbol files with make update-symbol-files
+ Some symbols were manually added to these files not in the right place
+ (non-alphabetical order). This causes spurious diffs when trying to
+ compare these files with the ones make update-symbol-files would
+ generate.
+ This commit syncs these file with the ones which are autogenerated to
+ spot more easily differences between the file in git and the
+ autogenerated one.
+
+ Tell ctags to ignore G_GNUC_CONST in declarations
+ Without that, it will fail to parse:
+ GType spice_uri_get_type(void) G_GNUC_CONST;
+
+ Remove spice_gtk_session_sync_keyboard_modifiers from public headers
+ It's not meant to be exported as it's not listed in spice-gtk symbol map file.
+
+ Add spice_session_get_proxy_uri to spice-glib-sym-file
+ It was only added to map-file.
+
+ Update spice-common submodule
+ This picks up some warning fixes.
+
+ Update NEWS
+
+ Don't strip \0 from non-text clipboard data
+ Commit a8f2e2d added recomputation of the length of clipboard data to
+ strip the trailing \0 in order to avoid a Windows gtk+ bug. However it's
+ doing it too for non-text data, which causes issues when copying images
+ as they are very likely to contain \0 within their data. They will thus
+ be truncated.
+
+ This fixes https://bugzilla.redhat.com/show_bug.cgi?id=1154719
+
+ Reindent block of code in clipboard_received_cb
+ This is in preparation for fixing a regression in image copy&paste. This
+ commit only introduces a new (unused) block and reindent the
+ corresponding code, it can easily be reviewed with git show -w
+
+2014-10-29 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: make vapigen silent
+
+ build-sys: clean-up generated vapi files
+
+ build-sys: remove unnecessary BUILT_SOURCES rule
+
+ build-sys: add extra dependencies on symbols files
+ Whenever the symbols files are modified, rebuild the library.
+
+ build-sys: s/GLIB_VERSION/GLIB_SYMBOLS
+
+2014-10-27 Daniel P. Berrange <berrange@redhat.com>
+
+ Fix macro for checking spice version numbers
+ As it is for now, the micro number is never checked.
+
+2014-10-27 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: hide cursor when ungrabbed
+ Let's avoid confusion of multiple pointers visible on the client
+ desktop: hide the guest pointer if the spice client doesn't have the
+ grab, display it again when the grab is taken back.
+
+ gtk: keep cursor in the same place on ungrab
+ On ungrab, the transition from remote (server-side) cursor to host
+ cursor makes it jump somewhere else rather than staying at the same
+ place. Restore cursor position on ungrab to match with guest position.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=85117
+
+2014-10-23 Christophe Fergeau <cfergeau@redhat.com>
+
+ Fix SndCodec leak in playback_handle_start()
+ An audio SpiceChannel can get several times the 'start' message during
+ its lifetime. If received multiple times (for example when rebooting a
+ VM), this would lead to a SndCodec leak as reported by valgrind:
+
+ ==7749== 27,036 (48 direct, 26,988 indirect) bytes in 1 blocks are definitely lost in loss record 11,418 of 11,440
+ ==7749== at 0x4A08946: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
+ ==7749== by 0x5772A9A: spice_malloc0 (mem.c:109)
+ ==7749== by 0x5772D42: spice_malloc0_n (mem.c:173)
+ ==7749== by 0x57FB3E2: snd_codec_create (snd_codec.c:267)
+ ==7749== by 0x573774C: playback_handle_start (channel-playback.c:380)
+ ==7749== by 0x5721E44: spice_channel_handle_msg (spice-channel.c:2859)
+ ==7749== by 0x571ECB3: spice_channel_recv_msg (spice-channel.c:1877)
+ ==7749== by 0x571F402: spice_channel_iterate_read (spice-channel.c:2114)
+ ==7749== by 0x571F614: spice_channel_iterate (spice-channel.c:2152)
+ ==7749== by 0x5720411: spice_channel_coroutine (spice-channel.c:2429)
+ ==7749== by 0x575CD3A: coroutine_trampoline (coroutine_ucontext.c:63)
+ ==7749== by 0x575C9F4: continuation_trampoline (continuation.c:55)
+ ==7749== by 0x3898E47FEF: ??? (in /usr/lib64/libc-2.20.so)
+ ==7749== by 0xAED547666C92C2FF: ???
+ ==7749== by 0xFFEFFF92F: ???
+
+2014-10-10 Cole Robinson <crobinso@redhat.com>
+
+ m4: Update manywarnings from gnulib
+ Fixes these noisy errors on Fedora 21:
+
+ gcc: warning: switch '-Wmudflap' is no longer supported
+
+2014-10-10 Fabiano Fidêncio <fidencio@redhat.com>
+
+ Add support to handle username when connecting with SASL
+ Based on a patch from Dietmar Maurer <dietmar@proxmox.com>
+ http://lists.freedesktop.org/archives/spice-devel/2013-October/015138.html
+
+ Add errors related to the SASL auth
+ SPICE_CLIENT_ERROR_AUTH_* will be used to set more detailed errors
+ with respect to the main channel event SPICE_CHANNEL_ERROR_AUTH.
+
+ Add missing doc for SPICE_CLIENT_USB* errors
+
+2014-10-10 Dietmar Maurer <dietmar@proxmox.com>
+
+ Add "username" property to SpiceSession
+
+2014-09-18 Christophe Fergeau <cfergeau@redhat.com>
+
+ Don't report IO error on clean guest shutdown
+ Since commit 9cf9ca434, spice_channel_iterate() will report a
+ SPICE_CHANNEL_ERROR_IO error to library users when
+ SpiceChannel::has_error is set. In particular, when the server side
+ closes its SPICE sockets because the VM is being shut down, an IO error
+ will get reported. Prior to this change, a channel-closed event was
+ reported on graceful VM shutdowns as there was
+ a g_socket_condition_check() guarding the emission of the IO error
+ signal.
+
+ This commit readds the g_socket_condition_check() test, but only when
+ SpiceChannel::has_error is set.
+
+ This fixes https://bugs.freedesktop.org/show_bug.cgi?id=83692
+
+2014-09-18 Pavel Grunt <pavel.grunt@gmail.com>
+
+ Fix -Wsign-compare
+
+2014-09-18 Fabiano Fidêncio <fidencio@redhat.com>
+
+ channel-main: allow transferring multiple files at once
+ Allow to drag and drop, from host to guest, more than one file at the
+ same time.
+
+2014-09-05 Christophe Fergeau <cfergeau@redhat.com>
+
+ win-usb: Initialize GError before using it
+ GError variables must be set to NULL before passing them to a function
+ which might set them.
+ This fixes the runtime warning reported in rhbz#1138195:
+
+ (remote-viewer.exe:3896): GLib-WARNING **: GError set over the top of a
+ previous GError or uninitialized memory.
+ This indicates a bug in someone's code. You must ensure an error is NULL
+ before it's set.
+ The overwriting error message was: handle_dev_change: Error getting
+ device list from libusb: Other error [-99]
+
+2014-08-29 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ xfer: send data message of size 0 for 0-size file
+ Make sure we send a xfer data message for 0-size files.
+ This avoid leaking file descriptiors in guest agent when
+ copying such files.
+
+ Reported-by: Cody Chan <int64ago@gmail.com>
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=1135099
+
+2014-08-29 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Wait to send monitor config until agent caps are received
+ When the first display is disabled and the vdagent is restarted in the guest,
+ it sometimes becomes enabled. This appears to be caused by a race condition
+ when an agent becomes connected. When the agent becomes connected, virt-viewer
+ triggers a display update (spice_main_send_monitor_config()). This display
+ update happens in a timeout handler, but the timeout interval is set to 0 (so
+ it behaves basically like an idle handler).
+
+ The race happens because spice_main_send_monitor_config() behaves slightly
+ differently depending on the agent's capabilities. And sometimes the idle
+ handler runs before the client and server have negotiated capabilities. In this
+ case, we have to assume that the server does not support sparse monitor
+ configurations. So instead of sending down an update where display #0 is off
+ and display #1 is WxH, we send down an update that only a single display:
+ display #0 is WxH. This results in the first display becoming enabled.
+
+ To solve the issue, we wait until the agent negotiates capabilities
+ before sending the display configuration message.
+
+ Resolves: rhbz#1043782, rhbz#1032923
+
+2014-08-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ win32: fix coroutine assertion when switching to TLS port
+ Since v0.21-35-gbaa51c5, there are some new coroutine preconditions.
+
+ The winfiber implementation can reach, when the structure isn't cleared,
+ which happens when switching channel connection to TLS port and the
+ coroutine is recycled.
+
+ CRITICAL **: coroutine_yieldto: assertion '!to->exited' failed
+
+ In a near future, it would be nice to use the safer implementation
+ proposed for glib, see bgo#719362 (using a private copy)
+
+2014-08-13 Christophe Fergeau <cfergeau@redhat.com>
+
+ Use G_OS_WIN32 #define everywhere
+ Currently some parts of the windows specific code is checking for the
+ WIN32 define, and other parts are checking G_OS_WIN32. This commit uses
+ G_OS_WIN32 everywhere for consistency.
+
+2014-08-13 Cody Chan <int64ago@gmail.com>
+
+ keyboard: wrong defined macro for WIN32
+ On windows client, there's no effect for guest when
+ enabling CAPS_LOCK/NUM_LOCK/SCROLL_LOCK on
+ (because of the delay, guest may take the effect for several seconds).
+ There's a wrong defined macro, then <modifiers> is ALWAYS 0,
+ and the keyboard state of guest is synchronized with the state client
+ by spice_gtk_session_sync_keyboard_modifiers_for_channel(...).
+
+2014-08-13 Christophe Fergeau <cfergeau@redhat.com>
+
+ Fix 'loose' typo
+
+ Fix build with automake 1.14
+ When building a source file from a different directory, automake 1.14
+ is warning that the automake option 'subdir-objects' must be used:
+
+ automake: warnings are treated as errors
+ gtk/Makefile.am:218: warning: source file
+ '$(top_srcdir)/spice-common/common/sw_canvas.c' is in a subdirectory,
+ gtk/Makefile.am:218: but option 'subdir-objects' is disabled
+ automake: warning: possible forward-incompatibility.
+ automake: At least a source file is in a subdirectory, but the
+ 'subdir-objects'
+ automake: automake option hasn't been enabled. For now, the
+ corresponding output
+ automake: object file(s) will be placed in the top-level directory.
+ However,
+ automake: this behaviour will change in future Automake versions: they
+ will
+ automake: unconditionally cause object files to be placed in the same
+ subdirectory
+ automake: of the corresponding sources.
+ automake: You are advised to start using 'subdir-objects' option
+ throughout your
+ automake: project, to avoid future incompatibilities.
+ autoreconf: automake failed with exit status: 1
+
+ This causes the build to fail because we are also using the -Werror
+ automake option.
+ Updating the spice-common submodule to git master fixes part of this
+ issue as 7ea1cc5 'Fix generation of marshallers in VPATH builds' removed
+ directory references from some source files.
+
+ This commit removes the references to
+ $(top_srcdir)/spice-common/common/sw_canvas.[ch] from gtk/Makefile.am.
+ At this point, automake subdir-objects support does not seem to cope
+ very well with source files which are not in relative subdirectories,
+ see http://mytestbed.net/issues/1327
+ What is done instead is to add some local client_sw_canvas.[ch] files
+ which will include the needed files from spice-common with the
+ appropriate #define set (these sw_canvas.[ch] files are meant to be used
+ as templates).
+
+ This fixes https://bugs.freedesktop.org/show_bug.cgi?id=67304
+
+ channel-display: Remove #ifdef SW_CANVAS_CACHE
+ It's unconditionnally defined at build time in the global CPP flags, so
+ the #ifdef SW_CANVAS_CACHE are always enabled and can be removed.
+
+ Ensure '\0' is not part of text clipboard data
+ On Windows, with some versions of gtk+, GtkSelectionData::length
+ will include the final '\0'.
+ When a string with this trailing '\0' is pasted in some linux
+ applications, it will be pasted as <NIL> or as an invisible character,
+ which is unwanted.
+
+ This commit ensures the length we send to the agent does not
+ include any trailing '\0'.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=1090122
+
+2014-07-23 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Update spice-common
+
+2014-07-23 Fabiano Fidêncio <fidencio@redhat.com>
+
+ Don't use _GET_PRIVATE all the time
+ Let's make use of the priv members in the structs, which are much much
+ faster. Also, to keep the type-safety, the SPICE_IS_* macros were added
+ in the public methods affected by this patch.
+
+ Patch based on an old patch from Alexander Larsson (alexl@redhat.com).
+
+ Prefer using g_malloc0()/g_free()
+ As we already depend on GLib, let's use g_{malloc,new}0() instead of the
+ standard malloc() or the spice_{malloc,new}*() and g_free() instead of
+ the standard free() when possible.
+ Memory allocated by other libraries using malloc() should still be freed
+ by free().
+ As a side effect of the changes, we are muting a few warnings caught by
+ coverity.
+
+ Fix "REVERSE_INULL" caught by coverity
+
+ g_type_init() is deprecated in GLib 2.36
+
+2014-07-07 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: prefix proxy lookup errors
+ Proxy errors are already reported with G_IO_ERROR_PROXY messages,
+ however proxy name lookup error can be more detailed.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=1115986
+
+2014-06-17 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ proxy: use http proxy by default if no scheme given
+ SPICE_PROXY used to accept URI without scheme, falling back on
+ http/3128. This is a regression introduced with 5dcab09ac
+
+2014-06-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Remove coroutine trampolines
+ Use va_list instead of an ugly trampoline hack
+
+ usbredir: don't use emit_main_context() for non-signal code
+ The following patch deprecates the signal helper code
+
+2014-05-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ README: add vala-tools build-dep
+
+2014-05-22 Tiziano Müller <tiziano.mueller@stepping-stone.ch>
+
+ Add missing GIO_LIBS to libspice-client-glibs
+ If spice-gtk is built without PHODAV, libgio is missing from the list of
+ libraries to link against, causing undefined symbols for all gio functions.
+
+2014-05-21 Tiziano Müller <tiziano.mueller@stepping-stone.ch>
+
+ Do not depend on libsoup directly
+ The libsoup-dependency is not directly used but comes in as a dependency
+ of phodav and phodav has libsoup correctly recorded in its pkg-config
+ file.
+
+ Introduce --enable/disable-webdav option
+ This makes the phodav dependency configureable.
+ And name it after the corresponding channel.
+
+2014-05-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Revert "clipboard: prevent reentering main loop if main channel is busy"
+ This change broke primary clipboard copying from remote to client, on win32.
+
+ There is a pending ::clipboard-grab emission, so the channel is not
+ idle, and it will handle emission and resume in the inner loop without
+ issue. We should really handle this situation with care though, and the
+ best would be to teach gtk+ to do async clipboard request.
+
+ This reverts commit e3efa8cec51045d87a14a7e4f921c24ad5caffb1.
+
+2014-05-15 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ clipboard: check that clipboard request does not belong to remote
+ Check clipboard owner, to avoid cyclic dependency of clipboard requests.
+
+ clipboard: prevent reentering main loop if main channel is busy
+ The main channel must be idle to avoid entering the nested loop,
+ or it will never reach the condition to leave it.
+
+ This should not happen. It can happen currently when the remote sends a
+ clipboard request while the clipboard is grabbed by the remote. In this
+ case, while the clipboard-request signal is emitted by main channel, the
+ clipboard_get() loop is entered, but the main coroutine will not be
+ woken up to proceed with the request, the main channel will remain
+ "frozen" and it won't be possible to leave cleanly from the inner loop.
+ The application appears to be frozen, because it can't quit properly.
+
+ Related to:
+ https://bugzilla.redhat.com/show_bug.cgi?id=1083489
+
+2014-04-29 Christophe Fergeau <cfergeau@redhat.com>
+
+ Include glib-compat.h in spice-option.c
+ Commit 8c89485 added a call to g_clear_pointer().
+
+2014-04-24 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ option: check that default ca-file exists
+ Don't set default ca-file path if the file doesn't exists.
+
+2014-04-23 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ option: use more portable default ca-file path
+ If no CA path is given, a default one is set. Use g_build_filename() to
+ set a more portable and valid default path.
+
+2014-04-17 Christophe Fergeau <cfergeau@redhat.com>
+
+ Fix leak in spice_gtk_session_sync_keyboard_modifiers()
+ The list of channels returned by spice_session_get_channels()
+ must be freed after use.
+
+2014-04-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ display: signal primary-destroy when clearing all surfaces
+ When destroying the primary surface, we need to signal it, since
+ listeners might be referencing the data pointer. Currently, this only
+ happens during channel finalize().
+
+ This could help with rhbz#1082555.
+
+ gtk-session: always sync modifiers for client events
+ The channel state is not synchronous.
+
+ It may happen that we want to set and unset quickly a modifier, but the
+ guest modifier state hasn't been updated yet, and will still be seen as
+ unset, preventing the last unset change.
+
+ gtk-session: s/g_debug/CHANNEL_DEBUG
+
+2014-04-15 Christophe Fergeau <cfergeau@redhat.com>
+
+ Include gtk-compat.h in spice-gtk-session.c
+ GDK_IS_X11_DISPLAY is not available on gtk+ 2.x, but it already has a
+ fallback definition in gtk-compat.h
+
+ Gather gtk+ compatibility code in a single file
+ There are gtk+ version checks in several source files to add
+ compatibility implementations of gtk3 functions not available
+ in gtk2. This commit gathers all of them in a gtk-compat.h header,
+ similar to what is done for glib-compat.h
+
+ Add compat implementation of g_queue_free_full()
+ This was introduced in glib 2.32 and the webdav channel uses it.
+
+2014-04-08 Christophe Fergeau <cfergeau@redhat.com>
+
+ Use correct printf format modifier for gssize
+ This fixes this warning/error:
+
+ channel-webdav.c: In function 'demux_to_client':
+ channel-webdav.c:318:5: error: format '%ld' expects argument of type 'long
+ int', but argument 5 has type 'gssize' [-Werror=format=]
+ CHANNEL_DEBUG(self, "pushing %ld to client %p", size, client);
+
+ Add man page
+ Spice-GTK provides SPICE-specific command line options. This man page
+ describes these options as well as the format of SPICE URIs.
+
+2014-04-04 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Use GdkKeymap to listen for keyboard modifier changes
+ Connect to the GdkKeymap::state-changed signal to detect when the client
+ keyboard modifiers have changed. This keeps the client and the guest in sync
+ even when the SpiceDisplay widget isn't focused. New values are only sent down
+ to the guest if the new value is different than the current value.
+
+ Ensure keyboard modifiers are synchronized properly
+ In certain circumstances, the keyboard modifiers get out-of-sync between the
+ guest and the client. This is easy to reproduce with the following steps:
+ - launch virt-viewer with a guest that is not running
+ - start the guest
+ - while guest is booting, enable CAPS LOCK on the client
+ - after guest finishes booting, it will set its modifiers to a default value
+ (e.g. numlock on, capslock off)
+ - now capslock is OFF in the guest, but ON in the client
+ - toggle caps lock
+ - now capslock is ON in the guest, but OFF in the client
+
+ This moves the responsibility for synchronizing client and guest modifiers into
+ SpiceGtkSession. It can't be handled easily within the SpiceDisplay widget since
+ there can be multiple display widgets for each inputs channel.
+
+ A new function (spice_gtk_session_sync_keyboard_modifiers()) was added so that
+ synchronization can be triggered manually if desired. But it also registers a
+ signal handler for the InputsChannel::inputs-modifiers signal to detect when the
+ guest has changed its modifiers. The signal handler simply overrides the guests
+ modifiers and sets them back to the value from the client.
+
+2014-04-02 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Update NEWS for v0.25
+
+ Make phodav an optional external dependency
+ Now that upstream provides a stable/versioned API, it will be
+ easier to deal with than with submodules.
+
+ build-sys: re-organize summary to show major info first
+
+ build-sys: add missing soup subst
+
+2014-04-01 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Fix missing SPICE_GTK_MICRO_VERSION value
+ configure.ac tries to assign a default value of 0 to the micro version if it's
+ empty, but the shell variable assignemnt doesn't work because there's whitespace
+ around the '=' sign.
+
+ This results in SPICE_GTK_MICRO_VERSION being defined to (), which causes a
+ compilation failure in files that include it.
+
+2014-03-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Update NEWS for v0.24
+
+ Update phodav
+
+2014-03-25 Christophe Fergeau <cfergeau@redhat.com>
+
+ Advertise SASL cap from client
+ A client setting this capability indicates to the server that it's able
+ to handle SASL authentication, and it also indicates that if SASL is
+ to be used for authentication, then it won't expect a valid 'pub_key' field
+ in SpiceLinkReply.
+
+ The reason for making guarantees about not looking at the pub_key field is
+ that its presence and size is hardcoded in the protocol, but in some
+ hardened setups (using fips mode), generating a RSA 1024 bit key as
+ expected is forbidden and fails. With this new capability, the server
+ knows the client will be able to handle SASL if needed, and can skip
+ the generation of the key altogether. This means that on the setups
+ described above, SASL authentication has to be used.
+
+2014-03-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ webdav: use some more explicit names
+ Address Alon's review from
+ http://lists.freedesktop.org/archives/spice-devel/2014-March/016383.html
+
+2014-03-19 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Start NEWS file
+
+ session: add shared-dir property and option
+ Allow to specify the shared directory from the command line, or at
+ runtime via properties. (still default to xdg public share, if none
+ specified)
+
+ Add webdav channel
+ See spice-common for protocol details. phodav, a webdav server library,
+ is imported thanks to a submodule, until this project has a stable API
+ and releases.
+
+ The webdav channel is reponsible for handling port events and
+ multiplexing the request streams. Extra care has been made to avoid
+ blocking and to enable some fairness between concurrent streams, however
+ this has been particularly tricky and is likely to have some issues
+ left.
+
+ The webdav server is run in a seperate thread, using libsoup. The client
+ communication is done via a local tcp socket, but protected to only
+ accept local connection and with a pretty strong password.
+
+ The home directory is exported for the remote to browse, which seems to
+ be a sensible default atm.
+
+2014-03-18 Christophe Fergeau <cfergeau@redhat.com>
+
+ mingw64: Fix gssize printf-format warnings
+ When building with mingw64, several warnings about using the wrong format
+ specifier for gssize/gsize occur similar to:
+
+ win-usb-dev.c: In function 'g_udev_client_list_devices':
+ win-usb-dev.c:145:21: error: format '%i' expects argument of type 'int', but argument 7 has type 'gssize' [-Werror=format=]
+ name, errstr, rc);
+
+ This commit makes use of the G_GSIZE_FORMAT/G_GSSIZE_FORMAT macros provided
+ by glib to silence these warnings.
+
+ I've checked that this does not introduce new warnings on linux and mingw32
+ builds.
+
+2014-03-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix spice_display_get_pixbuf() with offset area
+ Fix screenshot of secondary displays, with an area position != (0,0).
+
+ This has never been working correctly since the surface display "area"
+ was introducted in:
+
+ commit e3bb7b1cfd162fcb8943e9d582dab43eeec6ce41
+ Author: Marc-André Lureau <marcandre.lureau@redhat.com>
+ Date: Tue Jun 12 19:24:47 2012 +0200
+
+ display: learn to restrict display to an area
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=1029761
+
+ Silence some gcc warnings
+ cc1: warnings being treated as errors
+ spice-uri.c: In function ‘spice_uri_parse’:
+ spice-uri.c:105: error: ‘saveptr’ may be used uninitialized in this
+ function [-Wuninitialized]
+ spice-uri.c:105: error: ‘saveptr2’ may be used uninitialized in this
+ function [-Wuninitialized]
+
+2014-03-13 Christophe Fergeau <cfergeau@redhat.com>
+
+ sasl: Rework memory handling in spice_channel_perform_auth_sasl()
+ While looking at the SASL code, I noticed some memory leaks in error paths.
+ This commit adds a cleanup: block to free some of the memory dynamically
+ allocated in that function, and remove the corresponding g_free() from
+ the regular code flow. This should ensure that both the regular path
+ and the error paths free the same memory.
+
+ This fixes at least this 'mechlist' leak which I got during regular SASL
+ PLAIN authentication:
+ ==3452== 6 bytes in 1 blocks are definitely lost in loss record 140 of 11,706
+ ==3452== at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.s
+ ==3452== by 0x35BAC4EE6E: g_malloc (gmem.c:104)
+ ==3452== by 0x5BF7CAA: spice_channel_perform_auth_sasl (spice-channel.c:1440)
+ ==3452== by 0x5BF9033: spice_channel_recv_link_msg (spice-channel.c:1727)
+ ==3452== by 0x5BFAECD: spice_channel_coroutine (spice-channel.c:2348)
+ ==3452== by 0x5C35D6D: coroutine_trampoline (coroutine_ucontext.c:63)
+ ==3452== by 0x5C35A1B: continuation_trampoline (continuation.c:51)
+ ==3452== by 0x31342479BF: ??? (in /usr/lib64/libc-2.18.so)
+ ==3452== by 0x75F2940591224CFF: ???
+ ==3452== by 0xE756E5F: ???
+ ==3452== by 0xE7589BF: ???
+ ==3452== by 0xFFEFFF78F: ???
+ ==3452== by 0x5BFCD92: g_io_wait_helper (gio-coroutine.c:43)
+ =
+
+ Make sure config.h is included first in all .c files
+ This is recommended by autoconf documentation
+ http://nondot.org/sabre/Mirrored/autoconf-2.12/autoconf_3.html#SEC15
+ and some #defines in config.h can change what happens in system headers,
+ so config.h has to be included first.
+
+ The only file which does not get this treatment is
+ gtk/spice-client-gtk-module.c as this breaks the build on gtk+2:
+
+ CC SpiceClientGtk_la-spice-client-gtk-module.lo
+ In file included from /usr/include/python2.7/pyconfig.h:6:0,
+ from /usr/include/python2.7/Python.h:8,
+ from /usr/include/pygtk-2.0/pygobject.h:5,
+ from spice-client-gtk-module.c:20:
+ /usr/include/python2.7/pyconfig-64.h:1182:0: error: "_POSIX_C_SOURCE" redefined [-Werror]
+ #define _POSIX_C_SOURCE 200112L
+ ^
+ In file included from /usr/include/limits.h:25:0,
+ from /usr/lib/gcc/x86_64-redhat-linux/4.8.2/include/limits.h:168,
+ from /usr/lib/gcc/x86_64-redhat-linux/4.8.2/include/syslimits.h:7,
+ from /usr/lib/gcc/x86_64-redhat-linux/4.8.2/include/limits.h:34,
+ from /usr/lib64/glib-2.0/include/glibconfig.h:11,
+ from /usr/include/glib-2.0/glib/gtypes.h:34,
+ from /usr/include/glib-2.0/glib/galloca.h:34,
+ from /usr/include/glib-2.0/glib.h:32,
+ from /usr/include/glib-2.0/gobject/gbinding.h:30,
+ from /usr/include/glib-2.0/glib-object.h:25,
+ from ./glib-compat.h:24,
+ from ../config.h:201,
+ from spice-client-gtk-module.c:18:
+ /usr/include/features.h:228:0: note: this is the location of the previous definition
+ # define _POSIX_C_SOURCE 200809L
+ ^
+ cc1: all warnings being treated as errors
+
+2014-03-10 Christophe Fergeau <cfergeau@redhat.com>
+
+ build-sys: Fix setting of SPICE_GTK_MICRO_VERSION
+ After e124a3b2e which added the SPICE_GTK_CHECK_VERSION macro, a non-fatal
+ './configure: line 15251: x24: command not found' appears in configure
+ output. This is because [ ] is not interpreted as the 'test' command by
+ autoconf, but is rather used as a way to quote configure.ac content.
+ This commit replaces the use of [] with a more typical AS_IF.
+
+2014-02-27 Christophe Fergeau <cfergeau@redhat.com>
+
+ Add missing #include "glib-compat.h"
+ wocky-http-proxy.c and vmcstream.c make use of functions that were
+ not available in glib 2.26 so we need fallback for them through
+ glib-compat.h or spice-gtk won't build with older glibs.
+
+2014-02-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ display: fix crash when releasing primary surface
+ Since 1fcaaa15f8aca362f9e6afc87fb43cfbccf6ff62, display_surface is
+ allocated using gslice. However MSG_DISPLAY_MODE handler didn't allocate
+ using GSlice. This can eventually lead to a crash when freeing, such as:
+
+ Thread no. 1 (6 frames)
+ #2 g_slice_free1 at gslice.c:1097
+ #3 iter_remove_or_steal at ghash.c:787
+ #4 clear_surfaces at /lib64/libspice-client-glib-2.0.so.8
+ #5 spice_display_channel_finalize at
+ /lib64/libspice-client-glib-2.0.so.8
+ #7 spice_channel_delayed_unref at /lib64/libspice-client-glib-2.0.so.8
+ #12 gtk_main at gtkmain.c:1158
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=1069546
+
+2014-02-24 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Add a SPICE_GTK_CHECK_VERSION macro
+
+2014-02-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ spice-common: revert last change
+
+ session: add spice_session_get_proxy_uri()
+ Learn to return the currently configured proxy, to allow
+ client to tweak parameters, such as username and password.
+
+ channel: add spice_channel_get_error()
+ Add a function to retrieve the last GError from a channel, this may be
+ useful to provide additional error details to the client.
+
+ Make SpiceURI a public API
+ Generalize a little bit SpiceProxy to allow easy URI manipulation by
+ clients.
+
+ channel: talk to giostream instead of gsocket
+
+ channel: simplify has error code
+ Get rid of a superflous g_socket_condition_check().
+
+ openssl: learn to handle a new kind of BIO based on GIOStream
+ Although reusing BIO_new_socket() once again is a hack, it seems
+ to be the easiest way... The proper solution is certainly to start
+ using GTls instead, but that will require a glib 2.28 dep bump.
+
+ Fill g_proxy_address_new() with protocol, user and password
+ This way, the call might eventually support more proxy and
+ authentication.
+
+ http-proxy: add https proxy
+ This will require glib 2.28 for GTls support, atm
+
+ spice-proxy: parse https protocol
+
+ http-proxy: specify Basic scheme
+ Or Squid will fail with:
+ WARNING: Unsupported or unconfigured/inactive proxy-auth scheme
+
+ proxy: parse user and pass from uri
+
+ proxy: add user and pass properties
+
+ proxy: split uri with : in only 2 parts
+ We want just host:port here.
+
+ compat: add strtok_r fallback
+ The following Spice proxy URI parsing code makes use of it, but it is
+ not available on Windows
+
+ Origin:
+ http://git.videolan.org/gitweb.cgi/vlc.git/?p=vlc.git;a=blob;f=compat/strtok_r.c
+
+ misc: indent wocky proxy with 2-spaces
+
+ misc: make warning more explicit
+
+ Add SpiceVMC GIOStream
+ This allows to use conveniently GIOStream APIs without caring about
+ coroutine and Spice messages details.
+
+ channel: add spice_vmc_write_async()
+ Refactor port code to create a private GIO async function that can send
+ SPICE_MSGC_SPICEVMC_DATA message over any channel.
+
+2014-02-20 Christophe Fergeau <cfergeau@redhat.com>
+
+ build-sys: Don't build tests when not building static libs
+ The tests rely on static linking in order to get access to symbols which
+ are not exported in spice-gtk shared libraries. When build of static
+ libraries is disabled with --disable-static, we should not attempt to build
+ the tests as this will result in link errors.
+
+2014-02-10 Christophe Fergeau <cfergeau@redhat.com>
+
+ Don't attempt to send 0 scancode when releasing keys
+ When releasing all keys, we send a key release for scancode in the
+ key_state array, including the very first element with scancode 0.
+ send_key() complain when the scancode is 0, so make sure we don't call it
+ for this first element.
+
+ This fixes a
+ (remote-viewer:25548): GSpice-CRITICAL **: send_key: assertion 'scancode != 0' failed
+ warning when starting remote-viewer windowed, and then switching to another
+ desktop client-side using ctrl+alt+arrow.
+
+2014-02-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release v0.23
+
+2014-02-10 Ryan Lortie <desrt@desrt.ca>
+
+ utils tests: fix sign comparison problem
+ This test compares a guint8 and a gchar with '==' which fails when comparing
+ 240 to -16, even though these are the same byte value. Add an explicit
+ 'guchar' cast to correct the problem.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=74754
+
+2014-02-07 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: don't track open_host_idle source id
+ In all cases, when the coroutine is resumed, the idle source has been
+ running and thus will be removed. Doing it a second time results in the
+ wrong source being removed or an invalid source warning.
+
+ spicy: do not flush and disconnect all kind of ports
+ Some ports may want to live a bit longer, such as following webdav.
+
+ port: send opened a port-event signal on init
+ If the port is already opened, emit a "opened" port-event on init. This
+ simplifies user code to only handle port events.
+
+ test: fix a few compiler warnings
+ util.c: In function 'test_set_bit':
+ util.c:131:13: warning: pointer targets in initialization differ in signedness [-Wpointer-sign]
+
+ Add GDBus version of dbus-glib code
+
+ Narrow dbus-glib code, to fit other implementation easily
+
+ dbus: remove priv->dbus_conn
+ It's only needed once, and it is better to group with rest of dbus-glib
+ code.
+
+ build-sys: detect GDBus
+
+ misc: sed -i -e 's/USE_DBUS/USE_DBUS_GLIB/g'
+
+2014-01-07 Christophe Fergeau <cfergeau@redhat.com>
+
+ Use local GError in spice_convert_newlines()
+ spice_convert_newlines() declares a local 'err' GError but never uses it as
+ the function directly uses the 'error' variable passed as an argument.
+ Use 'err' throughout the function instead of the 'error' argument as this
+ looks like what was intended.
+ This fixes this coverity warning:
+
+ Error: DEADCODE (CWE-561): [#def144]
+ spice-gtk-0.22.9-fb3d/spice-gtk3-0.22.9/gtk/spice-util.c:318: assignment: Assigning: "err" = "NULL".
+ spice-gtk-0.22.9-fb3d/spice-gtk3-0.22.9/gtk/spice-util.c:364: null: At condition "err", the value of "err" must be NULL.
+ spice-gtk-0.22.9-fb3d/spice-gtk3-0.22.9/gtk/spice-util.c:364: dead_error_condition: The condition "err" cannot be true.
+ spice-gtk-0.22.9-fb3d/spice-gtk3-0.22.9/gtk/spice-util.c:365: dead_error_begin: Execution cannot reach this statement "g_propagate_error(error, err);".
+
+2014-01-04 Christophe Fergeau <cfergeau@redhat.com>
+
+ controller: Don't call g_type_init() in test with newer glib
+ g_type_init() is deprecated, calling it on newer glib causes a compile-time
+ warning.
+
+ controller: Add missing #ifdef WIN32 in test
+ The spicec_pid variable is only used in a #ifdef WIN32 block, but it was
+ unconditionnally declared/initialized. This causes a gcc warning.
+
+2014-01-03 Christophe Fergeau <cfergeau@redhat.com>
+
+ controller: Avoid out of string bound accesses in test
+ When computing the amount of data to send for static strings, the test
+ program is confusing sizeof() which returns the size of the string
+ including the trailing '\0' and strlen() which returns the size of the
+ string without the trailing '\0'.
+ This causes attempts to access one byte past the string.
+ This fixes this coverity warning:
+ Error: OVERRUN (CWE-119): [#def44]
+ spice-gtk-0.20/spice-gtk-0.20/gtk/controller/test.c:258:
+ overrun-buffer-arg: Overrunning array ""main,inputs,playback"" of 21 bytes
+ by passing it to a function which accesses it at byte offset 21 using
+ argument "22UL".
+ spice-gtk-0.20/spice-gtk-0.20/gtk/controller/test.c:101:5:
+ access_dbuff_in_call: Calling "memcpy(void * restrict, void const *
+ restrict, size_t)" indexes array "data" with index "data_size".
+
+ cursor: Avoid potential sign extension issue
+ When doing arithmetic operations on the uint16_t cursor width and height
+ with integer constants, the result of the operation will be of type 'int'
+ as the integer constant as type 'int'.
+ There are 2 places which assign the result of such an operation to
+ an (unsigned 64 bit)) size_t variable. This means that if width/height are
+ big enough, the int -> size_t conversion would cause a sign extension to
+ happen, which is unwanted as we are only manipulating positive values.
+
+ This commit explicitly mark the constants with the correct unsigned type.
+ This fixes this kind of coverity warnings:
+
+ spice-gtk-0.20/spice-gtk-0.20/gtk/channel-cursor.c:388: sign_extension:
+ Suspicious implicit sign extension: "hdr->height" with type "unsigned
+ short" (16 bits, unsigned) is promoted in "4 * hdr->width * hdr->height" to
+ type "int" (32 bits, signed), then sign-extended to type "unsigned long"
+ (64 bits, unsigned). If "4 * hdr->width * hdr->height" is greater than
+ 0x7FFFFFFF, the upper bits of the result will all be 1.
+
+2014-01-02 Jeremy White <jwhite@codeweavers.com>
+
+ Add support for the Opus codec.
+
+ Don't emit start signals if codec creation fails.
+
+ Use the new snd_codec interface to process encoded audio.
+
+2013-12-12 David Jaša <djasa@redhat.com>
+
+ Use TLS version 1.0 or better
+ When creating a TLS socket, both spice-server and spice-gtk currently
+ call SSL_CTX_new(TLSv1_method()). The TLSv1_method() function set the
+ protocol version to TLS 1.0 exclusively. The correct way to support
+ multiple protocol versions is to call SSLv23_method() in spite of its
+ scary name. This method will enable all SSL/TLS protocol versions. The
+ protocol suite may be further narrowed down by setting respective
+ SSL_OP_NO_<version_code> options of SSL context. This possibility is
+ used in this patch in order to block use of SSLv3 that is enabled by
+ default in openssl for client sockets as of now but spice has never used
+ it.
+
+2013-12-09 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ coroutine: add missing glib.h include
+
+2013-12-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: fix giscan warnings, add missing signal doc
+ GISCAN SpiceClientGLib-2.0.gir
+ channel-main.c:633: Warning: SpiceClientGLib: incorrect number of
+ parameters in comment block, parameter annotations will be ignored.
+ channel-main.c:672: Warning: SpiceClientGLib: incorrect number of
+ parameters in comment block, parameter annotations will be ignored.
+ channel-main.c:716: Warning: SpiceClientGLib: incorrect number of
+ parameters in comment block, parameter annotations will be ignored.
+ channel-main.c:757: Warning: SpiceClientGLib: incorrect number of
+ parameters in comment block, parameter annotations will be ignored.
+ channel-display.c:367: Warning: SpiceClientGLib: incorrect number of
+ parameters in comment block, parameter annotations will be ignored.
+ GICOMP SpiceClientGLib-2.0.gir
+
+ Pushed unreviewed under trivial rule.
+
+2013-11-27 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release v0.22
+ v0.22
+ =====
+
+ - improve inverted cursor support
+ - use system-wide trust certificate store
+ - make sasl support work with other method than MD5
+ - fix some clipboard crasher, limit clipboard size
+ - fix various regressions:
+ usbredir, alt-tab on win32, palette crash, agent notification, old
+ protocol support, sasl ending crash, gthread coroutine crash, close
+ sockets on migration, pulse backend crash
+ - fix a few memory leaks
+ - build-sys improvements
+
+ build-sys: bump spice-glib version
+ new symbols in spice-glib, bump before release
+
+ continuation: fix "fortify" crash
+ Since 0508f586, errno.h is included above #undef _FORTIFY_SOURCE.
+
+ But it must be placed above system headers to take effect
+
+ *** longjmp causes uninitialized stack frame ***:
+ /home/jwhite/xfer/spice/bin/spicy terminated
+ ======= Backtrace: =========
+ /lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x37)[0x7ffff48dc2a7]
+ /lib/x86_64-linux-gnu/libc.so.6(+0xef239)[0x7ffff48dc239]
+ /lib/x86_64-linux-gnu/libc.so.6(__longjmp_chk+0x33)[0x7ffff48dc1a3]
+ /home/jwhite/xfer/spice/lib/libspice-client-glib-2.0.so.8(+0x49761)[0x7ffff78f1761]
+ /home/jwhite/xfer/spice/lib/libspice-client-glib-2.0.so.8(+0x499a4)[0x7ffff78f19a4]
+ /home/jwhite/xfer/spice/lib/libspice-client-glib-2.0.so.8(+0x1bae7)[0x7ffff78c3ae7]
+ /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_context_dispatch+0x135)[0x7ffff505f355]
+ /lib/x86_64-linux-gnu/libglib-2.0.so.0(+0x4a688)[0x7ffff505f688]
+ /lib/x86_64-linux-gnu/libglib-2.0.so.0(g_main_loop_run+0x72)[0x7ffff505fa82]
+ /home/jwhite/xfer/spice/bin/spicy[0x4054aa]
+ /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7ffff480bead]
+ /home/jwhite/xfer/spice/bin/spicy[0x405679]
+
+2013-11-26 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ pulse: do not abort on corking no stream
+ There is no guarantee that a stream actually exist when min-latency
+ change is notified.
+
+ Check that there is an actual stream before calling cork(). All callers
+ where previously checking that stream existed. Add a pre-condition to
+ verify argument and spot that error is from spice-gtk itself.
+
+ Fixes the following crash:
+ #1 0x0000003c12e34105 in abort () at abort.c:92
+ #2 0x0000003c2c223180 in pa_stream_is_corked (s=0x0) at
+ pulse/stream.c:2536
+ #3 0x0000003c2c648cb7 in stream_cork (pulse=<value optimized out>,
+ s=0x7fbb38, with_flush=0) at spice-pulse.c:227
+ #4 0x0000003c2c649989 in playback_min_latency_changed (object=<value
+ optimized out>, pspec=<value optimized out>, data=0x7fbad0) at
+ spice-pulse.c:674
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=1032785
+
+2013-11-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ channel: swap channel GSocketConnection on migration
+ When migration completes, unrefing the new connection leads to original
+ GSocket pending refs, and thus the sockets stay in CLOSE_WAIT.
+
+ This is a regression from 8029bd0 where GSocketConnection is kept around
+ to satisfy old glib.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=1024501
+
+ This will also probably fix:
+ https://bugzilla.redhat.com/show_bug.cgi?id=952375
+
+2013-11-21 dietmar@proxmox.com <dietmar@proxmox.com>
+
+ Fix SASL for mechanism using WANT_CLIENT_FIRST
+ Current code works with DIGEST-MD5, but not with PLAIN.
+
+ In particular, when using PLAIN, sasl_client_start() returns SASL_OK, which
+ should not be an error in spite of vague/confusing upstream documentation
+ about this:
+ http://asg.andrew.cmu.edu/archive/message.php?mailbox=archive.cyrus-sasl&msg=10104
+
+2013-11-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ main: fix recent main_channel_reset() warning
+ Fix wrong warning added in 0704147d.
+
+ (lt-spicy:17511):
+ GSpice-WARNING **: (channel-main.c:415):spice_main_channel_reset:
+ runtime check failed: (c->agent_connected == FALSE)
+
+ coroutine: make gthread coroutine pass tests
+ The coroutine entry() return value must be passed via the caller->data,
+ since coroutine_swap() returns from->data. (this is needed because
+ coroutine_swap() argument is used both to return from entry() or to send
+ data to a running coroutine)
+
+ When leaving a coroutine, clear its caller.
+
+ Return correct coroutine_self() before other coroutine are initialized.
+
+ tests: add some coroutine tests
+
+ coroutine: replace IN_MAIN_CONTEXT macro
+ Use a nicer function, with correct prefix.
+ Remove extra "context" from function name
+
+ coroutine: error out on OOM or impossible conditions
+ Take an approach similar to gthreads, which are considered as low
+ level/must work features by glib, which aborts on failures.
+
+ channel: get rid of connection_id, available from session
+
+ channel: remove useless desc != NULL check
+ spice_channel_type_to_string() does not return NULL
+
+2013-11-20 Christophe Fergeau <cfergeau@redhat.com>
+
+ Fix 'monitors' leak in update_monitor_area()
+ This function has an early return where we fail to unref the 'monitors'
+ array.
+
+2013-11-19 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ main: send max-clipboard to agent
+ Send configured max-clipboard size to the agent, after receiving agent
+ capabilities.
+
+ See also spice-protocol patch description:
+ http://lists.freedesktop.org/archives/spice-devel/2013-November/015254.html
+
+ main: simplify usage of VD_AGENT_HAS_CAPABILITY
+ Introduce a helper function test_agent_cap() to clear the code a
+ little bit.
+
+ main: use self for main channel variable
+ This simplifies the following commit which uses even more
+ SPICE_MAIN_CHANNEL macro, and makes the code unnecessarily heavy.
+
+ Add SPICE_MAX_CLIPBOARD environment variable
+ Allow to easily override default max-clipboard value with environment
+ variable.
+
+ Block sending clipboard data > max-clipboard
+ Attempt to send very large clipboard data may easy cause OOM
+ abort, either in gdk - some patch are proposed to improve the situation,
+ or in spice-gtk itself.
+
+ Let's have a property that blocks unreasonably big clipboard data from
+ being processed (by default 100mb). Users willing to send larger data
+ can use the send basic drag-drop send file instead, or tweak the
+ property value.
+
+2013-11-19 Christophe Fergeau <cfergeau@redhat.com>
+
+ Use system-wide trust certificate store
+ Currently, spice-gtk will look in $HOME/.spicec/spice_truststore.pem
+ by default for its trust certificate store (to verify the certificates
+ used during SPICE TLS connections).
+ However, these days, progress is under-way to have a system-wide
+ certificate store [1].
+ In order to use it, we only need to call SSL_CTX_set_default_verify_paths()
+ and it will automatically use the shared system CA store if the distro
+ is properly setup.
+ We only try to use that store if there was no user-provided CA file to use,
+ or if we failed to load it.
+
+ [1] https://fedoraproject.org/wiki/Features/SharedSystemCertificates
+
+ build-sys: Add real autodetection of python
+ configure help text says that by default python will be used automatically
+ if appropriate, however this only means that on !windows and !gtk3, we will
+ force build of the python bindings, and fail if any needed package to build
+ them is missing.
+
+ This commit improves on the current checks so that when autodetecting
+ python, if a package is missing then build of the bindings is silently
+ disabled rather than failing.
+
+ build-sys: Re-enable building of python bindings by default
+ Commit daa4ece tried to disable building of python bindings on Windows by
+ default, but in doing so, it also disabled building of python bindings by
+ default when we are building neither for Windows nor for gtk3.
+
+ build-sys: Fix invalid 'test' syntax in configure.ac
+ test ... -o test ... is not a valid shell construct, change it to
+ test ... || test ... as this is more portable than test ... -o ...
+
+ This was causing a warning when running configure.
+
+2013-11-18 Christophe Fergeau <cfergeau@redhat.com>
+
+ Fix leak of mmapped memory when cc_init() fails
+
+ Check coroutine_init() return value
+ coroutine_init() can fail, but spice-channel.c was not checking its return
+ value, which could lead to some crashes if coroutine_init() failed and we
+ then try to use coroutine_yieldto()
+
+2013-11-18 Daniel P. Berrange <berrange@redhat.com>
+
+ Free coroutine stack when releasing coroutine
+ The coroutine_init function mmap's a stack for the
+ ucontext coroutine, but nothing ever munmaps it.
+
+ Abort if mmap of coroutine stack fails
+ If we fail to mmap the stack, abort the processs rather
+ than returning an error. This is standard practice in
+ glib apps, and the caller was not checking the
+ coroutine_init() return code leading to memory corruption.
+
+2013-11-18 Christophe Fergeau <cfergeau@redhat.com>
+
+ Fix IN_MAIN_CONTEXT when using coroutine=gthread
+ The IN_MAIN_CONTEXT macro checks coroutine_self()->caller against NULL to
+ decide whether we are in the main context or not. However, this is an
+ implementation detail of the ucontext coroutine implementation, in the
+ gthread implementation, coroutine_self()->caller will be non-NULL even in
+ the main context.
+
+ This commit introduces a coroutine_is_main_context() method which each
+ coroutine backend implements. It turns out it can be implemented the same
+ way for each backend.
+
+ Fix crash on remote-viewer startup with gthread coroutine
+ g_object_notify_main_context() was recently changed to automatically
+ detect whether we are running in the main context or not, and SpiceSession
+ is now using g_object_notify_main_context().
+
+ In order to achieve that, IN_MAIN_CONTEXT is used, but it's not safe
+ to be used before coroutine_init() is called. IN_MAIN_CONTEXT expands to
+ (coroutine_self()->caller == NULL), but coroutine_self() will be NULL when
+ using gthreads for the coroutine implementation until coroutine_init() has
+ been called.
+
+ Before coroutine_init() has been called, we'll always be running in the
+ main context, so we can just add a check for coroutine_self() != NULL to
+ IN_MAIN_CONTEXT to solve that issue.
+
+2013-11-18 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ coroutine: fix current coroutine
+ When leaving a coroutine, it swaps back to where it came from, not to
+ the leader/main coroutine.
+
+ coroutine: add some preconditions
+
+2013-11-08 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Guarantee that 'uuid' property is notified after connection
+ This creates a synchronization point and allows API users to rely on the fact
+ that they'll always get a UUID notification before all of the channels are
+ created.
+
+ Make sure property notifications are done in the main context
+ Modify g_object_notify_main_conetxt() to work whether it's called from the main
+ context or a coroutine context. Change object notify calls in SpiceSession to
+ use g_object_notify_main_context() instead of g_object_notify().
+
+ Revert "Add ability to get SpiceDisplay resolution"
+ This reverts commit a285e0187d15ad650f6524f3811072fa55b20617.
+
+ This API was not actually needed for what I intended to use it for. So revert
+ for now. We can always add it back if necessary in the future.
+
+ Conflicts:
+ gtk/spice-widget.c
+
+2013-11-06 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ display: blank surface on creation
+ In theory, zero-ing the surface shouldn't be necessary, as only
+ invalidated/painted region should be shown. However, this results in
+ less artifacts on resolution changes (probably some regions are painted,
+ but with masks, blend, copy etc), in particular on console after VM
+ reboot.
+
+2013-11-04 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ widget: add since tag for spice_display_get_monitor_config()
+
+2013-11-04 Jonathon Jongsma <jjongsma@redhat.com>
+
+ SpiceDisplay: validate 'self' argument for public API
+ Add defensive g_return[_val]_if_fail(SPICE_IS_DISPLAY()) to all public API
+
+ Add ability to get SpiceDisplay resolution
+ Add spice_display_get_monitor_config() to get the current configuration of the
+ display.
+
+2013-11-04 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix spice-common submodule, my bad
+
+2013-11-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ util: document spice_uuid_to_string
+
+2013-11-01 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ util: do not overwrite G_MESSAGES_DEBUG=all
+ glib log handler only check for a single 'all' value, mixing it with
+ other domains name will disable 'all' messages.
+
+2013-10-29 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Export spice_uuid_to_string() properly
+ Update map-file and spice-glib-sym-file
+
+ Expose spice_uuid_to_string() as public API
+ SpiceSeession has a 'uuid' property that is a byte array, but clients often need
+ the uuid in string format (for writing to disk, etc). Rather than having each
+ client re-implement this, expose the utility function as public API in
+ spice-gtk.
+
+2013-10-20 Alon Levy <alevy@redhat.com>
+
+ channel-cursor: mono cursors edge highlighting
+ Fix 998529, mono (invert) cursors not visible on a black background, by doing
+ simple edge detection on the cursor (this is done once when the cursor
+ is changed and then cached, cursors are 32x32 generally) and thus having
+ a cursor with contrast on both dark and light backgrounds.
+
+ When (if) GDK gets invert cursor support (wayland?) then we can just use
+ the cursor as is. Until then X doesn't provide any way I see of solving
+ this otherwise. The end result was tested with the I beam cursor that
+ the original bug was referring to (run putty on a windows 7 vm) and
+ looks ok to me.
+
+ Moving the core function to spice-util for testing.
+
+2013-10-18 Alon Levy <alevy@redhat.com>
+
+ cursor-channel.c: add cursor print function for debugging only (ifdefed)
+
+2013-10-16 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ main: add missing vdagent caps name
+ This is useful in debug messages atm.
+
+2013-10-16 Christophe Fergeau <cfergeau@redhat.com>
+
+ sasl: Fix crash when ending a SASL session
+ When exiting remote-viewer after authenticating through SASL, I got
+ this crash:
+
+ #0 0x0000000100a51870 in ?? ()
+ #1 0x000000314d20c53e in _sasl_log (conn=<optimized out>, level=5, fmt=0x7fffe49893e8 "DIGEST-MD5 client mech dispose")
+ at common.c:1985
+ #2 0x00007fffe4982d88 in digestmd5_client_mech_dispose (conn_context=0xaf1900, utils=0xaefd10) at digestmd5.c:4580
+ #3 0x000000314d208654 in client_dispose (pconn=0xaf0710) at client.c:332
+ #4 0x000000314d20b76b in sasl_dispose (pconn=0xa51898) at common.c:851
+ #5 0x00007ffff7602dc7 in channel_reset (channel=0xa52250, migrating=0) at spice-channel.c:2493
+ #6 0x00007ffff760f7b7 in spice_inputs_channel_reset (channel=0xa52250, migrating=0) at channel-inputs.c:615
+ #7 0x00007ffff76030ac in spice_channel_reset (channel=0xa52250, migrating=0) at spice-channel.c:2551
+ #8 0x00007ffff76031e0 in channel_disconnect (channel=0xa52250) at spice-channel.c:2570
+ #9 0x00007ffff760283d in spice_channel_coroutine (data=0xa52250) at spice-channel.c:2368
+ #10 0x00007ffff763d14b in coroutine_trampoline (cc=0xa51900) at coroutine_ucontext.c:58
+ #11 0x00007ffff763ce30 in continuation_trampoline (i0=10819840, i1=0) at continuation.c:49
+ #12 0x00000031342479c0 in ?? () from /lib64/libc.so.6
+ #13 0x0000000000a51cc8 in ?? ()
+ #14 0x0000000000000000 in ?? ()
+
+ It turns out that the sasl_callback_t data passed when calling
+ sasl_client_new() must be valid until sasl_dispose() is called. I could not
+ find mentions of this in the official documentation but
+ https://mail-archives.apache.org/mod_mbox/subversion-dev/201109.mbox/%3C20110908072256.GN25324@ted.stsp.name%3E
+ describes what happens.
+ Making the sasl_callback_t structure static should be enough to guarantee
+ that the data will stay around long enough.
+
+ Display g_debug messages when SPICE_DEBUG is set
+ When SPICE_DEBUG is set but --spice-debug is not used, we fail
+ to set G_MESSAGES_DEBUG to the log domain used by spice-gtk, which
+ causes debug messages not to be printed as one would expect.
+
+ Fix --spice-debug
+ If spice_util_set_debug() gets called before spice_util_get_debug(),
+ then the value set using spice_util_set_debug() will be overridden
+ by the result of g_getenv("SPICE_DEBUG") != NULL the first time
+ spice_util_get_debug() is called.
+
+ This causes remote-viewer --spice-debug to not enable debug as
+ advertised if SPICE_DEBUG is not set.
+
+ An alternate fix would have been to set debug_once.status to
+ G_ONCE_STATUS_READY but then we would lose the thread-safety
+ guarantees GOnce gives us.
+
+2013-10-10 Christophe Fergeau <cfergeau@redhat.com>
+
+ Fix switch to old SPICE protocol
+ After the previous commit, spice_channel_switch_protocol() is now
+ called when needed, but it's not doing anything. What happens is
+ that spice_channel_switch_protocol() triggers a channel disconnection
+ and then it queues an idle to reconnect (after having changed the
+ protocol version to be used).
+
+ When spice_channel_recv_link_hdr() returns, we need to jump out of
+ the coroutine to let the idle trigger and the new channel coroutine
+ be started. But jumping out of the coroutine will call channel_disconnect()
+ which calls channel_reset() which disables the idle switch_protocol()
+ just queued. This causes the connection attempt to be apparently
+ stuck with nothing happening.
+
+ Falling back to the older SPICE protocol is not the only situation
+ when we need to drop the current connection attempt and reconnect,
+ we also need to do that when the remote server returns
+ SPICE_LINK_ERR_NEED_SECURED to let the client know it needs to use
+ a secure port for this channel. This is handled by the 'switch_tls'
+ variable set in spice_channel_recv_link_msg and handled in
+ spice_channel_coroutine().
+
+ 'switch_tls' does the same thing as spice_channel_switch_protocol(),
+ except that it calls spice_channel_connect() after channel_disconnect()
+ has been called, which means the idle queued by channel_connect()
+ won't get cleared.
+
+ This all that commit does, remove the spice_channel_switch_protocol()
+ method and use the same codepath as 'switch_tls' to handle the
+ reconnection.
+
+ Reenable call to switch_protocol() on protocol version mismatches
+ This partially reverts b19acbc. This commit broke the fallback
+ to the old protocol as it added a check for c->peer_msg != NULL
+ before calling switch_protocol(), but mismatch between local
+ and remote protocol versions is detected before c->peer_msg is
+ allocated, so:
+ if (c->peer_msg != NULL && c->link_hdr.major_version != 1) {
+ SPICE_DEBUG("%s: error, switching to protocol 1 (spice 0.4)",
+ c->name);
+ spice_channel_switch_protocol(channel, 1);
+ return TRUE;
+ }
+ will never get triggered when c->peer_hdr.major_version !=
+ c->link_hdr.major_version
+
+ The crash described in b19acbc occurred when calling
+ spice_channel_recv_link_msg() in spice_channel_coroutine()
+ after a call to spice_channel_recv_link_hdr() failed and did
+ not set c->peer_msg.
+
+ This commit removes the c>peer_msg check done before calling
+ spice_channel_switch_protocol() so that it gets called when needed,
+ but makes sure that we return FALSE to indicate that an error happened
+ and that we need to reconnect. This way we won't try to call
+ spice_channel_recv_link_msg() when c->peer_msg is NULL.
+
+ Use latest warnings.m4 from gnulib
+ The one we were using does not work properly with clang, causing
+ the build process to try to use -f/-W options that are not
+ supported by clang.
+
+2013-10-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk-session: avoid mainloop recursion in clipboard_get
+ clipboard_get() exits when the clipboard data is received, or when the
+ agent connection state change. However, if the agent is already
+ disconnected, neither of those 2 conditions can be reached.
+
+ Check if the agent is connected before running loop, exit early if not.
+
+ gtk-session: fix clipboard_agent_connected
+ Use swapped connection to pass data as first argument to signal handler.
+
+ main: fix notify of agent disconnection
+ spice_main_channel_reset_agent() reset connected state, and prevent
+ notify of property change.
+
+ This is a minor regression introduced in c3adb24425.
+
+2013-10-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ display: cache id is uint64_t
+
+ display: fix palette regression
+ palette_get() used to return a ref, and palette_release() used to
+ release that ref.
+
+ Since ed877341, the palette is no longer refcount'ed, since its usage is
+ exclusively local in common/canvas code.
+
+ palette_release() shouldn't remove the palette from the cache.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=1011936
+
+2013-10-02 Alon Levy <alevy@redhat.com>
+
+ mono cursor: increase contrast, better looking putty cursor (rhbz 998529)
+
+2013-09-30 Hans de Goede <hdegoede@redhat.com>
+
+ spice-channel: Fix usbredir being broken since commit 159c6ebf
+ The usbredir channel uses spice_msg_in_raw to get its data, which uses
+ in->dpos to determine the msg size and that was no longer being set for
+ non sub-messages.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=69935
+
+2013-09-26 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ win32: fix alt-tab grab regression
+ Since 5f67178c, alt-tab is no longer grabbed by the client. The keyboard
+ hook still needs to handle WM_SYSKEY{DOWN,UP} messages.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=873341
+
+ build-sys: do not compile python binding with windows by default
+
+ Update spice-common
+
+ build-sys: add --with-audio=auto
+ Defaults to GStreamer on Windows, and PulseAudio otherwise atm.
+
+ build-sys: fix --with-sasl
+ The default configure sasl auto setting will error out if SASL is
+ missing. Instead, silentely skip sasl configure if detected missing.
+
+2013-09-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: fix g_clear_pointer usage on old glib
+ As pointed out and verified on the ML after 0.21 release by Klaus
+ Hochlehnert.
+
+2013-09-18 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release v0.21
+
+2013-09-18 Colin Walters <walters@verbum.org>
+
+ acl helper: Use ruid of invoker rather than looking up euid in /proc
+ This way we avoid a race condition if the parent execve()s a setuid
+ program (possibly this program).
+
+ This is the same as the fix for pkexec which is CVE-2011-1485:
+ See: https://bugzilla.redhat.com/show_bug.cgi?id=692922
+
+2013-09-18 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: fix bad cast on win64
+ spice-widget.c:814:50: error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]
+ g_return_if_fail(SystemParametersInfo(SPI_SETMOUSESPEED, 0, (PVOID)d->win_mouse_speed, 0));
+
+2013-09-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ display: unshare the palette cache
+ As pointed out by Yonit on the ML:
+ > (1) the palette cache shouldn't be shared among the display channels. I.e.,
+ > there should be one instance per channel, and not one instance in
+ > spice-session.
+
+ channel: unref incoming migrate data
+
+2013-09-13 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ gtk: simplify spice_channel_recv_msg
+ Use of coroutines allow to simplify spice_channel_recv_msg(), it doesn't
+ need to keep current reading state, it can rely on the coroutine stack
+ for that.
+
+ gtk: use slices for frequently allocated objects
+
+ gtk: use GHashTable in display_cache
+ The cache code isn't very quick, it shows up in profilers. Using
+ GHashTable allows to simplify the code while making it faster.
+
+ channel: do not reenter the mainloop at every iteration
+ The current coroutine channel_iterate() creates a GSource for the socket
+ reenters the mainloop waiting for IO condition. This is really heavy
+ usage of mainloop showing up in system time and user space
+ profiling (10% of CPU time spent in mainloop overhead). Instead flush
+ all pending input messages before switching context and reentering main
+ loop.
+
+ This is the kind of results I get with a replay:
+
+ before:
+
+ 2179,440455 task-clock # 0,629 CPUs utilized
+ 3 580 context-switches # 0,002 M/sec
+ 207 cpu-migrations # 0,095 K/sec
+ 48 909 page-faults # 0,022 M/sec
+ 7 362 442 301 cycles # 3,378 GHz
+ 5 256 957 520 stalled-cycles-frontend # 71,40% frontend cycles
+ idle
+ <not supported> stalled-cycles-backend
+ 5 460 266 981 instructions # 0,74 insns per cycle
+ # 0,96 stalled cycles
+ per insn
+ 982 749 523 branches # 450,918 M/sec
+ 20 745 453 branch-misses # 2,11% of all branches
+
+ 3,463422087 seconds time elapsed
+
+ after:
+
+ 1741,651383 task-clock # 0,522 CPUs utilized
+ 5 093 context-switches # 0,003 M/sec
+ 137 cpu-migrations # 0,079 K/sec
+ 49 033 page-faults # 0,028 M/sec
+ 5 874 567 974 cycles # 3,373 GHz
+ 4 247 059 288 stalled-cycles-frontend # 72,30% frontend cycles
+ idle
+ <not supported> stalled-cycles-backend
+ 4 419 666 346 instructions # 0,75 insns per cycle
+ # 0,96 stalled cycles
+ per insn
+ 776 972 366 branches # 446,112 M/sec
+ 17 862 170 branch-misses # 2,30% of all branches
+
+ 3,337472053 seconds time elapsed
+
+ util: avoid calling getenv for every SPICE_DEBUG
+ That doesn't seem to really improve performance so much,
+ but that' s what we should do probably.
+
+2013-09-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ display: keep a reference to the primary surface
+ Avoid hard-coding surface 0 as being primary, although in practice it
+ always is so far. Also a lot of lookups are primary, so add a shortcut
+ for this special case (~30% apparently), it shows some small lookup
+ speedup.
+
+ before:
+ real 0m5.008s
+ user 0m3.253s
+ sys 0m2.015s
+
+ after:
+ real 0m4.930s
+ user 0m3.133s
+ sys 0m2.027s
+
+ display: make the hashtable to destroy the surface
+ Improve a bit the code by using hashtable ownership.
+
+ display: replace ring with hashtable
+ With a Spice replay (a tool not yet merged, but available in dev
+ branches), the following commit improves a little bit performance by not
+ spending so much CPU time in looking up surfaces. I found initially
+ hotspot with "perf", and get a consistant ~200ms speedup with "time
+ spicy-stats" after replacing the ring.
+
+ before:
+ real 0m5.147s
+ user 0m3.506s
+ sys 0m1.949s
+
+ after:
+ real 0m5.008s
+ user 0m3.253s
+ sys 0m2.015s
+
+ channel: add SPICE_DISABLE_CHANNELS
+ Allow to disable selectively channels, mainly used for testing,
+ ex: SPICE_DISABLE_CHANNELS=display spicy-stats -p 12345
+
+ channels: use spice_channel_set_handlers()
+ This allows to simplify a little bit derived class (no need to override
+ handle_msg), and allows the base class more flexibility (for example for
+ filtering messages, as in the following patch)
+
+ channel: add spice_channel_set_handlers()
+ This function will allow to set base handlers and specific channel
+ handlers in a common way, instead of each channel having to override the
+ base channel virtual handle_msg().
+
+ display: use bitfields for surface flags
+ Checking by value make the flag fields useless. Unfortunately, when
+ adding more flags, the server will have to ensure it can safely send it,
+ by checking some of new client caps (for some features).
+
+ Update spice-common
+
+2013-09-10 Dunrong Huang <riegamaths@gmail.com>
+
+ Fix _FORTIFY_SOURCE redefine error
+ If the _FORTIFY_SOURCE has been already defined, we shouldn't redefine
+ it, or it will raise a build error as below:
+
+ In file included from spice-audio.c:36:0:
+ ../config.h:12:0: error: "_FORTIFY_SOURCE" redefined [-Werror]
+ spice-audio.c:1:0: note: this is the location of the previous definition
+
+ Suggested-by: Christophe Fergeau <cfergeau@redhat.com>
+
+2013-08-28 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ Revert "tmp: debug MIGRATE_DATA"
+ This reverts commit f670e0197c37b2f12518f6d216642f67cdf5de84.
+
+2013-08-28 Alon Levy <alevy@redhat.com>
+
+ gtk/channel-cursor: copy spicec hack, RHBZ #998529
+ flip -> unsupported by x11, since XCreatePixmapCursor has no invert
+ functionality, only a mask, shape, background and foreground colors. Use
+ this checkerboard hack to get some contrast for cursors in the guest
+ that relied on invert for the same contrast.
+
+ gtk/channel-cursor.c: add cursor_type_to_string for debugging
+
+ gtk/channel-display: only use SysV shm for x11
+
+ tmp: debug MIGRATE_DATA
+
+2013-08-28 Jonathon Jongsma <jjongsma@redhat.com>
+
+ Remove incorrect option context from spicy-stats
+ The argument given to g_option_context_new() was apparently copy/pasted from
+ spicy-screenshot and therefore inaccurate for spicy-stats. Since the actual
+ description of the program (from _set_summary()) is displayed on the next line
+ anyway, simply make the context NULL.
+
+ channel-main: Fix minor documentation issue
+ Documentation for spice_main_clipboard_selection_request() refers to deprecated
+ signal 'main-clipboard' instead of 'main-clipboard-selection'
+
+2013-08-24 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ tests: add some dos2unix tests
+ This is probably not exhaustive enough, but better than nothing.
+
+ gtk: handle clipboard CRLF conversion
+ gtk+ internal text/utf8 is using LF conversion, on all platforms.
+ Even though the toolkit may only handle a single line ending type, we
+ may want to avoid the conversion for Spice use cases, gtk+ could learn a
+ new native utf8 target type, see also:
+ https://bugzilla.gnome.org/show_bug.cgi?id=706657
+
+ In the meantime, the only thing we need to convert, is to/from crlf
+ guest (from/to lf). This is what this change is about.
+
+ It has been tested successfully with the various guest/client OS
+ combinations.
+
+ util: add unix2dos and dos2unix
+ Convert line endings from/to LF/CRLF.
+
+ Revert "channel-main: Convert text line-endings if necessary (rhbz#752350)"
+ This implementation assumes that the toolkit doesn't do any conversion
+ on its own. This is actually not the case, gtk+ converts line endings
+ already on windows. It would be pretty ugly to do conversions back and
+ forth at different levels. So the channel implementation shouldn't
+ try to do conversion, and implementation must be done at higher level,
+ where the actual system clipboard implementation is known (at
+ gtk-session for instance)
+
+ Since this code hasn't been officially released, let's revert it and
+ implement a better crlf conversion handling in gtk-session in the
+ following commits.
+
+ This reverts commit e45a446a9981ad4adaeff9c885962a8c6140333e.
+
+2013-08-23 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: remove dead code
+
+2013-08-20 Uri Lublin <uril@redhat.com>
+
+ win-usb-dev: ignore devices with addr 1 for LIBUSBX_API_VERSION
+ Starting libusbx version 1.0.13 (commit 8cd30bb7066f785ee78cf6c3dccafdbc4b957b50)
+ windows device enumeration changed and root hubs address number is 1 intead
+ of 0xff.
+
+ This patch uses LIBUSBX_API_VERSION which was introduced after 1.0.13 release
+ (commit 9d368fc4774344d81ab02840f3a8478301bfb6fa).
+
+ win usb: request for driver uninstall only for driver that were installed
+ Currently when spice_usb_device_manager_remove_dev() is called,
+ for windows clients a request to uninstall the driver is sent to usbclerk.
+
+ This cause problems when 2 instances (A and B) of the client are running:
+ - Both A and B get notified about a new USB device when it's plugged in
+ - A is requested to usbredir the USB device.
+ - A requests usbclerk to install WinUSB driver for that device.
+ - usbclerk starts installing the driver
+ - Windows sends to both A and B - device removal events, which may cause
+ B to call spice_usb_device_manager_remove_dev.
+ - usbclerk completes installing the driver and reply to A
+ - B requests usbclerk to remove the WinUSB driver for that device.
+
+ To prevent that, spice-gtk now requests usbclerk to remove the driver
+ only if it was the instance that requested the driver to be installed.
+ This is done with the help of a new device SPICE_USB_DEVICE_STATE_INSTALLED
+ state.
+
+ rhbz#919166
+
+2013-08-19 Christophe Fergeau <cfergeau@redhat.com>
+
+ Use g_slist_foreach_full glib implementation
+ For the compat case (glib < 2.28), we were using our own implementation
+ instead of directly reusing glib code.
+
+2013-08-19 Hans de Goede <hdegoede@redhat.com>
+
+ glib-compat: g_slist_free_full: pass the right ptr to destroy (rhbz#997893)
+ The destroy function passed to g_slist_free_full should be passed the elements
+ data pointer, not the element itself.
+
+2013-08-13 Christophe Fergeau <cfergeau@redhat.com>
+
+ Only use GOBJECT_INTROSPECTION_CHECK when available
+ Current el6 systems don't have gobject-introspection packages,
+ so the GOBJECT_INTROSPECTION_CHECK m4 macro is not available
+ on such systems. This makes it difficult to run autogen.sh
+ on these systems.
+ This commit uses m4_ifdef to check if this macro is available
+ before trying to use it, and makes sure introspection is
+ disabled when GOBJECT_INTROSPECTION_CHECK could not be found.
+ This allows to compile spice-gtk from git on el6 systems
+ with:
+ ./autogen.sh --with-gtk=2.0 --disable-gtk-doc --disable-vala
+ --disable-controller --disable-werror
+
+2013-08-07 Yonit Halperin <yhalperi@redhat.com>
+
+ usb-device-manager: fix compilation error when usbredir is disabled
+
+2013-08-06 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ usb-widget: fix gtk2 Python bindings
+ The Python bindings generator failed to bind the USB widget, because of
+ the object/class declaration. The declaration was circumventing the
+ deprecated errors when compiling with GTK_DISABLE_DEPRECATED. We used
+ to need that because of broken gtk+ headers, but it is no longer
+ necessary since 15bd7ceba1434b5d710bfd16078044f30693467b.
+
+2013-07-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: copy "ca" property in copy ctor
+ This fixes the GSpice-WARNING **: no cert loaded, when doing a seamless
+ migration (when using the "ca" property).
+
+2013-07-11 Christophe Fergeau <cfergeau@redhat.com>
+
+ smartcard: Only init manager once
+ The SpiceSmartcardManager is a singleton, so it does not make
+ a lot of sense to try to init it multiple times. This commit adds
+ a GOnce to ensure the manager is only init'ed once.
+
+ smartcard: Handle VCARD_EMUL_INIT_ALREADY_INITED
+ When initializing a software smartcard, vcard_emul_init() can
+ report success, error, or indicate that initialization has already
+ been done. In this last case, we would assume that an error occurred
+ instead of behaving as if the initialization succeeded.
+
+ vcard_emul_init() can end up being called multiple time if the
+ smartcard channel gets destroyed and recreated during the lifetime
+ of the application
+
+ Fixes rhbz#815639
+
+2013-07-08 Christophe Fergeau <cfergeau@redhat.com>
+
+ doc: Fix typo in code comment
+
+ gst: Chain up dispose impl to parent class
+
+ gi: Add (allow none) to optional const char * params
+ Without that annotation, it will not be possible to pass NULL to
+ these methods when using a gi-based binding.
+
+ gi: Make sure usb-device-widget.c is introspected
+ If it's not, annotation we add to inline gtk-doc comments won't
+ be taken into account in the .gir file.
+
+2013-07-05 Hans de Goede <hdegoede@redhat.com>
+
+ usb-device-manager: Add support for libusb hotplug API
+ For now this makes the usb-code even more of a #ifdef party (albeit only
+ slightly so). But it does give us (theoretical, untested) usb support on
+ Mac OS X, and once the libusb Windows backend also gets hotplug support, we
+ can bump the required libusb version to a new enough one, and drop both the
+ windows gudev emulation as well as the gudev code-paths.
+
+2013-07-04 Hans de Goede <hdegoede@redhat.com>
+
+ usb-device-manager: Splitout device add / remove function
+ Split the device add / remove functions into a gudev specific part and
+ a generic part. This is a preparation patch for adding support libusb's
+ new hotplug API.
+
+2013-06-27 Hans de Goede <hdegoede@redhat.com>
+
+ Add spice_channel_string_to_type to map files
+ And document both spice_channel_string_to_type and
+ spice_channel_type_to_string.
+
+ channel-main: Convert text line-endings if necessary (rhbz#752350)
+ This implements line-ending conversion following the specification in the
+ commit message of spice-protocol commit 7be0e88e7e03a956b364cc847aad11b96ed4 :
+ vd_agent: Add caps for the agent to signal the guest line-ending (rhbz#752350)
+
+2013-06-26 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release v0.20
+
+ build-sys: bump spice-glib version
+ new symbols in spice-glib, bump before release
+
+ doc: add missing symbols and versions
+
+2013-06-24 Yonit Halperin <yhalperi@redhat.com>
+
+ display: disabling adaptive video streaming via env var SPICE_DISABLE_ADAPTIVE_STREAMING
+ spice-server supports adaptive video streaming only if the client
+ publishes SPICE_DISPLAY_CAP_STREAM_REPORT.
+
+ Disabling this feature is useful for debugging and performance comparison.
+
+ display: video stats logging - improve readability and ease of parsing
+
+2013-06-24 Christophe Fergeau <cfergeau@redhat.com>
+
+ automake: Disable portability warnings
+ When they are enabled, autogen.sh fails with:
+ automake: warnings are treated as errors
+ gtk-doc.make:77: warning: GTK_DOC_V_SETUP_$(V: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:78: warning: GTK_DOC_V_SETUP_$(AM_DEFAULT_VERBOSITY: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:96: warning: GTK_DOC_V_SCAN_$(V: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:97: warning: GTK_DOC_V_SCAN_$(AM_DEFAULT_VERBOSITY: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:100: warning: GTK_DOC_V_INTROSPECT_$(V: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:101: warning: GTK_DOC_V_INTROSPECT_$(AM_DEFAULT_VERBOSITY: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:132: warning: GTK_DOC_V_XML_$(V: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:133: warning: GTK_DOC_V_XML_$(AM_DEFAULT_VERBOSITY: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:149: warning: GTK_DOC_V_HTML_$(V: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:150: warning: GTK_DOC_V_HTML_$(AM_DEFAULT_VERBOSITY: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:153: warning: GTK_DOC_V_XREF_$(V: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:154: warning: GTK_DOC_V_XREF_$(AM_DEFAULT_VERBOSITY: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:185: warning: GTK_DOC_V_PDF_$(V: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ gtk-doc.make:186: warning: GTK_DOC_V_PDF_$(AM_DEFAULT_VERBOSITY: non-POSIX recursive variable expansion
+ doc/reference/Makefile.am:59: 'gtk-doc.make' included from here
+ autoreconf: automake failed with exit status: 1
+
+ on my F19.
+ -Wportability used to be automatically disabled with automake <= 1.12 when using
+ silent rules, but this is no longer the case with automake 1.13 which is what
+ fedora 19 uses: http://www.flameeyes.eu/autotools-mythbuster/automake/silent.html
+ "As of version 1.13, though, this opt-in is no longer necessary, as all the
+ Makefiles are generated to support them. The silent-rules option is now a
+ no-op, doing nothing at all, in particular not silencing the portability
+ warnings."
+
+ This commit disables these warnings in order to avoid autogen.sh breakage
+ because of the use of -Werror, they can be reenabled once gtk-doc.make is
+ fixed to avoid these portability warnings.
+
+ Remove obsolete files from POTFILES.in
+ intltool-update -M complains about them
+
+ smartcard: Move down spice_smartcard_reader_is_software body
+ It's more consistent to have it close to
+ spice_smartcard_reader_insert_card() et al.
+
+ Add spice_smartcard_manager_get_readers()
+ This returns the list of smartcard readers known to a given
+ SpiceSmartcardManager. This is useful to check whether a software
+ smartcard reader is available or not.
+
+ smartcard: Add methods to act on software readers
+ Currently, the methods to insert/remove smartcards from a software
+ smartcard reader are global to the SpiceSmartcardManager singleton
+ rather than acting on a SpiceSmartcardreader object.
+ This commit adds insert/remove methods acting on such objects.
+
+ smartcard: Report failure when software reader is missing
+ As there is no easy way to know if the SpiceSmartcardManager
+ has an associated software reader or not, it's better to report
+ failure instead of g_return_if_fail on attempts to use
+ spice_smartcard_manager_insert/remove_card with no software reader
+ available.
+
+2013-06-24 Hans de Goede <hdegoede@redhat.com>
+
+ Update spice-common
+
+2013-06-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ proxy: remove trailing slash from proxy URL
+ Apparently, trailing slash are common for proxy URI. Is there a
+ specification for these kind of URI?
+
+ (I cry that we don't have GUri yet to handle parsing... gbo#489862)
+
+ Fixes:
+ https://bugzilla.redhat.com/show_bug.cgi?id=975472
+
+2013-06-14 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ win32: don't block key up events
+ The win32 ll keyboard hook avoid Windows and other application to
+ receive global keyboard events. But some key combinations can't be
+ filtered, such as Win+L. However, the windows lock screen doesn't catch
+ that the Win key is released, when virt-viewer still holds the hook and
+ filters it.
+
+ So pressing Win+L quickly will lock the screen, but some key press in
+ the password entry will still be handled as if the Win key was pressed,
+ such as Win+P or Win+U and probably other, and prevents user from typing
+ his password.
+
+ The only working solution I could find is to just let go all the release
+ key events in the hook. There doesn't seem any drawback with that.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=917986
+
+ widget: release keys on grab-broken
+ This is similar to 8cbd5d745c221f788878c9c713f3b46a25828d3f and can be
+ reproduced by pressing Win+l while the widget has the keyboard
+ grab (pointer over the display).
+
+ I have not reproduced implicit grab-broken event, I suppose they could
+ happen if the grab is stolen from within the app. In any case, it's
+ probably better to release the keys.
+
+ This is related to:
+ https://bugzilla.redhat.com/show_bug.cgi?id=917986
+
+2013-05-29 Hans de Goede <hdegoede@redhat.com>
+
+ Make sure our foo_get_type functions are thread-safe
+ While debugging:
+ https://bugzilla.redhat.com/show_bug.cgi?id=866718
+
+ I found a thread-safeness issue with a couple of foo_get_type functions
+ in polkit causing this crash.
+
+ After this I decided to check if spice-gtk has the same issue, and it does,
+ since foo_get_type can be called from different threads, it is important to
+ make them thread-safe.
+
+2013-05-16 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ widget: remove grab key filter
+ The widget currently filters out last key press from grab key sequence
+ if it's not a modifier key. But this will prevent nested usage of ungrab
+ combinations such as shift+f12.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=889962
+
+ This will also make the following obsolete:
+ https://bugzilla.redhat.com/show_bug.cgi?id=846005
+
+ Build fix, use correct check version
+
+2013-05-15 Mattias Grönlund <mattias@gronlund.se>
+
+ mingw: Fix non-working AltGr with some layouts
+ Running virt-viewer-x64-0.5.6.msi, on Windows 7, connecting to QEMU using
+ spice, AltGR key combinations fails (using Swedish keyboard layout both at
+ server and client).
+
+ I suspect that this is a variant of
+ https://bugzilla.redhat.com/show_bug.cgi?id=904092.
+
+ After some debugging, I realized that there is an extra VK_LCONTROL
+ keypress sent by Windows. This extra VK_LCONTROL will then make the key
+ e.g. AltGr-< actually be Control-AltGr-<, which is not interpreted as a |
+ sign.
+
+ So in spice-widget.c : keyboard_hook_cb(), I added SPICE_DEBUG lines which
+ printed out the hooked->scanCode, and realized that this extra VK_LCONTROL
+ has a very suspect scanCode with bit 9 set. If I instead press the left
+ Ctrl key, it will also emit VK_LCONTROL, but with bit 9 cleared.
+
+ So I just made sure that keyboard_hook_cb(), silently dropped these strange
+ VK_LCONTROL events, which seems to work for me.
+
+2013-05-15 Christophe Fergeau <cfergeau@redhat.com>
+
+ Fix printf format string warning
+ When doing a mingw32 build, I hit the following warning (which became an
+ error because of -Werror):
+
+ channel-display.c: In function 'destroy_stream':
+ channel-display.c:1546:9: error: format '%lu' expects argument of type 'long unsigned int', but argument 6 has type 'uint64_t' [-Werror=format=]
+ CHANNEL_DEBUG(channel, "%s: drops total duration %lu ==>", __FUNCTION__, drops_duration_total);
+ ^
+
+2013-05-14 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Build fixes for gtk+2
+
+ Fix glib2 2.22 build after edf1daf5
+ channel-display.c: In function 'display_update_stream_report':
+ channel-display.c:1273: warning: implicit declaration of function
+ 'g_get_monotonic_time'
+
+2013-05-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: timeout after 10s of socket connect() attempt
+ https://bugzilla.redhat.com/show_bug.cgi?id=885101
+
+ Fix build after 577263aaf4c
+
+2013-05-13 Yonit Halperin <yhalperi@redhat.com>
+
+ channel-display: protect video streaming from temporarily unsynced mm_time (migration related)
+ rhbz#951664
+
+ When the src and dst servers have different mm-times, we can
+ hit a case when for a short period of time the session mm-time and
+ the video mm-time are not synced. If the video mm-time is much
+ bigger than the session mm-time, the next stream rendering will be
+ scheduled to (video-mm-time - session-mm-time), and even after
+ the different mm-times are synced, the video won't be rendered
+ till the rendering timeout that was scheduled based on a wrong mm-time,
+ takes place.
+ This patch protects from such cases. You can find more details in the
+ code comments.
+
+ spice-session: new signal for notifying on a significant change in mm-time
+ mm-time can change after migration. This can cause video synchronization
+ problems after migration if not handled appropriately (see rhbz#951664).
+
+ emit_main_context macro: handle calls from both coroutine context and main context
+
+2013-05-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ vncdisplaykeymap: add wayland support
+ The Wayland keycode are just Linux evdev, but the Gdk backend
+ add the +8 offset used by Xorg evdev.
+
+2013-05-11 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ vncdisplaykeymap: add broadway support
+
+ keymaps: add basic x11 keysyms
+ Ok, this isn't a good idea, but atm, the browser don't seem to send
+ hardware keycode, and so Gtk+ broadway backend decided to use keysyms
+ representation, which spice-gtk receives as "hardware keycodes"...
+
+ Since Gdk keysyms are same as X11, add a new x11 keysym to keymap.
+
+ This is not going to fly,...
+
+ vncdisplaykeymap: adapt gtk2 compat code
+
+ vncdisplaykeymap: use a window to associate table
+
+ widget: check backend is X11
+ spice-gtk blindly assume the backend is X11 if it's compiled on
+ Unix. But nowadays, gtk+ support runtime backend selection.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=961577
+
+ Remove unused spice_set_keyboard_lock_modifiers()
+ That code was used in early version to set client modifiers lock
+ but it is the wrong approach, and guest should follow client
+ state instead.
+
+ Remove GnomeRR code
+ Changing client resolution is a bad idea, and never took up.
+ Remove some unmaintained experimental code.
+
+ widget: release keys when the grab is taken elsewhere
+ gtk may propagate some press event up to the Spice display widget, but
+ a widget may take focus and grab the release event, so the guest will
+ keep seeing the key pressed.
+
+ Releasing the keys when the grab is taken solves two menu-related bugs:
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=820829
+ https://bugzilla.redhat.com/show_bug.cgi?id=924577
+
+ main: do not send monitors config if some are missing
+ Spice-gtk does a bit of client-side work by optionnally delaying sending
+ the monitor configuration to the guest automatically. However, the
+ client may be slow to set all the monitors, so teach the timer to not
+ fire the event unless at least the number of monitors set explicitely
+ enabled or disabled matches the number of display channels.
+
+ This avoid some configuration races when connecting to a multi-channel
+ display server which is slow to set up.
+
+2013-04-30 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ widget: don't grab mouse when switching to server mode
+ spice-gtk used to try taking the grab when switching to server mode, so
+ that the current mouse interaction (for example a drag), isn't
+ interrupted if the agent dies. However, shutting down a VM will
+ automatically try taking the grab when there is no tablet input, and
+ agent exits.
+
+ Some users are complaining about it (especially when they don't know the
+ ungrab combination).
+
+ Instead, let's try to keep the grab only if we have currently a mouse
+ button pressed.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=873272
+
+2013-04-26 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ main: do not send monitor config if monitor state didn't change
+ Don't send monitor config after spice_main_set_display_enabled() if the
+ monitor state didn't change.
+
+ This solves monitor "flashing", reconfiguring in a loop:
+ https://bugzilla.redhat.com/show_bug.cgi?id=952327
+
+2013-04-24 Hans de Goede <hdegoede@redhat.com>
+
+ usb-redir-manager: Fix redirect_on_connect string mem leak
+
+ usb-device-manager: Fix stray '\n'-s in g_warning calls
+
+ usb-device-manager: Fix redirect_on_connect_rules mem-leak
+
+ usb-device-manager: Add spice_usb_device_manager_get_devices_with_filter (fdo#63807)
+
+ usb-device-manager: Error check spice_usb_device_manager_device_to_libdev calls
+ Under Windows all calls to spice_usb_device_manager_device_to_libdev may fail,
+ so error check them all.
+
+ usb-device-manager: Avoid needless re-numeration of usb devs under Linux
+ libusb_get_device_list() is not exactly a cheap call (lots of sysfs and
+ usbfs accesses), so it is worth to avoid it where possible.
+
+ This patch restores the old (pre win32 support addition) of dealing with
+ libusb-devices under Linux, it keeps the device from the first lookup
+ in spice_usb_device_manager_add_dev cached and uses that throughout.
+
+ This also means that spice_usb_device_manager_device_to_libdev can no
+ longer fail under Linux, so no need to error check it.
+
+2013-04-23 Christophe Fergeau <cfergeau@redhat.com>
+
+ option: Allow multiple options in --disable-effects
+ Commit 82c367 added checks that the value passed to --disable-effects
+ is valid, but it does not take into account that it's perfectly valid
+ to pass multiple values separated by commas. This commit splits
+ the value passed to --disable-effects and checks each component separatey.
+
+ Fixes rhbz#955277
+
+ Fix setting of SPICE_{GLIB,GTK}_REQUIRES
+ Because of a typo (REQUIRED vs REQUIRES), these variables only
+ contained the last require that was set rather than a concatenation
+ of all the needed libraries.
+
+ Fix GNetworkAddress leak when opening spice session
+
+2013-04-22 Yonit Halperin <yhalperi@redhat.com>
+
+ channel-display: trigger re-sync of audio playback latency when there are frequent video frame drops
+ This was added in order to respond more quickly when the audio and video playback are
+ not synchronized, and when the latency between the client and the server
+ is high (i.e., when the server response to the status is delayed).
+
+ playback: support syncing the playback latency via session
+
+ spice-pulse: adjust the playback latency when the min-latency property changes
+ If the current latency is smaller than the new min-latency
+ value, we cork the playback till the target latency is achieved.
+
+ Note: I didn't modify the prebuf configuration and used
+ pa_stream_prebuf, because pulse updated the prebuf only if
+ I set both prebuf and tlength to be target_latency*2. Then,
+ due to the tlength growth, each time the playback latency deviated
+ from the target latency, an underflow occurred. Since the latency
+ that is computed by the server is not exact and is based on its
+ current evaluation of the bit-rate, which is dynamic, it is better not
+ to change the tlength (in order to avoid unnecessary underflows).
+
+ channel-playback: support SPICE_MSG_PLAYBACK_LATENCY
+ Add a new property for minimum playback latency. This property is
+ updated with the value from SPICE_MSG_PLAYBACK_LATENCY.
+ I also increased the default latency from 100ms to 200ms in order to
+ be more robust to different bandwidth settings.
+ The patch also updates spice-common submodule.
+
+ channel-display: video stream quality report
+ Handle MSG_STREAM_ACTIVIATE_REPORT and send MSGC_STREAM_REPORT
+ periodically, or when the playback is out of sync.
+ The patch also updates spice-common submodule.
+
+ channel-playback: provide access to playback properties via the session
+ Support checking whether an audio playback is active and what its latency
+ is.
+
+ spice-pulse: update the playback latency automatically when it changes
+
+ channel-display: collect and print video stream stats
+ also prints the number of underflows during a spice-pulse audio playback
+
+2013-04-12 Christophe Fergeau <cfergeau@redhat.com>
+
+ Revert "build-sys: keep common submodule up to date"
+ This reverts commit 5150285e1cba35570c29bd923df065d2c81f081e.
+
+2013-04-11 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: enforce secure channels
+
+ option: add --spice-secure-channels
+
+ Add function to return Spice channel type from string
+
+ Add function to return list of supported channels
+
+ session: add secure-channels property
+
+ channel: try TLS only once
+ A broken server may reply to switch to TLS again and again. spice-gtk
+ should only try once.
+
+ cosmetic: fix indentation and comment
+
+2013-04-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release v0.19
+
+ build-sys: bump spice-glib version
+ new symbols in spice-glib, bump before release
+
+ Update README/TODO
+
+ spicy-ss: quit when channel error
+
+ Rename snappy to spicy-screenshot
+ Following discussion on the ML:
+ http://lists.freedesktop.org/archives/spice-devel/2013-April/012953.html
+
+ build-sys: keep common submodule up to date
+ This requires git 1.8.2 to work properly. With this we should no longer
+ need to update the reference, assuming the tarball is always up to
+ date (that doesn't change from before, you need to update the submodule)
+
+2013-04-10 Alex Efros <powerman-asdf@yandex.ru>
+
+ gnome-rr: keep user DPI
+ I'm running startx -dpi 144, but after exiting from spicy's full screen mode Xorg DPI reset to 96. Attached patch fix this issue by keeping user's DPI.
+
+ See also: https://bugs.gentoo.org/show_bug.cgi?id=448362
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=58715
+
+2013-04-10 Tiziano Müller <tiziano.mueller@stepping-stone.ch>
+
+ build: fix parallel install
+ This is a workaround for broken parallel install support in automake
+ with LTLIBRARIES, see http://debbugs.gnu.org/cgi/bugreport.cgi?bug=7328
+
+ Broken parallel install can be reproduced when building with --with-gtk=2.0
+ and dies with:
+ /home/teuf/redhat/spice-gtk/gtk/.libs/libspice-client-gtk-2.0.so: file not recognized: File truncated
+ collect2: error: ld returned 1 exit status
+ libtool: install: error: relink `SpiceClientGtk.la' with the above command before installing it
+ make[5]: *** [install-pyexecLTLIBRARIES] Erreur 1
+ m
+
+2013-04-10 Christophe Fergeau <cfergeau@redhat.com>
+
+ Use a GHashTable for list of file transfer tasks
+ This list is used to lookup tasks by their numerical id, so
+ a hash table is a more appropriate data structure for this kind of
+ uses.
+
+2013-04-10 Hans de Goede <hdegoede@redhat.com>
+
+ spice-common: Update
+
+2013-04-09 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ widget: don't send current configuration back
+ spice-gtk keep the main channel monitor configuration in sync, but
+ shouldn't send back to the remote if disabled, as this may results in
+ different settings, for example if the remote has switched to
+ 16 bits.
+
+ main: add spice_main_update_display()
+ Allow to change locally display resolution without sending it to remote,
+ this is useful to keep local information without bothering the remote.
+
+2013-04-09 Yonit Halperin <yhalperi@redhat.com>
+
+ channel_base: exit handle_migrate when expecting MIGRATE_DATA and receiving something else
+ Previously, when an error occurred on the src server side, and we
+ received other message than MIGRATE_DATA, this messages was forwarded
+ to the dest server, and made it crash.
+
+2013-04-09 Hans de Goede <hdegoede@redhat.com>
+
+ channel-main: Don't g_warn when not finding a file-xfer-id
+ Since the agent channel can have a significant latency, it is possible
+ for a cancel send from the client to the agent and a status message from
+ the agent to cross each other. If this happens then the file-xfer will no
+ longer be on the list.
+
+ Printing a g_warning on this (rare but triggerable) condition will only get
+ us hard to debug bug reports, so turn it into a SPICE_DEBUG.
+
+ channel-main: Cancel active file-xfers on channel/agent disconnect
+
+ channel-main: Check no callbacks are pending on xfer start and end
+ We should never have pending callbacks when we receive a file-xfer start or
+ end (success) message from the agent.
+
+ channel-main: Don't call g_input_stream_close on a NULL stream
+ If we fail to open a file, task->file_stream will be NULL, so we should
+ not call g_input_stream_close on it.
+
+ channel-main: Allow calling file_xfer_close_cb with a NULL object
+ So that it can used for cleanup before we've a file_stream.
+
+ Note this also gets rid of the weird double initialization of the local
+ stream variable.
+
+ channel-main: Don't close the file_stream if callbacks are pending
+ If file_xfer_completed gets called while callbacks are pending we should
+ not call g_input_stream_close_async, because:
+ 1) Doing so while another operation is pending on the file_stream will fail
+ 2) Doing so while a non file_stream callback is pending may result in the
+ task being freed before the callback runs, resulting in a use after free.
+
+ This patch fixes this by setting a pending flag when any callbacks are
+ scheduled, and clearing it when it runs + checking for task->error
+ from all callbacks and if that is set call file_xfer_completed again.
+
+ channel-main: Use file_xfer_completed where appropriate
+
+ channel-main: file_xfer_failed -> file_xfer_completed
+ Make file_xfer_failed usable for all file_stream closing.
+
+ channel-main: Make SpiceFileXferTask-s ref the channel
+ So that the channel sticks around while their callbacks are completing.
+
+ channel-main: Reset agent message receive state on agent stop
+ Discard any partially received messages from the agent on agent stop.
+
+ channel-main: Add a spice_main_channel_reset_agent helper function
+
+ channel-main: Drop bogus xfer_id check from file_xfer_send_start_msg_async
+ xfer_id > UINT32_MAX is never true since xfer_id is an uint32_t, and
+ thus explicit wrapping is not necessary since it will wrap every
+ UINT32_MAX + 1 itereations anyways.
+
+ channel-main: Properly verify result in spice_main_file_copy_finish
+ Call g_simple_async_result_is_valid on the passed in result to verify it is
+ what we expect.
+
+ channel-main: Call g_simple_async_result_is_valid first
+ Call g_simple_async_result_is_valid before using the result.
+
+ Revert "channel-main: Fix dangling references to freed file-xfer-tasks on agent cancel"
+ The fix from commit 19313a133af0d2404b29914b5937219127ad455b is incomplete,
+ this commit added code to file_xfer_close_cb, to remove any reference to
+ the task being closed from the flushing queue.
+
+ But file_xfer_flushed / file_xfer_flush_async execute file_xfer_data_flushed_cb
+ from an idle handler, so it is possible that when file_xfer_close_cb runs and
+ frees the task, it is not part of the flushing queue, but a
+ file_xfer_data_flushed_cb with the task as user_data argument still needs to
+ run, and when it will run it will refer to the now freed task.
+
+ A related problem which is also addressed in this patchset happens when we
+ receive a file-xfer-cancel from the agent when an async operation on the
+ file_stream is pending, since we then cannot call g_input_stream_close_async
+ on it. This is fixed in the patchset by adding a pending flag to the task
+ struct, and the problem with pending flushes is solved in the same way.
+
+ spice-widget: Fix file drag-n-drop mime-type
+ Currently the user can drag-drop text onto the widget, and it will try to
+ open it as a file, not good, this fixes this.
+
+2013-04-05 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ cairo: fix reference leak
+ cairo_surface_finish() doesn't remove the reference,
+ cairo_surface_destroy() does and will call surface_finish().
+
+ Thanks to Uli Schlachter for noticing that in:
+ https://bugs.freedesktop.org/show_bug.cgi?id=61876
+
+2013-04-04 Uri Lublin <uril@redhat.com>
+
+ usb-device-manager: fix log messages to match vid:pid change
+ On Windows clients now USB devices are identified by their vid:pid
+ (sometimes these values are being held by variables "bus" and "addr")
+ Change log messages accordingly.
+
+ usb-device-manager: Windows: identify devices by vid:pid instead of bus.address
+ rhbz#842816
+
+ Sometimes bus.address of a USB device changes upon WinUSB driver installation
+ for that device. This makes bus.address not a good identifier to use when
+ running on Windows machines.
+
+ Instead this patch makes usb-device-manager, when running on a Windows client,
+ identify devices by their vid:pid.
+
+ What changes were made in this patch (in addition to previous patches):
+ - vid:pid are asked from the udev.
+ - match functions that compare vid:pid were added
+ - when comparing devices vid:pid are used.
+
+ This also means that a scenario where two USB devices with the same vid:pid
+ on a Windows client is not supported. However there was a problem with this
+ scenario before as on Windows drivers for (specific) USB devices are
+ installed based on their vid:pid.
+
+ usb-device-manager: Windows: spice_usb_device_equal_libdev: compare vid:pid
+ When comparing spice_usb_device with a libusb_device on Windows clients,
+ use vid:pid instead of bus.address
+
+ It seems that a device bus.address may change when WinUSB driver
+ is being installed.
+
+ usb-device-manager: use a function to get vid:pid from a libusb_device
+ To be reused later.
+
+ Also implemented a get_device_descriptor function (in case it will be
+ needed in the future).
+
+ usb-device-manager: find_libdev: use a match function
+ Instead of comparing directly against <bus, address>.
+
+ In preparation of comparing against vid:pid for Windows clients.
+
+ usb-device-manager: find_device: use a match function
+ Instead of comparing directly against <bus, address>
+
+ In preparation of comparing against vid:pid for Windows clients.
+
+ usb-device-manager: constify spice_usb_device_get_ functions
+
+ win-usb-dev: compare vid:pid instead of bus.addr (Windows)
+ It seems that sometimes, on Win7 clients, bus.addr is changing
+ when WinUSB driver is being installed (e.g. 4.1 -> 4.2).
+
+ So compare vid:pid instead.
+
+ win-usb-dev: make VID and PID available via get_property (Windows)
+
+2013-04-03 Hans de Goede <hdegoede@redhat.com>
+
+ channel-playback/record: Refuse audio-vol-msgs with 0 channels
+ Older servers send these, explicitly warn about this, rather then triggering
+ the following error later:
+
+ (remote-viewer:8726): GSpice-WARNING **: set_sink_input_volume() failed: Invalid argument
+
+2013-04-02 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ win32: do not handle win keys when the keyboard is not grabbed
+ Special-case on win32, filter out the win keys when not having the
+ keyboard grab. This is to avoid the win keys to be received both by
+ the guest and the client, which can be undesirable in general.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=873341
+
+ Release pointer grab on grab-broken
+ On windows, the client receives a WM_KILLFOCUS event which generates
+ solely a keyboard grab-broken event.
+
+ This event is received when pressing ctrl-alt-del (to show up the task
+ manager), and we need to release the pointer grab and clip region in
+ this case for the client to be usable.
+
+ This also clear the clipping region when the client pops-up a dialog.
+
+ Since keyboard focus is a pre-requisite for pointer grab, it sounds
+ logical to release the pointer grab if losing keyboard focus, but for
+ now, we just release it in grab-broken, as a result of discussion on
+ the ML.
+
+ Fixes:
+ https://bugzilla.redhat.com/show_bug.cgi?id=857114
+ https://bugzilla.redhat.com/show_bug.cgi?id=922818
+
+2013-03-29 Hans de Goede <hdegoede@redhat.com>
+
+ channel-main: Don't send empty monitor config on main_init with agent
+ Currently we send a monitor-config on any agent_start, including sending it if
+ the agent is already started when the main channel connects, but when the main
+ channel gets initialized, the display channels aren't intialized yet, so our
+ monitor config will be empty. Resulting in the Linux agent logging:
+
+ spice-vdagent[1285]: err: client sent config with all monitors disabled
+
+ This patch fixing this by only sending our monitor-config to the agent when
+ it (re)starts later on.
+
+2013-03-29 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ main: copy the right nth monitor config
+ i is our counter for c->display[]
+
+2013-03-27 Christophe Fergeau <cfergeau@redhat.com>
+
+ Keep GSocketConnection around after initial connect
+ There has been reports of recent spice-gtk versions not working on
+ RHEL6 or Ubuntu 10.04. This happens because these systems have
+ an older glib version without:
+
+ commit a0e1b226a21ca498b301981b0c89e89ad9a31eb1
+ Author: Dan Winship <danw@gnome.org>
+ Date: Fri Apr 23 08:47:18 2010 -0400
+
+ GSocketConnection: don't close the socket if it's still reffed
+
+ When disposing a GSocketConnection, don't explicitly close the
+ underlying GSocket. The GSocket will close itself if it gets
+ destroyed, and if it doesn't get destroyed, that presumably means the
+ app still wants to use it. Eg, this lets you use GSocketClient to
+ create a GSocketConnection, and then take the GSocket and destroy the
+ GSocketConnection.
+
+ https://bugzilla.gnome.org/show_bug.cgi?id=616855
+
+ and spice-gtk commit 0f9a432c "session: allow to connect via HTTP CONNECT
+ proxy" changed spice_session_channel_open_host to get its socket by doing:
+
+ open_host->socket = g_socket_connection_get_socket(connection);
+ g_object_ref(open_host->socket);
+ g_object_unref(connection);
+ (see socket_client_connect_ready)
+
+ If glib does not have the commit mentioned above, then this won't
+ work as expected as open_host->socket will get closed when 'connection'
+ gets destroyed.
+
+ This commit changes spice_session_channel_open_host to return a
+ GSocketConnection rather than a GSocket so that we can keep the
+ socket open even on older glib versions.
+
+ Huge thanks go to Brad Campbell <brad@fnarfbargle.com> for doing all the
+ spice-gtk/glib bisecting work.
+
+2013-03-27 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Be less verbose about monitor config
+
+2013-03-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: copy proxy setting
+ Solve migration falling back to switch-host method when using proxy
+ set through controller:
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=923894
+
+2013-03-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk-session: remove clipboard timeout
+ A large clipboard may take longer than 7s on slow networks. Since the
+ Gtk+ API forces us to use an inner main-loop, exit it asap, if agent
+ is disconnected for instance.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=752483
+
+ main: warn if receiving message from disconnected agent
+
+ main: only notify on agent status change
+
+2013-03-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ controller: don't try to set integrity on XP x64 edition
+ XP x64 uses version 5.2, but doesn't accept setting the pipe to low
+ integrity.
+
+ 5.2 seems to be shared with many versions (server 2003 for example),
+ but only Vista+ matters, which is only major >=6.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=918342
+
+2013-03-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Notify of monitors when not using MonitorConfig
+ Windows guest don't use MonitorConfig, but we may want to notify the
+ client of the number of monitors.
+
+ Related to: https://bugzilla.redhat.com/show_bug.cgi?id=919530
+
+ Update current resolution when agent is started
+ This ensures we have the requested resolution whenever possible.
+
+2013-03-15 Hans de Goede <hdegoede@redhat.com>
+
+ spice-widget: Reconfiguring the grab is only needed on win32
+ Commit 8a7e72e3 "widget: regrab when widget is reconfigured" adds an
+ ungrab + grab call to the configure event handling code. Because:
+ "On Windows, we need to update the cursor clip. Call ungrab&grab to update it."
+
+ But on X11 this is not needed, see man XGrabPointer, which explains that
+ the grab automatically adjusts to window resizing.
+
+ Not only is it not needed it is also racy, causing spice-gtk based
+ apps to log messages like:
+ (remote-viewer:9935): GSpice-WARNING **: pointer grab failed 3
+
+ This patch fixes this by disabling the ungrab + re-grab on non-win32.
+
+ spice-widget: Fix auto-grab on window size change
+ Commit 8a7e72e3 "widget: regrab when widget is reconfigured" adds an
+ ungrab + grab call to the configure event handling code. But it does this
+ without checking if the mouse is grabbed at all, causing an unsolicited
+ grab in certain scenarios, ie:
+
+ 1) User boots a vm
+ 2) Connects with remote-viewer
+ 3) Goes and do some web-browsing while the vm boots
+ 4) Mouse happens to hover over the remote-viewer window
+ 5) Guests changes resolution (ie X starts)
+ 6) The mouse is grabbed, and when the user tries to move it to
+ click something in his web-browser this does not work.
+
+ This patch fixes this by checking that the mouse is grabbed before doing
+ the ungrab + re-grab which is needed to reconfigure the grab to the new window
+ size / location.
+
+ spice-widget: Ignore duplicate configure events
+ gtk seems to be sending us identical / repeated configure events quite
+ regularly (atleast under X11), we don't care about re-configures with the
+ same size + coordinates, so filter these out.
+
+ Note this patch uses the SpiceDisplayPrivate mx and my members which
+ were already defined to store the window position, but not yet used.
+
+2013-03-11 Dunrong Huang <riegamaths@gmail.com>
+
+ spice-channel: Do not segfault fault if peer_msg was a NULL pointer
+ $ remote-viewer spice://192.168.0.233:111 # 111 is not a valid spice port
+ (remote-viewer:29381): GSpice-WARNING **: incomplete link header (-104/16)
+ Segmentation fault (core dumped)
+
+ $ gdb /usr/bin/remote-viewer core
+ [Thread debugging using libthread_db enabled]
+ Using host libthread_db library "/lib64/libthread_db.so.1".
+ Core was generated by `remote-viewer spice://192.168.0.233:111'.
+ Program terminated with signal 11, Segmentation fault.
+ switch_tls=0x7f9eb6855b88) at spice-channel.c:1675
+
+ warning: Source file is more recent than executable.
+ 1675 switch (c->peer_msg->error) {
+ (gdb) bt
+ switch_tls=0x7f9eb6855b88) at spice-channel.c:1675
+ at spice-channel.c:2299
+ at coroutine_ucontext.c:58
+ at continuation.c:49
+
+ c->peer_msg->error was accessed without checking the validity of pointer in
+ spice_channel_recv_link_msg(). Actually, c->peer_msg may be a NULL pointer if
+ we got a error in spice_channel_recv_link_hdr().
+
+ This patch fixes this error.
+
+2013-03-05 Christophe Fergeau <cfergeau@redhat.com>
+
+ usb: Remove device from ::devices before emitting device-removed
+ The code is currently removing the USB device that is gone from
+ the SpiceUsbDeviceManager::devices array after the device-removed
+ signal has been emitted. As signal handlers are called synchronously,
+ this means that the list returned by
+ spice_usb_device_manager_get_devices() will still contain the
+ removed device if it's called from the signal handler.
+
+2013-03-04 Hans de Goede <hdegoede@redhat.com>
+
+ channel-main: Handle the new VD_AGENT_FILE_XFER_STATUS_SUCCESS status msg
+ So that we can pass along an error from the agent to report an xfer error
+ after the last FILE_XFER_DATA message has been sent.
+
+ Update spice-common
+
+ channel-main: Send an error to the agent on file-xfer read error
+ So that the agent knows the rest of the file won't be coming.
+
+ channel-main: Fix dangling references to freed file-xfer-tasks on agent cancel
+ While testing the agent error handling code I was triggering the
+ agent-file-xfer-cancel code-path in spice-gtk. This crashes due to the
+ flushing queue still having a reference to the task in question when its
+ gets cancelled from the agent side. This fixes this.
+
+2013-02-28 Christophe Fergeau <cfergeau@redhat.com>
+
+ Add fallback for g_key_file_set_uint64
+ This was only added in glib 2.26
+
+ Don't try to call _wocky_http_proxy_get_type with old gio
+ Proxy support is only built when gio is newer than 2.26, don't try
+ to call symbols from wocky-http.c with older glib as this would
+ result in link failures.
+
+2013-02-26 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ smartcard: do not register monitor before smartcard init
+ Never call vevent_get_next_vevent() before calling vcard_emul_init()
+
+ Some mutexes are initialized in vevent_queue_init(), during emul_init()
+
+ smartcard: trivial cleanup
+
+ session: warn on invalid port value
+
+2013-02-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ channel: swap tls status during seamless migration
+ In some cases, source and destinations may have different channel
+ encryption. We need to swap tls state too during seamless migration.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=855870
+
+2013-02-19 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ main: use stable comparison function for monitors
+ If monitors are equal, compare them by their addresses, to get the
+ effect of a stable sort.
+
+ main: use glib sort
+ Use glib sort for monitors. This allows to share the same
+ implementation and behaviour on various platforms.
+
+2013-02-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release v0.18
+ v0.18
+ =====
+
+ - Build fix with Gtk+ unstable.
+ - MinGW build fixes with old headers
+ - Fixes rhbz#908057
+
+2013-02-12 Hans de Goede <hdegoede@redhat.com>
+
+ usb-device-manager: Fix coldplug race
+ It is possible for us to see a device show up twice, if it gets plugged
+ in between us starting listening for new devices and doing "coldplug", then
+ it will get added once from the coldplug code, and then again from from
+ the hotplug code path. We already have code checking for this, but the check
+ is only compiled in under Windows -> Remove the #ifdef to also catch this
+ under Linux.
+
+2013-02-08 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ display: keep monitor config updated if resize-guest is disabled
+ https://bugzilla.redhat.com/show_bug.cgi?id=908057
+
+ Update spice-common
+
+2013-02-07 Uri Lublin <uril@redhat.com>
+
+ mingw: spice-widget: make sure MAPVK_VK_TO_VSC is defined
+ MAPVK_VK_TO_VSC is defined in the file:
+ <path-to-mingw-sys-root>/mingw/include/winuser.h
+
+ In older mingw-headers the definition of MAPVK_VK_TO_VSC is
+ defined only -- #if _WIN32_WINNT >= 0x0601
+
+2013-02-06 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: don't use -Wstrict-prototypes with Gtk+ 2.0
+
+ build-sys: remove GTK_DISABLE_DEPRECATED
+ Gtk 3.0 no longer includes deprecated headers if it's defined:
+ http://git.gnome.org/browse/gtk+/commit/?id=a1de67f438f057711353a55b322babce7044226f
+
+ We added it as a workaround for Gtk 2.0 build issue.
+
+ build-sys: bump spice-glib version-info
+ spice-glib version-info should have been bumped, since we have new
+ symbols.
+
+ 249dd73132a7ecc1ceb32b4fea6529491ca219d3
+
+ Release v0.17
+ v0.17
+ =====
+
+ - Update spice-common with fedora 875348, 826036 fixes
+ - Multi-monitor fixes (avoid monitor order shuffling, fix mouse offset
+ if monitor 0 is not at +0+0 and let agent do monitor offset)
+ - Add support for VD_AGENT_CAP_SPARSE_MONITORS_CONFIG
+ - Add controller & session "proxy" properties
+ - Add drag and drop file copy support to send file to guest, you will
+ need capable agent to use that feature. Adds spice_main_file_copy_async()
+ - Introspection fixes
+ - Build fixes
+
+ spice-proxy: explicitely mark as internal
+
+2013-02-06 Hans de Goede <hdegoede@redhat.com>
+
+ widget: Fix mouse position reporting for multiple monitors on 1 display channel
+ VDAgentMouseState contains a display_id and expects coordinates in multi-mon
+ mode to be relative to the origin of the monitor specified by the display_id.
+
+ The agent will then adjust the mouse coordinates for the position of the
+ monitor as configured in the guest.
+
+ In multiple monitors on 1 display channel spice-gtk is wrongly setting
+ display_id to the channel_id (which is 0 for all monitors), and is working
+ around the problems this causes by doing the adjustment of the mouse position
+ itself.
+
+ But the agent is still applying the correction for the monitor position to
+ all VDAgentMouseState messages it gets, and since for all monitors a display_id
+ of 0 is reported it always uses the position of display 0 for the correction.
+
+ Since the position of display 0 is usally +0+0 this usually works, but as soon
+ as the position of display 0 is not +0+0, the correction will get done twice
+ for display 0, and the display 0 position will wrongly get added the mouse
+ position for other displays.
+
+ This patch fixes this by properly setting display_id, and removing the
+ modification of the mouse coordinates as that is already done in the agent.
+
+2013-02-04 Natanael Copa <ncopa@alpinelinux.org>
+
+ build: fix for automake-1.13
+ Use AC_CONFIG_HEADER instead of deprecated AM_CONFIG_HEADER.
+
+2013-02-01 Yonit Halperin <yhalperi@redhat.com>
+
+ update spice-common submodule
+ obtaining a fix related to palettes caching (fedora 875348, 826036)
+
+2013-01-30 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ controller: add proxy property
+
+2013-01-29 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: clear SpiceSession:proxy also if SPICE_PROXY is NULL
+
+ Add SpiceSession:proxy
+ Add a session property to set proxy setting, since it is racy to rely
+ on setenv(). Also doing so would override system environment, which
+ will modify other session too sharing the same process.
+
+ proxy: initialize proxy at session construct time
+
+2013-01-28 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix a bunch of gtkdoc/giscan warnings
+
+ Update spice-common
+
+ session: simplify a little bit open_host_idle_cb
+ open_host->error is only set if we try to use a proxy. Let´s make that
+ more clear.
+
+2013-01-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: generate THANKS at dist time
+
+2013-01-22 Jasper Lievisse Adriaanse <jasper@humppa.nl>
+
+ build-sys: Use a portable variable assignment in configure.ac
+
+2013-01-21 Jasper Lievisse Adriaanse <jasper@humppa.nl>
+
+ build-sys: missing sys/types.h in gtk/channel-display.c
+
+2013-01-18 Hans de Goede <hdegoede@redhat.com>
+
+ channel-main: Fix monitors_align to not shuffle monitor order
+ Before this patch monitor_align was calling qsort directly on the
+ VDAgentMonConfig monitors array, but VDAgentMonConfig does not contain
+ an id, so the order matters!
+
+ This fixes (for example) 2 issues with having 3 windows/monitors on a row
+ numbered 1-3, ordered left-to-right as 1-2-3, and then changing the
+ ordering to 1-3-2:
+ 1) Window 3 would be resized to the size of window 2, and window 2 would
+ get resized to the size of window 3.
+ 2) Dragging a window on monitor 1 over its right edge, makes the part over
+ the edge show up on the right monitor, rather then on the middle.
+ This is happening because the agent is configuring qxl-1 (which is monitor 2)
+ with the monitors[1] data, which after the qsort contains the size and
+ coordinates of monitor 3.
+
+ Note this only happens with virt-viewer fixed to properly send window
+ coordinates, as before that all monitors had x and y set to 0 making the
+ sort a nop.
+
+ channel-main: Add support for VD_AGENT_CAP_SPARSE_MONITORS_CONFIG (rhbz#881072)
+
+ spice-widget: update_monitor_area: Fix memory-leak on whole fallback
+ When we've successfully gotten the monitors display-channel property, but
+ still end up falling back to whole-display mode, we still need to free
+ the monitors array.
+
+ spice-widget: Search monitor info by display monitor-id
+ As discussed indexing the display-channel's monitors property by monitor-id
+ causes problems with the vdagent's new sparse monitor config support.
+
+ Searching the monitors property by monitor-id avoids these problems.
+
+2013-01-17 Andrew Hughes <gnu.andrew@redhat.com>
+
+ build-sys: fix out-of-tree build with vala
+
+2013-01-16 Cole Robinson <crobinso@redhat.com>
+
+ Fix introspection for send_keys
+ Without this I can't find a usable way to call this API with the
+ introspected python bindings.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=59444
+
+2013-01-14 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: avoid use gtk+ 3.0 only API
+
+2013-01-12 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ file-xfer: always take error if set in xfer_read_cb()
+
+ file-xfer: use file_xfer_..() prefix for all internal copy functions
+
+ file-xfer: move file_close_cb() above all to ease reading
+
+ file-xfer: try to report any error from file_info_async_cb()
+
+ file-xfer: non-programming errors should be reported in async
+ It is fine to not return async errors for programming errors via
+ g_return_if_fail() and friends, however, we need to return proper
+ error if it's a normal run-time error.
+
+ file-xfer: avoid g_alloca() usage when possible
+
+2013-01-12 Dunrong Huang <riegamaths@gmail.com>
+
+ file-xfer: handle "drag-data-received" signal
+ When user drags a file to SpiceDisplay and drops it, a signal named
+ "drag-data-received" will be emitted, the signal will be received by
+ SpiceDisplay, then our signal handler should receive data which contains
+ file path, and call spice_main_file_copy_async() to transfer file to guest.
+
+ file-xfer: disable file-xfer when agent is not connected
+
+ file-xfer: handling various transfer messages in main channel
+ This patch is aimed to handle various file xfer messages.
+
+ How it works:
+ 0) our main channel introduces a API spice_main_file_copy_async().
+
+ 1) When user drags a file and drop to spice client, spice client will
+ catch a signal "drag-data-received", then it should call
+ spice_main_file_copy_async() for transfering file to guest.
+
+ 2) In main channel: when spice_main_file_copy_async() get called with file
+ list passed, the API will send a start message which includes file
+ and other needed information for each file. Then it will create a
+ new xfer task and insert task list for each file, and return to caller.
+
+ 3) According to the response message sent from guest, our main channel
+ decides whether send more data, or cancel this xfer task.
+
+ 4) When file transfer has finished, file xfer task will be removed from
+ task list.
+
+2013-01-12 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release v0.16
+ v0.16
+ =====
+
+ - Fix crash with SSL connection (#890464)
+ - Send monitor config to the agent on spice_main_set_display_enabled() (#881072)
+ - Fix channel leak and wrong condition in spice_channel_flush()
+ - Build fixes
+
+2013-01-11 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ spice-channel: fix state condition check in flush()
+
+ spice-channel: plug a channel ref leak
+
+2013-01-09 Hans de Goede <hdegoede@redhat.com>
+
+ Send monitor config to the agent on spice_main_set_display_enabled (#881072)
+ Currently we send an updated monitor-config to the agent whenever some
+ of the display settings are changed (whenever spice_main_set_display is
+ called), including when a new display is enabled, as that involves
+ creating a new window, which calls spice_main_set_display. The only
+ exception to this is when a display gets disabled.
+
+ This is rather inconistent, it causes the user to be able to move windows
+ in the guest to the now no longer visible monitor, and any windows which
+ were already there are hidden... until something else triggers us sending
+ updated monitor info. Withe gnome3 an alt-tab away and back again from a still
+ open display-window is enough to trigger the update, and then the guest will
+ all of a sudden become aware of the monitor no longer being there and
+ re-arrange windows accordingly, on an alt-tab in the client machine ...
+ not pretty.
+
+ So lets make things consistent and also send the agent updated monitor info
+ from spice_main_set_display_enabled, like we already do from
+ spice_main_set_display.
+
+2012-12-27 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix switching to TLS regression
+ The commit fcbbc248a8f885f9a9a6e7c47d7aae0c1ab3cd1b changed the way a
+ channel coroutine is exiting. In particular, it was going through the
+ coroutine main cleanup (finishing in main coroutine) while switching
+ to TLS is recycling the channel. That part of the code is a bit
+ difficult to grasp, but with this refactoring, I think it makes it
+ easier to understand the reconnection.
+
+ Clean-up idle handler when leaving the open_host_idle()
+ An explicit yield back to the channel coroutine when the idle function
+ is still pending will leave it in the background, referencing objects
+ that may no longer exist. Make sure we remove it when
+ channel_open_host() is resumed.
+
+2012-12-21 Christophe Fergeau <cfergeau@redhat.com>
+
+ mingw: Fix link errors
+ Without this patch build fails with:
+
+ CCLD libspice-client-glib-2.0.la
+ .libs/spice-channel.o: In function `spice_channel_coroutine':
+ /home/teuf/redhat/spice-gtk/gtk/spice-channel.c:2287: undefined reference to `_imp__setsockopt@20'
+ .libs/channel-display.o: In function `create_compatible_dc':
+ /home/teuf/redhat/spice-gtk/gtk/channel-display.c:672: undefined reference to `_imp__CreateCompatibleDC@4'
+ ../spice-common/common/.libs/libspice-common.a(canvas_utils.o): In function `release_data':
+ /home/teuf/redhat/spice-gtk/spice-common/common/canvas_utils.c:41: undefined reference to `_imp__DeleteObject@4'
+ ../spice-common/common/.libs/libspice-common.a(canvas_utils.o): In function `surface_create':
+ /home/teuf/redhat/spice-gtk/spice-common/common/canvas_utils.c:192: undefined reference to `_imp__CreateDIBSection@24'
+ /home/teuf/redhat/spice-gtk/spice-common/common/canvas_utils.c:208: undefined reference to `_imp__DeleteObject@4'
+ ../spice-common/common/.libs/libspice-common.a(ssl_verify.o): In function `inet_aton':
+ /home/teuf/redhat/spice-gtk/spice-common/common/ssl_verify.c:38: undefined reference to `_imp__inet_addr@4'
+ ../spice-common/common/.libs/libspice-common.a(ssl_verify.o): In function `verify_hostname':
+ /home/teuf/redhat/spice-gtk/spice-common/common/ssl_verify.c:216: undefined reference to `_imp__inet_ntoa@4'
+ collect2: error: ld returned 1 exit status
+
+2012-12-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release v0.15
+ v0.15
+ =====
+
+ - Add HTTP Proxy support (only with glib >= 2.26)
+ - Add "port" channel support, to allow arbitrary communication on top
+ of spice connection
+ - usb-redir: fix migration support
+ - win32: various keyboard & mouse fixes
+ - Add info message when USB dialog is empty
+ - Fix initial black screen on some 16bits guest
+ - Various bug fixes and improvements
+
+ build-sys: update sym-files
+
+ session: improve open_host() clean-up
+ Make sure the GSocketClient is unref when leaving the function, and
+ not left around in some unfinished async state.
+
+ session: do not unref() NULL connection
+ #3 0x00007ffff59cfb3b in g_object_unref (_object=0x0) at gobject.c:2916
+ #4 0x00007ffff6ea9c20 in socket_client_connect_ready (source_object=0x87ced0,
+ result=0x8a58f0, data=0x7fffe3fffa80) at spice-session.c:1606
+ #5 0x00007ffff5ea1278 in g_task_return_now (task=0x8a58f0) at gtask.c:1102
+
+2012-12-21 Hans de Goede <hdegoede@redhat.com>
+
+ acl-helper policykit policy: Allow redir by default for console users
+ This makes usb-redir a lot more userfriendly to use. This has been
+ discussed with the security team and they are ok with it, rationale:
+
+ Since we only set <allow_active> to yes, we only give raw usb access
+ to users *physically present behind the machine*. This is ok since
+ they already have full control over usb devices anyways, they can
+ always just unplug the device and put it in a user controlled machine.
+
+ This follows how we already grant a great deal of access to users
+ *physically present behind the machine* including dangerous things like
+ /dev/sg access for cd/dvd writers. And raw usb access to all devices which
+ happen to have a userspace driver rather then an in kernel driver.
+
+ Also the opening up is limited compared to the existing opening up of
+ other devices listed above in that:
+
+ 1) It will only happen on machines which have spice-glib installed
+ 2) We are not opening up the device nodes rights automatically, as an udev rule
+ would do. So there is no chance that any random app can start (accidentally)
+ poking the devices.
+
+2012-12-19 Hans de Goede <hdegoede@redhat.com>
+
+ spicy: Fix compilation breaking due to a compiler warning
+ This fixes:
+ spicy.c:1711:10: error: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Werror=unused-result]
+
+2012-12-17 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ controller: fix new vala warnings
+ send_msg() is done in background, use .begin
+
+ controller.vala:62.3-62.10: warning: implicit .begin is deprecated
+ foreign-menu.vala:44.3-44.10: warning: implicit .begin is deprecated
+ foreign-menu.vala:59.3-59.10: warning: implicit .begin is deprecated
+ foreign-menu.vala:70.3-70.10: warning: implicit .begin is deprecated
+ Compilation succeeded - 4 warning(s)
+
+ channel: switch to protocol 1 on error during link-time
+ The Spice server doesn't wait until all the data are received by the
+ remote before closing the socket (that would need SO_LINGER?). Under
+ some racy conditions, the client may not have received the link reply
+ indicating the server protocol version mismatch, which would trigger
+ reconnection with compatible protocol.
+
+ It seems to happen on local networks with Windows sockets (error
+ WSAECONNRESET). To workaround that issue, spice-gtk can try to
+ reconnect with protocol 1 when a socket error is encoutered during
+ link-time.
+
+ Fixes:
+ https://bugzilla.redhat.com/show_bug.cgi?id=874698
+
+2012-12-14 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: allow to connect via HTTP CONNECT proxy
+ Allow to connect to a Spice server via a HTTP proxy with CONNECT
+ method. spice-gtk will use the SPICE_PROXY environment variable, which
+ can currently only have the following syntax: [http://]hostname[:port]
+
+ This is paving the way to more proxies support (socks4/socks5).
+
+ This code is now entirely sync (it was not even completely async), the
+ following patch will make it all async again.
+
+ Tested with Squid, locally only.
+
+ Add SpiceProxy object
+ Add a simple object to handle the SPICE_PROXY values.
+
+ It's not clear to me whether each GIO user needs to handle the proxy
+ configuration, or if there is a more global mechanism (via
+ g_network_address_parse_uri())
+
+ Also, the parsing is currently very limited and only support basic
+ HTTP proxy URI. In the future, we really want to rely on GUri or
+ similar instead...
+
+ Add wocky HTTP proxy
+ Courtesy of Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+
+ It might make sense to include this proxy in glib/gio, but it is still
+ missing some features according to its author, namely SSL and perhaps
+ better CRLF.
+
+ spice-channel: remove unnecessary g_socket_close()
+
+ spice-channel: plug a small memory leak
+
+2012-12-10 Uri Lublin <uril@redhat.com>
+
+ gtk/channel-port: include glib-compat for g_clear_pointer
+
+ glib-compat: add g_slist_free_full
+
+ channel-display: add more protection against bad access to streams
+
+2012-12-07 Dunrong Huang <riegamaths@gmail.com>
+
+ spice-widget: Fix rendering issue with X11 backend enabled
+ commit 5ec6e4d fixes a rendering issue on win32 platform, but raises another
+ bug on linux platform.
+
+ If X11 backend is enabled, app window will becomes while screen when draging it.
+ This bug can be reproduced easily:
+ compile spice-gtk using:
+ $ ./configure --with-gtk=2.0 --with-x11
+ $ make
+ $ gtk/spicy -h host -p port
+
+2012-12-05 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ channel: rely on couroutine instead of channel state
+ We can simplify the channel state callback and simplify a little
+ the code by relying on coroutine state instead.
+
+ spicy: demo SpicePort usage
+ spicy has been modified to recognized 2 different port types to play
+ with:
+
+ * org.spice.spicy: will connect the port to the current stdin/stdout,
+ and can be used as a chardev for the qemu monitor
+
+ * org.spice.spicy.break: will send a break event on connect and
+ disconnect immediately (exercice the port event and flush)
+
+ Add a port channel
+ A Spice port channel carry arbitrary data between the Spice client and
+ the Spice server. It may be used to provide additional services on top
+ of a Spice connection. For example, a channel can be associated with
+ the qemu monitor for the client to interact with it, just like any
+ qemu chardev. Or it may be used with various protocols, such as the
+ Spice Controller.
+
+ A port kind is identified simply by a fqdn, such as org.qemu.monitor,
+ org.spice.spicy.test or org.ovirt.controller...
+
+ channel: add flush_async()
+ Add spice_channel_flush_async() that asynchronously will write all the
+ pending channel data.
+
+ update spice-common
+
+2012-11-30 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ channel: make spice_msg_out_send() slightly easier to read
+ Avoid the obfuscating many -> indirection by using the
+ SpiceChannelPrivate *c variable.
+
+2012-11-27 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ win32: fix rendering issue when widget is partially off screen
+ Gtk+ in win32 has a rendering bug with window non-buffered:
+ https://bugzilla.gnome.org/show_bug.cgi?id=688962
+
+ According to Alex Larsson, this shouldn't affect performance much,
+ since there is already extra-copy done for offscreen buffers, and
+ might even make it faster in gtk+ 3.0...
+
+ Fixes:
+ https://bugzilla.redhat.com/show_bug.cgi?id=874482
+
+2012-11-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ channel: learn to load certificate from memory
+ Sadly, OpenSSL doesn't provide a way to load certificate from memory,
+ but all the functions necessary to do so are actually public, so we
+ can implement our own version and avoid files, how awesome!
+
+ Add SpiceSession:ca property
+
+2012-11-19 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ win32: translate virtual-key code to scancode via MapVirtualKey
+ Local client keyboard layout shouldn't affect hardware scancode sent
+ to guest, so that guest keyboard layout configuration can map it
+ properly.
+
+ Unfortunately, the Win32 GdkEventKey.hardware_keycode isn't a hardware
+ scancode, but the Windows virtual-key code. We could modify Gdk to
+ return the scancode (available in MSG.lParam or via global hook), but
+ that would mean some Gdk breakage, or some unnecessary complexity.
+ Instead, we can rely on MapVirtualKey(), which translates the
+ vitual-key code into a scan code using current keyboard layout.
+
+ This solves the following bug:
+ https://bugzilla.redhat.com/show_bug.cgi?id=871125
+
+2012-11-18 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ win32: track current window handle
+ We need current window handle for the global keyboard hook. It is not
+ enough to rely on focus-in event to set it, so do it also in
+ key-event. This avoids extra warnings on Windows.
+
+2012-11-14 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ win32: clip and move cursor within window region
+ Windows grab do not exist like on X11, so we need to clip the cursor
+ to our client window, while making sure it doesn't overlap with
+ windows statusbar. When wrapping the cursor, we need to make sure we
+ also stay within the clip region, or else the clip is inverted
+ (pointer can't enter the clip region anymore), and we also lose the
+ keyboard hook/grab.
+
+ The end result works better than spicec, which didn't exclude the
+ Windows statusbar, and was subject to losing pointer when wrapping
+ mouse over it.
+
+ Another approach I have been playing with is to clip the cursor, and
+ process raw input messages, this will have the advantage to work even
+ when the client is completely out of the working area (under the
+ statusbar for example), but the complexity involved is too high for
+ very poor benefit (interacting with a non-visible client), we could
+ even argue that the behaviour implemented by this patch is more
+ correct (it refuses to grab the cursor if the client isn't visible in
+ the working area).
+
+ v2:
+ - choose the nearest monitor for clipping
+ - the ClipRegion is in Windows coordinate, we can't use gdk warp
+ - fix https://bugzilla.redhat.com/show_bug.cgi?id=872640
+
+ This solves the following bugs:
+ https://bugzilla.redhat.com/show_bug.cgi?id=857430
+ https://bugzilla.redhat.com/show_bug.cgi?id=857389
+
+2012-11-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ widget: regrab when widget is reconfigured
+ On Windows, we need to update the cursor clip. Call ungrab&grab to update it.
+
+ widget: don't redraw server mouse until moved
+ When switching between client mode and server mode, the pointer is
+ being invalidated on each display and the cursor will end up being
+ drawn on both. Since there is no information on which display the
+ cursor is supposed to be until a move is received, hide the cursor
+ until it actually moves.
+
+2012-10-25 Uri Lublin <uril@redhat.com>
+
+ win-usb-driver: use usbclerk new message: USB_CLERK_DRIVER_SESSION_INSTALL
+ With this message usbclerk keeps a list of devices for which
+ a libusb driver was installed (per connection).
+ When a spice-gtk client exits, the connection is closed, and
+ usbclerk uninstalls the driver for all devices in the list.
+
+ That means we need to keep the connection open, so added
+ the win-usb driver installer to usb-device-manager's priv.
+
+ This prevents the case were the user exits the client, while a usb
+ device is connected to the guest, and can not use the device from
+ the client machine.
+
+ rhbz#869542
+
+2012-10-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ controller/win32: limit access to current user only
+ Based on RHEV spicec-win only code.
+
+ controller/win32: allow ActiveX connection on untrusted website
+ Set low integrity on named-pipes.
+
+ This bug was originally resolved as:
+ https://bugzilla.redhat.com/show_bug.cgi?id=668980
+
+ Fixes regression:
+ https://bugzilla.redhat.com/show_bug.cgi?id=844461
+
+2012-10-24 Uri Lublin <uril@redhat.com>
+
+ spice-gtk: controller: log messages received from a controller
+
+2012-10-23 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ win32: implement disabling mouse accel
+ https://bugzilla.redhat.com/show_bug.cgi?id=867885
+
+ move mouse acceleration code in a seperate function
+
+ Fix disabling mouse acceleration on X11
+ It turns out the acceleration code didn't work, because we didn't set
+ it to the default values. Then we need to restore it back. Eventually,
+ it would be nicer to inhibit gnome-settings-daemon to apply devices
+ changes, and restore settings when un-inhibiting.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=867885
+
+2012-10-19 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Empty host subject from qemu should only validate hostname
+ Validate empty host subject from qemu exactly like when no explicit
+ host subject is specified.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=858228
+
+ channel: improve debugging message
+ The open_host() can return FALSE when the connection is discarded or
+ skipped. Improve the message to not indicate a failure.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=858232
+
+ Print list of supported channels
+ https://bugzilla.redhat.com/show_bug.cgi?id=834513
+
+2012-10-18 Hans de Goede <hdegoede@redhat.com>
+
+ channel-inputs: Fix sending 00 scancodes to guests with scancode cap
+ The code for handling single key up / down events in spice-server is:
+ SpiceMsgcKeyDown *key_down = (SpiceMsgcKeyDown *)buf;
+ uint8_t *now = (uint8_t *)&key_down->code;
+ uint8_t *end = now + sizeof(key_down->code);
+ for (; now < end && *now; now++) {
+ kbd_push_scan(keyboard, *now);
+ }
+
+ Notice the *now, which makes sure that no scancodes with the value 0 get
+ send! But the new SPICE_MSGC_INPUTS_KEY_SCANCODE in the server does:
+
+ uint8_t *code = (uint8_t *)buf;
+ for (i = 0; i < size; i++) {
+ kbd_push_scan(keyboard, code[i]);
+ }
+
+ And thus will push any 0 bytes in the buffer. Resulting in these message
+ in the guest:
+
+ atkbd serio0: Unknown key pressed (translated set 2, code 0x0 on isa0060/serio0).
+ atkbd serio0: Use 'setkeycodes 00 <keycode>' to make it known.
+
+ Rather then making the server skip 0 bytes I believe it is better to just
+ make spice-gtk not send these in the first place, which is what this patch
+ does.
+
+2012-10-17 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ win32: implement sync_keyboard_lock_modifiers()
+ Fix numlock numerical keypad being broken:
+ https://bugzilla.redhat.com/show_bug.cgi?id=856538
+
+ spicy: show the correct ungrab key combination
+ The gtk accelerator for ungrab is useless, since it has to be handled
+ by the spice widget only. It could be useful to still show the ungrab
+ key sequence in the menu (for help), but unfortunately, spice-gtk grab
+ sequence syntax is not the same as gtk accelerator syntax, and that
+ would be needlessly complicated to handle.
+
+ Also correctly show the configured sequence in the status bar when the
+ widget has the grab.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=851090
+
+2012-10-16 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ widget: apply color conversion when creating image
+ The color conversion only happened during "invalidate", but we also
+ need to apply it when the image is created in the first place.
+
+ This solves initial screen being black after connection to agent-less
+ guest with 16b colour depth:
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=843134
+
+2012-10-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ win32: ignore hardware keycode 255
+ It's a reserved value, and it doesn't have a valid scancode
+ translation. Currently, We hit a warning in the delayed key handling
+ later.
+
+ vnc keymap: fix incorrect table size
+ This lead to out of bound array access
+
+ Add a warning if scancode lookup failed
+ This helps tracking some send_keys() issues, such as
+ https://bugzilla.gnome.org/show_bug.cgi?id=686170
+
+ win32: fix quote key handling
+ Fix keymaps to correctly handle the quote key.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=856317
+
+2012-10-11 Hans de Goede <hdegoede@redhat.com>
+
+ Add spice-usbredir-filter alias for spice-usbredir-auto-redirect-filter (v2)
+ For commandline backward compatibility with older spice-gtk versions.
+
+ Changes in v2:
+ -warn about spice-usbredir-filter being deprecated when it gets used
+
+ UsbDeviceManager: Don't warn on EINTR
+
+ UsbDeviceManager: Hookup redirect-on-connect property
+
+ UsbDeviceManager: Build channel list after building the device list
+ This is necessary for redirect-on-connect
+
+ UsbDeviceManager: Add a redirect-on-connect property
+
+ Rename spice-usbredir-filter option to spice-usbredir-auto-redirect-filter
+ The spice-usbredir-filter cmdline option was not chosen well, as it does
+ not indicate what it filters. Now that we are also getting a filter for
+ selecting already plugged in devices to redirect when a spice connection gets
+ established, it needs to be renamed to make its function more clear.
+
+2012-10-09 Hans de Goede <hdegoede@redhat.com>
+
+ usb-redir: Fix read error handling depending on SpiceUsbDevice == libusb_device
+ This has not been true for a while now, but since getting an error return
+ from usbredirhost_read_guest_data() is rare no one has tripped over this
+ sofar.
+
+2012-10-08 Hans de Goede <hdegoede@redhat.com>
+
+ channel-usbredir: Properly reset state from reset callback
+ This is necessary to be able to use the usbredir channel after a
+ non seamless migration.
+
+ Set channel state before calling channel_reset
+ This way functions called from the channel_reset function can rely
+ on state accurately reflecting the state. This is necessary to stop
+ channel-usbredir's reset callback from trying to send the initial
+ hello message while the channel is no longer in a connected state.
+
+2012-10-03 Christophe Fergeau <cfergeau@redhat.com>
+
+ Update spice-glib-sym-file for new symbol
+
+2012-10-01 Christophe Fergeau <cfergeau@redhat.com>
+
+ usb: Add info message when USB dialog is empty
+ From rh bug #804187:
+ « The redirection dialog can feel a bit strange when there is no device to
+ redirect.
+
+ It could be useful to provide a help message indicating that there is no
+ device to redirect yet, and that the user can insert a USB device to
+ redirect, and some related guidance. »
+
+ This commit adds a "No USB devices detected" infobar in the USB
+ dialog below the 'Select USB devices to redirect" label.
+ Content could probably be improved, but this is a step in the right
+ direction ;)
+
+ This can be tested with
+ diff --git a/gtk/usb-device-widget.c b/gtk/usb-device-widget.c
+ index b1bf090..660ea03 100644
+ --- a/gtk/usb-device-widget.c
+ +++ b/gtk/usb-device-widget.c
+ @@ -220,6 +220,11 @@ static GObject *spice_usb_device_widget_constructor(
+ G_CALLBACK(device_error_cb), self);
+
+ devices = spice_usb_device_manager_get_devices(priv->manager);
+ + if (devices) {
+ + g_ptr_array_unref(devices);
+ + devices = NULL;
+ + }
+ +
+ if (!devices)
+ goto end;
+
+2012-09-25 Hans de Goede <hdegoede@redhat.com>
+
+ Deal with libusbredirparser.pc rename to libusbredirparser-0.5.pc
+ The usbredir 0.5 release introduced the new API for 64 bit packet ids, but
+ it kept the libusbredirparser.pc name as is, meaning that older versions of
+ qemu will still have their pkg-config check for usbredirparser fulfilled,
+ and build with the usb-redir device. Due to the API change there will be
+ some compiler warnings, but the build will succeed, however the usb-redir
+ device will be broken on 32 bit machines.
+
+ To solve this, the usbredir-0.5.2 release renames the libusbredirparser.pc
+ file to libusbredirparser-0.5.pc, so that it will no longer fulfill the
+ pkg-config check of the qemu-1.2 and older releases, stopping the (silent)
+ breakage.
+
+ spice-gtk does not use the changed parts of the API, but does
+ use libusbredirparser for the usbredirfilter* functions. This patch adapts
+ spice-gtk's configure to accept both the libusbredirparser-0.5 and the
+ libusbredirparser pkg-config names.
+
+2012-09-25 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ G_GNUC_DEPRECATED_FOR must be defined publicly
+ It's not enough to define G_GNUC_DEPRECATED_FOR in glib-compat.h,
+ since this header is not public. Instead, let's define our own
+ public SPICE_DEPRECATED_FOR macro, and clean-up double definition.
+
+2012-09-24 Dunrong Huang <riegamaths@gmail.com>
+
+ spicy: Make "CopyToGuest" and "PasteFromGuest" insensitive if spice agent is not connected
+ "CopyToGuest" and "CopyToGuest" can not work if spice agent is not
+ connected, e.g. guest does not install or enable spice agent, or spice
+ server does not create vdagent channel.
+
+ In these cases, make those item insensitive.
+
+2012-09-21 Christophe Fergeau <cfergeau@redhat.com>
+
+ Update spice-common submodule
+
+ Update git.mk to latest version
+
+2012-09-20 Christophe Fergeau <cfergeau@redhat.com>
+
+ Update NEWS
+
+ Unescape SpiceSession::uri component by component
+ Unescaping the whole URI and then parsing it is dangerous as
+ the unescaping may (for example) add some extra '/' in the URI
+ which are not part of a path. It's better to do the unescaping later
+ once the URI has been split in separate components.
+ This commit unescapes the path, host and query values. Handling escaped
+ query values is important for usernames/passwords which might contain
+ chars which are invalid in URIs.
+ If the host is enclosed in [], it's intentionally not escaped as this
+ contains an ipv6 URI, and may contain a %zone_id (see RFC4007). This is
+ consistent with libvirt/libxml2 behaviour, not with what gvfs does.
+
+2012-09-14 Colin Walters <walters@verbum.org>
+
+ usb-acl-helper: Clear environment
+ Otherwise we can be subject to attack via environment variables such
+ as DBUS_SYSTEM_BUS_ADDRESS.
+ This addresses CVE-2012-4425 http://seclists.org/oss-sec/2012/q3/470
+
+2012-09-13 Christophe Fergeau <cfergeau@redhat.com>
+
+ cursor: don't access unitialized data when logging
+ SpiceCursor::header is only valid when SPICE_CURSOR_FLAGS_NONE is
+ not set in SpiceCursor::flags, so don't try to log info about
+ the header before we have tested this flag.
+
+2012-09-12 Christophe Fergeau <cfergeau@redhat.com>
+
+ channel: Introduce CHANNEL_DEBUG for channel debug logs
+ It automatically prepends the channel name to the log message
+ for easier debugging.
+
+ Fixes rhbz#822437
+
+2012-09-10 Christophe Fergeau <cfergeau@redhat.com>
+
+ build-sys: Fix symbol versioning
+ My changes in bug 5bf72a2e had a typo which broke symbol versioning
+ of libspice-client-gtk.so when -Wl,--version-script is available...
+
+ Update spice-common submodule
+ We need a newer spice-protocol to get the definitions for A8 surfaces.
+ Without it, compilation is broken.
+
+ Fix VD_AGENT_HAS_CAPABILITY use
+ The 'size' argument to this macro (defined in
+ spice-protocol/spice/vd_agent.h) is the number of 32 bit elements
+ available in its first argument. In channel-main.c it's used
+ most of the time with SpiceMainChannelPrivate::agent_caps which is
+ an uint32_t[VD_AGENT_CAPS_SIZE]. The 'size' argument to pass to
+ VD_AGENT_HAS_CAPABILITY is thus the number of elements in this array,
+ and not sizeof(agent_caps).
+
+ Fixes rhbz#837545
+
+2012-09-07 Søren Sandmann Pedersen <ssp@redhat.com>
+
+ Advertise SPICE_DISPLAY_CAP_A8_SURFACE
+
+2012-09-06 Christophe Fergeau <cfergeau@redhat.com>
+
+ build: Add fallback symbol files to EXTRA_DIST
+
+2012-09-05 Uri Lublin <uril@redhat.com>
+
+ spicy: add --title=<title> command line option
+
+ Revert "spice-common removed"
+ This reverts commit 519f118c7786aa0c16cd2a5f216b52cea4ac42d5.
+
+ spice-common removed
+
+2012-09-03 Alexander Larsson <alexl@redhat.com>
+
+ Fix region leak in gtk2 compat defines
+ https://bugs.freedesktop.org/show_bug.cgi?id=54277
+
+2012-09-03 Søren Sandmann Pedersen <ssp@redhat.com>
+
+ Advertise SPICE_DISPLAY_CAP_COMPOSITE
+
+ Add support for Composite command
+ All the real work is done in spice-common, so this is a pretty simple
+ change.
+
+ Conflicts:
+ spice-common
+
+2012-08-31 Alexander Larsson <alexl@redhat.com>
+
+ Make region code build with gtk2
+ https://bugs.freedesktop.org/show_bug.cgi?id=54277
+
+2012-08-31 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix X11 backend
+ The X11 backend allocates the "image" with X11 and needs the widget to
+ be realized before calling spicex_image_create().
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=54310
+
+ Update SpiceDisplay:only-downscale documentation
+
+2012-08-31 Alexander Larsson <alexl@redhat.com>
+
+ Fix flickering regression on some systems
+ For some reason the way we remove the "inner" area
+ when clearing the background doesn't work on one computer.
+ I don't really know why, but the current approach does seems a
+ little fragile.
+
+ This replaces it with a solid region operation that works on
+ all my machines.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=54277
+
+ Add only_downscale property
+ When this is enabled we never scale displays larger
+ than their actual size.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=54277
+
+ Centralize scaling handling
+ This moves all the handling of scaling calculations and
+ positioning of the display inside the widget into one place.
+
+ This makes it easier to later change how scaling works.
+
+ Also, the new scaling only support aspect-ratio-keeping
+ scaling.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=54277
+
+2012-08-30 Christophe Fergeau <cfergeau@redhat.com>
+
+ Move AM_PROG_AR before LT_INIT call
+ The other way round generates warnings:
+ configure.ac:14: warning: LT_INIT was called before AM_PROG_AR
+ aclocal.m4:1015: AM_PROG_AR is expanded from...
+
+2012-08-29 Alon Levy <alevy@redhat.com>
+
+ support automate >= 1.12 with new required AM_PROG_AR
+
+2012-08-29 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Update spice-common
+
+2012-08-28 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ glib-compat: add G_GNUC_DEPRECATED_FOR
+ G_GNUC_DEPRECATED_FOR was introduced in glib 2.26
+
+ misc build fix when --disable-smartcard
+
+ widget: differentiate key press & release from press only events
+ Until now, Spice clients only sent separate key events for press and
+ release. But this may result in unwanted key repetition from guest VM
+ side. It seems OSes have various implementations. While MS Windows
+ relies on hardware key repeats (which are several sequential press
+ events), otoh, X11 uses software key repeat (although not Linux
+ keyboard/VT by default).
+
+ We can't easily disable guest side repeaters, as it may be enforced by
+ other components (a X11 client can adjust each key individually, or
+ the desktop settings may change it etc.). Neither can we rely only on
+ guest software repeater as Windows doesn't seem to have one by
+ default, so we need to keep sending multiple press events as of today.
+
+ It seems a nice way to improve the situation is to send a single
+ "press&release" key event when the user released the key within a
+ short delay. If the key is pressed for longer, we keep the existing
+ behaviour which has been working pretty well so far, sending separate
+ "press", then repeatedly "press", and an ending "release" event.
+
+ v2:
+ - fix some commit message spelling spotted by Alon & Christophe
+ - simplify a bit the timer handling code after Hans review
+ - remove the submodule change (will be updated in earler patch once
+ pushed upstream)
+
+ widget: add keypress-delay property
+ The delay before the press event is sent to the server if the key is
+ kept pressed. If the key is released within that time, that delay is
+ ignored and a single key-press-release event will be sent.
+
+ widget: give more context to send_key()
+ - use a more explicit SendKeyType enum
+ - if the key is a modifier key, we don't want to delay press event
+
+ v2: fix compilation (remove down usage)
+
+ inputs: add spice_inputs_key_press_and_release()
+ If the server is capable of SPICE_INPUTS_CAP_SCANCODE, then we send
+ can send a single message with key press and release, to avoid
+ unwanted guest side key repeatition due to network jitter.
+
+ If the server is not capable, spice-gtk will use some compatibility
+ mode and send the existing DOWN and UP key events seperately.
+
+ util-priv: factor out spice_make_scancode()
+ Factor out the keyboard scancode manipulation function, to be reusable
+ by newer code.
+
+ Update spice-common
+
+2012-08-28 Yonit Halperin <yhalperi@redhat.com>
+
+ channel-smartcard: do not attach temporary migration channel to smartcard
+ During migration, the smartcard channel that belongs to the temporary
+ copied session shouldn't be active.
+
+ migration: copy enable-smartcard/audio/usbredir state to the migrated session
+ Otherwise, we will not create smartcard/usb channel on the destination
+ side, and we will create audio channels, no matter if they existed
+ of didn't exist for the src side.
+
+ seamless migration: don't reset messages data when swapping channels
+ When swapping the src and dest channels's, we need to keep
+ the xmit_queue and msg serials. Their state is expected to stay the same
+ after migration.
+
+ seamless migration: transfer pending msgs to the destination, instead of sending them to the src before FLUSH_MARK
+ In order to save migration time, and probably also decrease migration
+ data size, we push the flush mark to the src server before any other
+ message. All the other pending msgs will be sent later to the
+ destination server (see next patch).
+
+ seamless migration: src and dest servers handshake
+ Flow:
+ (1) *src* main channel coroutine (main_handle_migrate_begin_seamless):
+ handles SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS; yields to the main loop,
+ supplying it the destination information needed for connection.
+ (2) main context (migrate_connect):
+ Establishes a new session for connecting to the destination.
+ After all the channels are opened (async), their state, except for
+ the one of the main channel, is modified to
+ SPICE_CHANNEL_STATE_MIGRATING (see migrate_channel_event_cb);
+ no reading is done from the channel during this state.
+ The dest main channel's state is changed to SPICE_CHANNEL_STATE_MIGRATION_HANDSHAKE
+
+ (3) *dest* main channel coroutine: sends to the dest server SPICE_MSGC_MAIN_MIGRATE_DST_DO_SEAMLESS
+ (see spice_channel_recv_auth)
+ (4) *dest* main channel coroutine: recevices SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK/NACK.
+ adds main_migrate_handshake_done to the main loop.
+ (5) main context: when all the dest session channels are connected, and the main channel handshake
+ is done, we yield to the src main channel coroutine (see
+ migrate_channel_event_cb and main_migrate_handshake_done)
+ (6) *src* main channel coroutine: sends to the src server
+ SPICE_MSGC_MAIN_MIGRATE_(CONNECTED|CONNECTED_SEAMLESS|CONNECT_ERROR)
+
+ For more details see spice-protocol. commit
+ 1ad5d259cb4b695ec3106de7ccd082e031e7ae11
+
+ seamless-migration: update spice-common submodule
+ Update channel-main as well to support the change made to
+ SpiceMsgMainMigrationBegin: it now holds all the destination fields
+ inside SpiceMigrationDstInfo.
+
+ channel_main: handle SPICE_MSG_AGENT_CONNECTED_TOKENS
+
+ channel-base: remove bad check of SpiceMsgWaitForChannels validity
+ SpiceMsgWaitForChannels is not packed. Comparing the original
+ msg size to SpiceMsgWaitForChannels is wrong.
+
+2012-08-28 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Update spice-common
+
+ Release v0.13
+
+2012-08-26 Dunrong Huang <riegamaths@gmail.com>
+
+ spicy: connect from cli only if hostname and port are provided
+ This patch will fix following error:
+ $ spicy --spice-debug
+ ......
+ (spicy:21981): GSpice-DEBUG: spice-session.c:1618 new main channel, switching
+ (spicy:21981): GSpice-DEBUG: spice-gtk-session.c:811 Changing main channel from (nil) to 0x8534b0
+ (spicy:21981): GSpice-DEBUG: spicy.c:1587 new channel (#0)
+ (spicy:21981): GSpice-DEBUG: spicy.c:1590 new main channel
+ (spicy:21981): GSpice-DEBUG: spice-channel.c:2255 Open coroutine starting 0x8534b0
+ (spicy:21981): GSpice-DEBUG: spice-channel.c:2098 Started background coroutine 0x853538 for main-1:0
+ (spicy:21981): GSpice-DEBUG: spice-channel.c:2122 connection failed, trying with TLS port
+ (spicy:21981): GSpice-DEBUG: spice-channel.c:2126 Connect error
+ GSpice-Message: main channel: failed to connect
+ ......
+
+ When user starts spicy without any command-line arguments, spicy
+ should not attempt to connected to server automatically because
+ hostname or port are unknown at the moment.
+
+ What this patch changes is to show the dialog window instead of
+ connecting to server automatically if no hostname or port are found.
+
+2012-08-10 Christophe Fergeau <cfergeau@redhat.com>
+
+ Check --spice-disable-effects parameter validity
+ When --spice-disable-effects is used, error out unless this is
+ the name of one of the effects we can disable.
+
+ Fixes rhbz#818848
+
+ Check --spice-color-depth parameter validity
+ When --spice-color-depth is used, error out unless the color depth
+ is 16 or 32.
+
+ Fixes rhbz#818847
+
+2012-08-09 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Update spice-common
+
+2012-08-08 Christophe Fergeau <cfergeau@redhat.com>
+
+ build: make spice-controller.pc installation conditional
+ It shouldn't be installed when controller support is disabled.
+
+ build: generate sym-file
+ When -Wl,--version-script is not available, we fallback to using
+ libtool --export-symbols feature, but the needed sym-file is missing
+ from git. This commit adds generation of the sym-file to the
+ update-map-file Makefile target, and adds a sym-file to git.
+ The linker on OSX Lion doesn't like to have non-existing symbols
+ specified in the symbol files it's given, so the symbols need to
+ be split in glib symbols and gtk symbols.
+
+2012-08-07 Christophe Fergeau <cfergeau@redhat.com>
+
+ build: add --enable-smartcard=auto support
+ Currently, when running configure with no arguments, smartcard
+ support is enabled by default, and configure will fail if it cannot
+ find libcacard. This commit adds a --enable-smartcard=auto mode to
+ configure which will use automatically enable smartcard support if
+ libcacard is available, but it will be silently disabled if libcacard
+ is not available. Passing --enable-smartcard will fail if libcacard
+ is not available. Passing --disable-smartcard will always disable
+ smartcard support and will not test for libcacard availability.
+
+ build: make controller build optional
+ Apart from the Vala bindings, this is the only part of spice-gtk
+ which requires Vala to be built from git. Since it's only useful
+ when spice-gtk is used in conjunction with an oVirt browser plugin,
+ letting people disabling it will not necessarily cause issues.
+
+2012-08-05 Matthias Clasen <mclasen@redhat.com>
+
+ Don't use GDK_THREADS_ENTER/LEAVE
+ These macros have been deprecated. The quick fix for now is to just use the
+ functions gdk_threads_enter/leave instead. They are deprecated as well, but
+ deprecated functions don't cause the build to fail (unless you use -Werror).
+
+2012-07-30 Hans de Goede <hdegoede@redhat.com>
+
+ Remove "usbredirhost: " prefix from usbredirhost error messages
+ libusbredirhost prefixes all its messages with "usbredirhhost: ", which
+ is useful when logging to stderr, but not so much when showing the error
+ to the user in an error dialog, so remove the "usbredirhost: " prefix
+ when we store the message in a GError.
+
+2012-07-28 Hans de Goede <hdegoede@redhat.com>
+
+ channel-display: Set monitors_max to 1 on init
+ This fixes remote-viewer with the new multi monitor support not working
+ when connecting to a spice-server without the new multi-monitor support.
+
+ Before this fix remote-viewer would hit the following g_return_if_fail:
+ (remote-viewer:24787): remote-viewer-CRITICAL **:
+ virt_viewer_session_spice_display_monitors:
+ assertion `monitors->len <= monitors_max' failed
+
+ spice-widget: release mouse grab on keyboard-grab-inhibit
+ The purpose of the keyboard-grab-inihbit mechanism is to allow other apps
+ to grab the input while the spice-widget has the focus, mainly when we're
+ going to invoke policykit for usb-redirection, as that the policy-kit
+ agent may want to grab the input.
+
+ Before this patch we were only inhibitting the keyboard grab, which works fine
+ for vms which are in client mouse mode, but is not enough for vms which are
+ in server mouse mode.
+
+ This patch also releases the mouse grab on keyboard-grab-inhibit, fixing
+ the policykit dialog not showing (and thus usb redir not working) when
+ running with server mouse mode. Note that this makes the inhibit-keyboard-grab
+ name of the property no longer really cover what it does, but allas it is
+ part of our ABI...
+
+2012-07-18 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Run-time check monitor per display count <= 256
+ Limit range of monitors, to avoid potential crashes lead by invalid
+ received MonitorConfig values (could be misconfigured or misbehaving
+ guest)
+
+ This is a a client-side implementation limitation. Eventually, the
+ range could be inscreased (or unlimited == 0) in the future...
+
+2012-07-16 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Enable the display early when the widget is created
+ The spice_main_set_display_enabled() function is used to mark the
+ display/monitor config as enabled. In order to simplify client
+ implementation, the widget enables the matching display automatically
+ when the channel mark is received. This is only for legacy reason, and
+ my lack of understanding at that time. It could as well be enabled
+ earlier, when the widget is created. It wasn't really a good decision
+ to disable monitor when the mark is off, which can be toggled when the
+ primary surface is resize for example, and can cause some races..
+
+ Add SpiceDisplay:ready property
+ There are several condition to meet in order to have a widget ready to
+ be displayed: the monitor must exist, the area must intersect, and the
+ display mark must be reached. This property will help clients to know
+ when the widget display is ready. Until now, it was relying on the
+ channel mark signal only, and had to deal with the rest of the
+ conditions without much help.
+
+ Handle MonitorsConfig::max_allowed
+
+ main: send monitor config immediately
+ The only way this can be called currently is via the main/system
+ coroutine. Remove display timer if any.
+
+ Implement simple monitors alignment
+
+ widget: use display monitors configuration
+ Use display::monitors property to manage display area. Call
+ update_area_monitor() to update the widget area depending on monitor
+ configuration
+
+ spicy: disable display when deleting window
+
+ spicy: learn to deal with monitors
+
+ Make-up a MonitorConfig if the server doesn't provide one
+ This allows easier compatibility for clients that don't have to
+ check and interact differently depending on channel capabilities.
+
+ Handle SPICE_MSG_DISPLAY_MONITORS_CONFIG
+
+ Don't attempt to draw an invalid area
+ If we don't intersect, the area is invalid or of size 0.
+
+ Use monitor_id to compute display_id
+
+ Document spice_main_send_monitor_config()
+
+ widget: don't forget to disconnect all signals handlers
+ We forgot about display-mark. Use spice_g_signal_connect_object()
+ helper, which will disconnect properly in all circunstances.
+
+ spice_channel_connect() success if state >= CONNECTING
+ We may have several widget trying to re-connect the channels now.
+ It is fine to return successfully if we are already connecting or
+ connected.
+
+ widget: add monitor property with ctor
+
+ Claim SPICE_DISPLAY_CAP_MONITORS_CONFIG
+
+ Add spice_display_get_primary()
+
+ display: add readonly monitors property
+
+ glib-compat: add g_clear_pointer
+ A helpful macro from glib 2.34
+
+ Change surface_id to a guint32
+ That's the correct type used by the protocol.
+
+ widget: add main channel before other channels
+ Make sure that the d->main channel member can be referenced when
+ adding further channels, when we perform their setup.
+
+ Add missing agent cap description
+
+ display: learn to restrict display to an area
+ Each spice widget can now restrict the area of the primary
+ surface they show and interact with by setting the private
+ area member.
+
+ A nice clean-up would be to seperate an area object that
+ would deal with clipping, input translation and color
+ conversion, but the resulting code would be similar anyway
+
+ widget: simplify redraw call
+
+ Update spice-common
+
+2012-07-16 Uri Lublin <uril@redhat.com>
+
+ usb-device-manager: mingw: connect: cleanup device if it's libdev is missing
+ For Windows client, when connecting a device to the guest, if a libusb
+ device (libdev) does not exist, cleanup and forget about that device.
+
+ Most likely, the device was plugged out at driver installation
+ time, and its remove-device event was ignored.
+
+2012-07-12 Yonit Halperin <yhalperi@redhat.com>
+
+ migration/channel-inputs: reset motion count after migration
+ The motion count must stay synchronized with the server, otherwise,
+ it is possible that we will stop sending motion events to the server
+ after migration.
+
+ rhbz#835997
+
+2012-07-11 Uri Lublin <uril@redhat.com>
+
+ usb-device-manager: do not try to connect a usb device that was removed
+ If a device that is asked to be shared with the guest, is unplugged out
+ of the machine before being redirected, then let the user know that
+ usbredir of that device failed (and cleanup nicely).
+
+ For Windows client, the time between request and redir is larger, as
+ it includes the time it takes to install the libusb driver.
+
+2012-07-11 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ usbutil: be more explicit about usbids_vendor_count usage
+ I introduced a regression in the previous patch, counting the
+ usbids_vendor_count from -1 if the previous attempt failed.
+
+ usbutil: fix crash on windows
+ vendor_count is the last access index, the actually count is +1.
+
+ On Windows, it crashes later on because of corrupted memory.
+
+ Thanks to valgrind for this precious help:
+
+ ==4535== Invalid write of size 2
+ ==4535== at 0x40197E: spice_usbutil_parse_usbids (usbutil.c:170)
+ ==4535== by 0x401CEC: spice_usbutil_load_usbids (usbutil.c:241)
+ ==4535== by 0x4020C6: main (usbutil.c:322)
+ ==4535== Address 0x56b740c is 12 bytes after a block of size 348,160 alloc'd
+ ==4535== at 0x4A0884D: malloc (vg_replace_malloc.c:263)
+ ==4535== by 0x4EAAEBE: g_malloc (gmem.c:159)
+ ==4535== by 0x401847: spice_usbutil_parse_usbids (usbutil.c:156)
+ ==4535== by 0x401CEC: spice_usbutil_load_usbids (usbutil.c:241)
+ ==4535== by 0x4020C6: main (usbutil.c:322)
+ ==4535==
+
+ usbutil: look up usb.ids under g_get_system_data_dirs() by default
+ Simplify a little bit the portability by looking up usb.ids file
+ under g_get_system_data_dirs(). This is how most resources are
+ found under other OS, looking up files under various places, since
+ installation location may vary.
+
+2012-07-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: fix make distcheck
+
+2012-07-10 Uri Lublin <uril@redhat.com>
+
+ usb-device-manager: mingw: win driver install callback: add missing ifdef
+ This fixes the following compilation error message (without USE_USBREDIR):
+
+ usb-device-manager.c:183:13: error: 'spice_usb_device_manager_drv_install_cb' declared 'static' but never defined [-Werror=unused-function]
+
+ win-usb-driver-install: initialize "req" with memset
+ This fixes the following compilation error message:
+
+ ../../gtk/win-usb-driver-install.c: In function 'spice_win_usb_driver_send_request':
+ ../../gtk/win-usb-driver-install.c:187:5: error: missing braces around initializer [-Werror=missing-braces]
+ ../../gtk/win-usb-driver-install.c:187:5: error: (near initialization for 'req.hdr') [-Werror=missing-braces]
+
+ usb-device-manager: mingw: ignore "remove" udev event when un/installing a driver
+
+ usb-device-manager: mingw: keep driver install/uninstall state of a device
+ Currently only driver install/unsinstall is of interest, such that
+ extra udev events can be ignored.
+
+ usb-device-manager: add 'state' field to SpiceUsbDeviceInfo
+ To be used on Win32 to ignore extra udev events
+ received during driver install/uninstall.
+
+ Win32/mingw: win-usb-dev: skip hubs
+ also skip devices with bad (0) device-address.
+
+ Win32/mingw: usb-device-manager: uninstall win usb driver upon device disconnect
+
+ win-usb-driver-install: add capability to remove (uninstall) a win usb driver
+
+ Windows mingw: usb: Dynamically install a libusb driver for USB devices
+ - Added win-usb-driver-install.[ch]
+ - Added win-usb-clerk.h
+
+ Operation (on Windows, spice-gtk point of view):
+ - After some sanity checks, just before redir'ing a USB device
+ a libusb driver needs to be installed (before libusb can open the device)
+ - A connection (NamedPipe) is established with usb-clerk, a libusb
+ driver installation service, and a request for driver installation
+ is sent.
+ - Installation status is asynchronously read from the pipe, and
+ spice_usb_drv_install_finished() is called.
+ - Upon a successful intallation, usbredir continues.
+
+ Linux operation is not changed.
+
+2012-07-10 Arnon Gilboa <agilboa@redhat.com>
+
+ Windows mingw: usb: implement GUdevDevice & GUdevClient for windows
+ - Added win-usb-dev.[ch]
+ - Added GUdevDevice and GUdevClient like classes
+ - Added uevent signal based on WM_DEVICECHANGE
+
+2012-07-10 Uri Lublin <uril@redhat.com>
+
+ Make SpiceUsbDevice a box for SpiceUsbDeviceInfo, instead of a box for libusb_device
+ Note that this change may affect performance a bit, as sometimes there is
+ a need to find the libusb_device or the SpiceUsbDevice. Likely it's negligible.
+
+ Introduce SpiceUsbDeviceInfo to be kept instead of a libusb_device
+ For Windows, it's better not to keep references for libusb_devices
+ that are not used.
+ So instead of makeing SpiceUsbDevice a box for a libusb_device
+ it is going to be a box for a SpiceUsbDeviceInfo.
+
+ Windows mingw: usb: configure.ac: do not require GUDEV for USBREDIR
+ For windows GUDEV is not required
+ For Linux GUDEV is checked as a part of USBREDIR block, but
+ as a separate check.
+
+ usb-device-manager: mingw: add_dev: ignore already known devices
+ Sometimes on a Windows client, udev events are received while
+ the driver is being un/installed. so just ignore it
+
+ usb-device-manager: add a helper function to find a usb device <bus, addr>
+ And use it in spice_usb_device_manager_remove_dev
+
+ spice_usb_device_get_description: use device-descriptor only to get <vid,pid>
+ In preparation for a different SpiceUsbDevice.
+
+ With the new SpiceUsbDeviceInfo, <vid,pid> will be provided by
+ SpiceUsbDevice, and not by the device_descriptor (from libusb)
+
+ spice_usb_device_manager_device_error: replace SpiceUsbDevice with libusb_device
+ Its only user is channel-usbredir, which needs the libusb_device.
+
+ In preparations for a different SpiceUsbDevice.
+
+ spice_usb_device_manager_auto_connect_cb: use type SpiceUsbDevice for "device"
+ Currently SpiceUsbDevice is a BOX for libusb_device.
+ In preparation for a different SpiceUsbDevice.
+
+ spice_usb_device_manager_add_dev: use type SpiceUsbDevice for "device"
+ Currently SpiceUsbDevice is a BOX for libusb_device.
+ In preparation for a different SpiceUsbDevice.
+
+ Renamed the libusb_device variable to libdev. Needed when
+ asking usbredir to check the filter.
+
+ spice_usb_device_manager_add_dev: check auto_ok before freeing libusb device list
+ In preparation for a different SpiceUsbDevice.
+
+ spice_usb_device_manager_remove_dev: use type SpiceUsbDevice for "device"
+ Currently SpiceUsbDevice is a BOX for libusb_device.
+ In preparation for a different SpiceUsbDevice.
+
+ controller/test.c: mingw: fix compiler bad param warning for ReadFile
+ It seems that ssize_t is int, while DWORD is long
+
+ Compiler warning (some whitespaces where added for readability):
+ ../../../gtk/controller/test.c: In function 'read_from_pipe':
+ ../../../gtk/controller/test.c:108:5: warning: passing argument 4 \
+ of 'ReadFile' from incompatible pointer type [enabled by default]
+ In file included from /usr/i686-w64-mingw32/sys-root/mingw/include/windows.h:70:0,
+ from ../../../gtk/controller/test.c:27:
+ /usr/i686-w64-mingw32/sys-root/mingw/include/winbase.h:1426:29: note: expected \
+ 'LPDWORD' but argument is of type 'ssize_t *'
+
+ usb-device-manager: warn if a device to remove was not found
+ Also changed a bit the warning text on device-add to differentiate the two.
+
+ spicy: more informative presentation of usb devices in menu
+ Using the default format.
+
+2012-07-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ controller: async flush read/write
+ Windows namedpipes behave a bit differently from Unix socket, and may
+ return incomplete read/write. By using 2 read/write() helpers, try to
+ complete the operation before returning. Since the IO operation may be
+ splitted over several call, we make sure the buffer pointer is on the
+ heap. We use exception for EOF or BROKEN_PIPE condition, which also
+ simplifies the code.
+
+ To really work with namedpipe, the giowin32streams need to be fixed as
+ well to handle concurrent read & write properly, see for details:
+ https://bugzilla.gnome.org/show_bug.cgi?id=679288
+
+ Remove mandatory generation of vala debug C
+ Use make VALAFLAGS=-g if you need it instead
+
+2012-07-08 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix mingw build
+ printf is redefined by glib/gi18n.h
+
+ In file included from ../spice-common/common/spice_common.h:29:0,
+ from ../spice-common/common/ring.h:23,
+ from spice-channel-cache.h:23,
+ from spice-session-priv.h:26,
+ from desktop-integration.c:29:
+ ../spice-common/common/log.h:49:17: error: 'libintl_printf' is an unrecognized format function type [-Werror=format]
+ ../spice-common/common/log.h:56:16: error: 'libintl_printf' is an unrecognized format function type [-Werror=format]
+ In file included from ../spice-common/common/canvas_base.h:25:0,
+ from decode.h:23,
+ from spice-session-priv.h:27,
+ from desktop-integration.c:29:
+ ../spice-common/common/lz.h:22:5: error: 'libintl_printf' is an unrecognized format function type [-Werror=format]
+ ../spice-common/common/lz.h:23:5: error: 'libintl_printf' is an unrecognized format function type [-Werror=format]
+ ../spice-common/common/lz.h:24:5: error: 'libintl_printf' is an unrecognized format function type [-Werror=format]
+
+ unused variable 'self' if !USE_USB
+ CC spice-widget-enums.lo
+ desktop-integration.c: In function 'spice_desktop_integration_dispose':
+ desktop-integration.c:175:30: error: unused variable 'self'
+ [-Werror=unused-variable]
+
+2012-07-06 Hans de Goede <hdegoede@redhat.com>
+
+ spice-widget: Don't change usbredir/automount settings while redirecting
+ The keyboard focus may change while usb-device-manager is in the process of
+ redirecting a usb-device (as this may show a policykit dialog). Making
+ autoredir/automount setting changes while this is happening is not a good idea!
+
+ Since usb-device-manager already sets keyboard_grab_inhibit when it is
+ redirecting to allow the policykit dialog to show, we can use that to
+ inhibit usb-autoredir setting changes.
+
+ spice-gtk-session: hookup automount inhibiting
+ Inhibit automounting when usb-autoredirection is active.
+
+ Add a desktop-integration helper class
+ We need to integrate closely with the desktop environment of the user in
+ several cases. Some examples are disabling auto-mounting when auto-usbredir
+ is active (rhbz#812972), and disabling the screensaver when fullscreen
+ (fdo#34793).
+
+ Unfortuntely these kinds of things require desktop environment specific
+ handling. Therefor this patch introduces a desktop-integration helper class,
+ which is to server as a container for all sort of desktop environment specific
+ functions.
+
+ For now it just supports disabling automounting under Gnome, but this will be
+ extended in the future.
+
+2012-06-28 Yonit Halperin <yhalperi@redhat.com>
+
+ agent: fix mishandling of SPICE_MSG_MAIN_AGENT_TOKEN
+ Add the given tokens instead of overriding the existing ones.
+
+2012-06-26 Hans de Goede <hdegoede@redhat.com>
+
+ spice-gtk-session: rename update_keyboard_focus to request_auto_usbredir
+ To better reflect what then function does, also rename the tracking variable
+ inside spice-gtk-session to match.
+
+ spice-gtk-session: Fix keyboard focus tracking
+ This patch changes the "do we have focus?" tracking, to keeping a counter with
+ how many widgets have focus. The reason for this is that sometimes multiple
+ spice-widgets can have focus at the same time, yes really! Sometimes (rarely,
+ hard to reproduce) the focus in event for one window arrives before the
+ focus out of the other window.
+
+ spice-gtk-session: Only update usb "auto-connect" when doing "auto-usb-redir"
+ Only update the UsbDeviceManager's "auto-connect" property when
+ "auto-usb-redir" is set, otherwise leave it as is. This allows apps to
+ control UsbDeviceManager's "auto-connect" directly, without it getting reset
+ on every keyboard focus change.
+
+2012-06-24 Uri Lublin <uril@redhat.com>
+
+ Move "err" variable definition to beginning of the function
+ This fixes the following compilation error:
+ channel-usbredir.c: In function 'spice_usbredir_channel_connect_device_async':
+ channel-usbredir.c:313:9: error: jump skips variable initialization [-Werror=jump-misses-init]
+
+2012-06-13 Christophe Fergeau <cfergeau@redhat.com>
+
+ Fix build when usbredir is disabled
+ I broke it with my leak fixes
+
+ Fix various memory leaks
+ ==25063== 12,827 (2,032 direct, 10,795 indirect) bytes in 127 blocks are definitely lost in loss record 9,477 of 9,502
+ ==25063== at 0x4A0884D: malloc (vg_replace_malloc.c:263)
+ ==25063== by 0x3DE384D2BE: g_malloc (gmem.c:159)
+ ==25063== by 0x3DE38616B1: g_slice_alloc (gslice.c:1003)
+ ==25063== by 0x3DE38346B0: g_error_new_valist (gerror.c:393)
+ ==25063== by 0x3DE3834A8C: g_set_error (gerror.c:560)
+ ==25063== by 0x3DE4871108: g_socket_receive_with_blocking (gsocket.c:2513)
+ ==25063== by 0x5B708E8: bio_gsocket_bread (bio-gsocket.c:56)
+ ==25063== by 0x61AEBD8: BIO_read (bio_lib.c:212)
+ ==25063== by 0x5ECAC5B: ssl3_read_n (s3_pkt.c:238)
+ ==25063== by 0x5ECBD3D: ssl3_read_bytes (s3_pkt.c:318)
+ ==25063== by 0x5ECD6CF: ssl3_get_message (s3_both.c:426)
+ ==25063== by 0x5EC5AFB: ssl3_get_new_session_ticket (s3_clnt.c:1822)
+
+ ==25063== 90 bytes in 3 blocks are definitely lost in loss record 7,354 of 9,502
+ ==25063== at 0x4A0884D: malloc (vg_replace_malloc.c:263)
+ ==25063== by 0x3DE384D2BE: g_malloc (gmem.c:159)
+ ==25063== by 0x3DE3862D0B: g_strdup (gstrfuncs.c:356)
+ ==25063== by 0x5B961B5: spice_usb_device_manager_set_property (usb-device-manager.c:306)
+ ==25063== by 0x3DE40148FB: g_object_constructor (gobject.c:1352)
+ ==25063== by 0x3DE4015D70: g_object_newv (gobject.c:1713)
+ ==25063== by 0x3DE401655F: g_object_new_valist (gobject.c:1830)
+ ==25063== by 0x3DE485924D: g_initable_new_valist (ginitable.c:224)
+ ==25063== by 0x3DE4859348: g_initable_new (ginitable.c:148)
+ ==25063== by 0x5B97330: spice_usb_device_manager_get (usb-device-manager.c:770)
+ ==25063== by 0x52D8C6B: spice_gtk_session_update_keyboard_focus (spice-gtk-session.c:845)
+ ==25063== by 0x52D6DC1: spice_gtk_session_set_property (spice-gtk-session.c:238)
+
+ ==25063== 120 bytes in 3 blocks are definitely lost in loss record 8,448 of 9,502
+ ==25063== at 0x4A06F18: calloc (vg_replace_malloc.c:566)
+ ==25063== by 0x68BB2E5: usbredirfilter_string_to_rules (usbredirfilter.c:54)
+ ==25063== by 0x5B96123: spice_usb_device_manager_set_property (usb-device-manager.c:293)
+ ==25063== by 0x3DE40148FB: g_object_constructor (gobject.c:1352)
+ ==25063== by 0x3DE4015D70: g_object_newv (gobject.c:1713)
+ ==25063== by 0x3DE401655F: g_object_new_valist (gobject.c:1830)
+ ==25063== by 0x3DE485924D: g_initable_new_valist (ginitable.c:224)
+ ==25063== by 0x3DE4859348: g_initable_new (ginitable.c:148)
+ ==25063== by 0x5B97330: spice_usb_device_manager_get (usb-device-manager.c:770)
+ ==25063== by 0x52D8C6B: spice_gtk_session_update_keyboard_focus (spice-gtk-session.c:845)
+ ==25063== by 0x52D6DC1: spice_gtk_session_set_property (spice-gtk-session.c:238)
+ ==25063== by 0x3DE40148FB: g_object_constructor (gobject.c:1352)
+
+ ==25063== 11,959 (72 direct, 11,887 indirect) bytes in 1 blocks are definitely lost in loss record 9,475 of 9,502
+ ==25063== at 0x4A06F18: calloc (vg_replace_malloc.c:566)
+ ==25063== by 0x3459C92DDC: XkbGetKeyboardByName (XKBGetByName.c:59)
+ ==25063== by 0x52DF000: vnc_display_keymap_gdk2xtkbd_table (vncdisplaykeymap.c:153)
+ ==25063== by 0x52D9FA6: spice_display_init (spice-widget.c:389)
+ ==25063== by 0x3DE402FA05: g_type_create_instance (gtype.c:1892)
+ ==25063== by 0x3DE40147A7: g_object_constructor (gobject.c:1849)
+ ==25063== by 0x52DA07B: spice_display_constructor (spice-widget.c:412)
+ ==25063== by 0x3DE4015D70: g_object_newv (gobject.c:1713)
+ ==25063== by 0x3DE401655F: g_object_new_valist (gobject.c:1830)
+ ==25063== by 0x3DE4016893: g_object_new (gobject.c:1545)
+ ==25063== by 0x52DE746: spice_display_new (spice-widget.c:1924)
+ ==25063== by 0x41D6C3: virt_viewer_display_spice_new (virt-viewer-display-spice.c:219)
+
+2012-06-11 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ misc: use g_value_dup_object
+
+ Fix incorrect format string
+
+ Fix video playback with GStreamer backend
+ The playback audio delay is not correctly adjusted, we should take
+ min_latency, set by gst_bin_do_latency_func ().
+
+ Deprecate spice_channel_set_capability()
+ This was initially public to eventually let a derived class
+ implement more capabilities. Even though it is technically
+ doable to derive and tweak exisiting channels, there is a
+ lack of support in spice-gtk for doing that.
+
+ Allow to disable specific capabilities at runtime
+ Capability BAR for channel FOO can be disabled at runtime by setting
+ the SPICE_FOO_CAP_BAR environment variable to '0'
+ Disabling capabilities is useful for testing purpose.
+
+2012-06-11 Christophe Fergeau <cfergeau@redhat.com>
+
+ spice_channel_coroutine: fix function exit in error path
+ spice_channel_coroutine returns a void *, but one of its error path
+ is doing 'return FALSE'. This commit replaces this return with a
+ 'goto cleanup' since this is what is done in the other error paths.
+
+ spice_channel_coroutine: emit signals in all error cases
+ There are several very unlikely failures where no signal is emitted
+ to indicate the failure. Since applications rely on these signals
+ to detect spice-gtk connection failures, it's important to emit
+ one in all error cases.
+
+ Emit SPICE_CHANNEL_ERROR_TLS when certificate can't be found
+ When trying to start remote-viewer with SPICE over TLS with
+ --spice-ca-file with a wrong filename, the connection fails
+ but remote-viewer keeps displaying the "Trying to connect"
+ message. The only hint that something went wrong is:
+ (remote-viewer:12924): GSpice-WARNING **: loading ca certs from a/home/teuf/foo.crt
+
+ This patch makes sure we emit a SPICE_CHANNEL_ERROR_TLS before
+ giving up on channel creation to inform the application that
+ an error happened.
+
+2012-06-07 Christophe Fergeau <cfergeau@redhat.com>
+
+ build: allow building with newer glibc-headers and -O0
+ Fix copied from libvirt, commit by Eric Blake.
+
+ glibc 2.15 (on Fedora 17) coupled with explicit disabling of
+ optimization during development dies a painful death:
+
+ /usr/include/features.h:314:4: error: #warning _FORTIFY_SOURCE requires compiling with optimization (-O) [-Werror=cpp]
+
+ Work around this by only conditionally defining _FORTIFY_SOURCE,
+ in the case where glibc can actually use it. The trick is using
+ AH_VERBATIM instead of AC_DEFINE.
+
+2012-06-06 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Update spice-common
+
+2012-06-04 Hans de Goede <hdegoede@redhat.com>
+
+ spicy: Change 'OK' button to 'Close' button in USB device selection
+ The USB device selection applies immediately, so the dialog should be using
+ 'Close' instead of 'OK' for its primary button.
+
+ This patch syncs spicy with virt-viewer wrt the USB device selection dialog.
+
+2012-05-29 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ widget: disconnect session_inhibit_keyboard_grab_changed
+ There is one handler we forgot to disconnect on dispose()
+ that may cause a crash.
+
+ I am thinking of generalizing usage of
+ spice_g_signal_connect_object()..
+
+ Should fix:
+ https://bugzilla.redhat.com/show_bug.cgi?id=823570
+
+2012-05-28 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Clipboard clean-up and fixes for Windows client
+ The Windows client was getting in the way of guest copy-paste,
+ because when the guest was taking the clipboard grab, the agent
+ notifies the client, it takes the grab too, and in return
+ receives clipboard notification of new ownership from the client
+ clipboard.
+
+ Though we had a hack to check if this new client clipboard event
+ is caused by us, the Windows Gtk clipboard is giving 2 notifications
+ for some reasons.
+
+ It turned out there is a much better way than the "selfgrab" hack,
+ by setting ownership of the clipboard. Problem solved, and cleaner
+ code!
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=822688
+
+2012-05-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: correctly track main channel
+ The main channel can change when we are reconnecting to the server,
+ for example, when querying the password to the user. From there,
+ the old main channel is destroyed, but we don't track properly the
+ new main channel.
+
+ This fix migration crashing later on, because of missing main channel:
+ https://bugzilla.redhat.com/show_bug.cgi?id=823874
+
+2012-05-18 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Reset grab-sequence on match
+ This avoids triggering the grab event on consecutive
+ matches, such as ctrl+alt (match) then ctrl+alt+foo
+ (match again) that would prevent the longer combination
+ from being sent.
+
+ If grab sequence is matched, still send modifier keys
+ If the last key pressed from the grab sequence is a modifier
+ key, let send it to the guest too.
+
+ This solves the issue of default grab-sequence being ctrl+alt
+ and preventing ctrl+alt+del from working.
+
+2012-05-17 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Running out of reserved space, break ABI
+ The change abc56811de978ad336a651924a21b920cfe677f0 actually added
+ a field in a public struct while changing overall struct size, the
+ fields were also reorder, all of this breaks ABI.
+
+ However, we are running out of free space in SpiceChannelClass
+ struct. And since the SPICE_RESERVED_PADDING was 44 bytes, that is
+ quite limited on 64bits (only 5 pointers fit).
+
+ I propose we break ABI during this cycle. This means that programs
+ using spice-gtk will need to be recompiled to use the new library.
+ (the old library should be parallel installable though). This let us:
+ - use a better SPICE_RESERVED_PADDING based on pointer size, since
+ it is what is usually added for virtual methods
+ - reset the amount taken from the padding in the various struct
+ - reorder fields a little
+ - add some missing "priv" pointers
+ - whatever I am missing that we can still change before next release
+
+ Please comment if I am missing something, or correct me
+
+ session: correctly set and unset ssl-verify flags
+ If no cert-subject or pubkey is provided, we should unset the corresponding flags.
+
+2012-05-17 Yonit Halperin <yhalperi@redhat.com>
+
+ record channel: reseting channel caps
+
+ playback channel: reseting channel caps
+
+ display channel: reseting channel caps
+
+ main channel: reseting channel caps
+
+ Fix not setting channel specific capabilities upon channel reset
+ Related: rhbz#821795
+
+ The capabilities have been zeroed after channel reset, which have lead to
+ publish the wrong caps when both port and tls-port are given, and the
+ channels are secured (first attempt to connect the channel with "port"
+ has failed; the channel got reset, and then reconnected with "tls-port"
+ and bad caps). Specifically, the bug causes semi-seamless migration not
+ to work when part of the channels are secured.
+
+2012-05-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ python: fix Spice.Audio binding
+ The spice_audio_new() function is not correctly generated h2def.py
+ anymore because of the surrounding #ifdef and macros. Add it in
+ the manual.defs instead.
+
+ Avoid API breakage:
+ 2012-05-10 01:56:48,884 (cli:83): Uncaught exception:
+ Traceback (most recent call last):
+ File /usr/share/virt-manager/virtManager/console.py, line 475, in
+ _channel_new_cb
+ self.audio = spice.Audio(self.spice_session)
+ TypeError: GObject.__init__() takes exactly 0 arguments (1 given)
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=820335
+
+2012-05-03 Yonit Halperin <yhalperi@redhat.com>
+
+ display: video streaming: add support for frames of different sizes
+ rhbz #815426
+
+ When playing a youtube video on Windows guest, the driver sometimes sends
+ images which contain a video frame, but also other parts of the
+ screen (e.g., the you tube process bar). In order to prevent glitches, we send these
+ images as part of the stream, using SPICE_MSG_DISPLAY_STREAM_DATA_SIZED.
+
+2012-05-02 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix parsing URI query
+ Do not depend on uninitialized "len" variable to set the query string.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=818169
+
+2012-04-27 Christophe Fergeau <cfergeau@redhat.com>
+
+ g_getenv returns a const string
+ When switching from getenv to g_getenv, 'doms' declaration
+ wasn't changed from char * to const char *, which causes
+ a gcc warning.
+
+2012-04-27 Daniel P. Berrange <berrange@redhat.com>
+
+ Fix annotations for GrabSequence class
+ The default transfer mode is wrong for spice_display_get_grab_keys.
+ The array parameter for spice_grab_sequence_new needs explicit
+ annotation
+
+2012-04-26 Daniel P. Berrange <berrange@redhat.com>
+
+ Replace getenv/setenv with g_getenv/g_setenv for Win32 portability
+
+2012-04-25 Daniel P. Berrange <berrange@redhat.com>
+
+ Fix --spice-debug flag on glib >= 2.31
+ With glib >= 2.31 no debug messages are ever printed out by
+ default, which makes the --spice-debug flag useless. This
+ fix explicitly turns on the appropriate log domain when
+ debug is requested. It takes care to preserve the users
+ own existing log domain requests
+
+2012-04-24 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release v0.12
+
+ Lower a few warnings when migration fails
+
+2012-04-24 Daniel P. Berrange <berrange@redhat.com>
+
+ Fix multiple problems with URI parsing
+ The URI parsing was not correctly skipping over the path component
+ if a port number was specified using the traditional URI scheme,
+
+ eg
+
+ spice://somehost:5900/
+
+ would result in failed parse due to the trailing '/'
+
+ The URI parsing was also not considering that the authority
+ component is allowed to contain '[' and ']' around the hostname.
+ This is used when specifying raw IPv6 addresses to remove the
+ parsing ambiguity wrt ':'.
+
+ eg
+
+ spice://[::1]:5900/
+
+ Various stages of parsing also failed to report errors.
+
+2012-04-23 Uri Lublin <uril@redhat.com>
+
+ setsockopt: check for ENOTSUP only if defined
+ For windows (mingw32) ENOTSUP is not defined.
+
+ Related to 3bfadb8587f59a74d373e26385d348a105c2e425
+
+2012-04-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Allow to disable CELT at runtime
+ We might want to make it a property, but having an environemnt variable
+ is useful too, to override behaviour.
+
+ build-sys: pyparsing req. moved to spice-common
+
+2012-04-19 Daniel P. Berrange <berrange@redhat.com>
+
+ Fix callback signature for --spice-debug option handling
+ The callback for option handling should return TRUE otherwise the
+ option parser will think parsing failed. The current 'void' return
+ type meant it was non-deterministic whether --spice-debug actually
+ worked or not
+
+2012-04-16 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Clear cache and glz dictionnary on switch-host
+ If we don't clear the glz dictionnary, this might lead to
+ corrupted/invalid dictionnary and invalid memory allocation due
+ unbounded increase of dictionnary size
+
+ Set new cert-subject when switching host
+ https://bugzilla.redhat.com/show_bug.cgi?id=802574
+
+ gtk: scroll event are not received with recent gtk+
+ Add explicit scroll event mask to make it work again.
+
+2012-04-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix cursor hide not hiding in some cases
+ cursor_set() didn't un-hide correctly by setting "show_cursor" to
+ NULL.
+
+ The code is simplified a bit in server mode case, where the new cursor
+ will be invalidated and shown during cursor move only, instead of
+ twice (checked no regression with dual-head server mode)
+
+2012-04-06 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix crash when closing while recording
+ First notify about disconnection before resetting the channel data.
+ An audio recording task might expect the channel to be in a ready
+ state otherwise, for example.
+
+ https://bugzilla.redhat.com/show_bug.cgi?id=810247
+
+2012-04-05 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ agent: avoid use of alloca for sending large msg
+ Instead of allocating unbounded memory and doing extra copy on the
+ stack, let's just improve our helper function to send messages in
+ various pieces.
+
+ See also: https://bugzilla.redhat.com/show_bug.cgi?id=809145
+
+2012-04-04 Christophe Fergeau <cfergeau@redhat.com>
+
+ autogen.sh: default to --enable-vala when building from git
+ People using autogen.sh are likely to be building from git, so may
+ get updates to vala files at any time. Checking for the presence of
+ controller.vala.stamp to decide whether vala should be enabled or not
+ is not very accurate since it doesn't reflect if a .vala file needs
+ to be regenerated or not.
+ It's better to always pass --enable-vala to configure, it's always
+ possible to disable it by using --disable-vala as an autogen.sh argument.
+
+ controller: handle USB redirection messages
+
+ autogen.sh: log configure command line
+ Since --enable-vala may or may not be passed to configure, seeing
+ the actual command line that was used is helpful.
+
+2012-04-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ fix build with glib < 2.32
+ Reported and verified by Nicolas Prochazka
+
+2012-04-03 Hans de Goede <hdegoede@redhat.com>
+
+ SpiceDisplay: Fix rounding of mouse motion events with GTK-3.0
+ Before this patch we were assuming that the GdkEventMotion value we receive
+ are always whole (integer) numbers, which is not the case with GTK-3.0.
+
+ SpiceDisplay: Don't try to scale mouse coordinates when we're not scaling
+ Often (when not resized by the user) even though scaling is enabled, we are
+ not actually scaling. In this case it is not necessary to scale the
+ mouse coordinates, and sometimes it is even harmful.
+
+2012-04-03 Yonit Halperin <yhalperi@redhat.com>
+
+ controller: add support for DISABLE_EFFECTS and COLOR_DEPTH
+ rhbz #787449
+
+2012-03-31 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Handle grab-broken event
+ This fixes the pointer being "trapped" in the center of the screen in
+ server-side mouse mode. It also correctly inform the client that the
+ pointer/keyboard is no longer grabbed so it can adjust its UI state
+ accordingly (remote the "press ctrl+alt to ungrab" messages etc).
+
+ I can reproduce only with RHEVM22 host, and a RHEL6 guest, when
+ switching consoles.
+
+ widget: fix invalid memory ref after channel is distroyed
+ When the display channel is destroyed, we disconnect all signals
+ handlers, but we don't remove the reference on the primary surface
+ data, and that can lead to crashes in a later expose event, reusing
+ the canvas surface (ex, if scaling is disabled). Call
+ primary_destroy() when disconnecting the channel from the widget.
+
+ We now keep the primary surface during channel reset (right after
+ disconnect for example), so the primary surface can be eventually
+ recycled, and the widget still holds a valid reference until the
+ signal is received. The primary surface is ultimately destroyed during
+ finalize, or if the new primary surface size doesn't match.
+
+ Program received signal SIGSEGV, Segmentation fault.
+ __memmove_ssse3_back () at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:2130
+ 2130 lddqu -68(%rsi), %xmm0
+ Missing separate debuginfos, use: debuginfo-install gtk2-engines-2.20.2-2.fc15.x86_64 libusb1-1.0.9-0.3.rc1.fc16.x86_64 p11-kit-0.6-1.fc16.x86_64
+ (gdb) bt
+ at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:2130
+ srclen=<optimized out>, srcinc=4096, destinc=68, height=<optimized out>,
+ half_order=0) at /usr/include/bits/string3.h:52
+ dest_bits_per_pixel=32, req_yoffset=<optimized out>, req_xoffset=0,
+ image=0x7fffffffb9a0, req=<optimized out>, dpy=0x64a630) at PutImage.c:821
+ req_height=<optimized out>, req_width=<optimized out>, y=<optimized out>,
+ x=0, req_yoffset=<optimized out>, req_xoffset=0, image=0x7fffffffb9a0,
+ gc=0xa817e0, d=33554452, dpy=0x64a630) at PutImage.c:870
+ req_xoffset=0, req_yoffset=<optimized out>, x=0, y=26, req_width=17,
+ req_height=20, dest_bits_per_pixel=32, dest_scanline_pad=32)
+ at PutImage.c:908
+ image=0x7fffffffb9a0, req_xoffset=0, req_yoffset=0, x=0, y=26,
+ req_width=17, req_height=20) at PutImage.c:1027
+ image=<optimized out>, src_x=0, src_y=0, width=17, height=20, dst_x=0,
+ dst_y=26) at cairo-xlib-surface.c:1357
+ ---Type <return> to continue, or q <return> to quit---c
+ height=20, width=17, dst_y=26, dst_x=0, src_y=<optimized out>,
+ src_x=<optimized out>, pattern=0x7fffffffc6b0, op=CAIRO_OPERATOR_OVER,
+ surface=0xb9a650) at cairo-xlib-surface.c:2403
+ dst_y=26, dst_x=0, mask_y=0, mask_x=0, src_y=26, src_x=0,
+ abstract_dst=0xb9a650, mask_pattern=0x0, src_pattern=0x7fffffffc6b0,
+ op=CAIRO_OPERATOR_OVER) at cairo-xlib-surface.c:2452
+ src_pattern=0x7fffffffc6b0, mask_pattern=0x0, abstract_dst=0xb9a650,
+ src_x=0, src_y=26, mask_x=0, mask_y=0, dst_x=0, dst_y=26, width=17,
+ height=20, clip_region=0x0) at cairo-xlib-surface.c:2415
+ src=0x7fffffffc6b0, mask=0x0, dst=0xb9a650, src_x=0, src_y=26, mask_x=0,
+ mask_y=0, dst_x=0, dst_y=26, width=17, height=20, clip_region=0x0)
+ at cairo-surface.c:1802
+ traps=0x7fffffffbee0, src=0x7fffffffc6b0, op=CAIRO_OPERATOR_OVER,
+ dst=0xb9a650) at cairo-surface-fallback.c:762
+ op=CAIRO_OPERATOR_OVER, dst=0xb9a650, traps=0x7fffffffbee0,
+ antialias=CAIRO_ANTIALIAS_DEFAULT, clip=0x0, extents=0x7fffffffc600)
+ at cairo-surface-fallback.c:812
+ ---Type <return> to continue, or q <return> to quit---bt
+ op=CAIRO_OPERATOR_OVER, source=0x7fffffffc6b0, clip=0x0)
+ at cairo-surface-fallback.c:935
+ source=0x7fffffffc6b0, op=CAIRO_OPERATOR_OVER, surface=0xb9a650)
+ at cairo-surface.c:2027
+ source=0x7fffffffc6b0, clip=0x7fffffffc7b0) at cairo-surface.c:1993
+ at cairo-gstate.c:1049
+ at spice-widget-cairo.c:104
+ expose=0x7fffffffceb0) at spice-widget-cairo.c:133
+ expose=0x7fffffffceb0) at spice-widget.c:885
+ return_value=0x7fffffffca60, n_param_values=<optimized out>,
+ param_values=0x7fffffffcad0, invocation_hint=<optimized out>,
+ marshal_data=<optimized out>) at gtkmarshalers.c:86
+ return_value=0x7fffffffca60, n_param_values=2,
+ param_values=0x7fffffffcad0, invocation_hint=<optimized out>)
+ ---Type <return> to continue, or q <return> to quit---c
+ at gclosure.c:777
+ detail=0, instance=<optimized out>, emission_return=0x7fffffffccb0,
+ instance_and_params=0x7fffffffcad0) at gsignal.c:3584
+ signal_id=<optimized out>, detail=0, var_args=<optimized out>)
+ at gsignal.c:3305
+ signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3351
+ event=0x7fffffffceb0) at gtkwidget.c:4999
+
+ mjpeg: fix blue-tinted video stream with old server
+ The major == 1 uses RGB colorspace for mjpeg streams.
+
+2012-03-30 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ session: take pubkey reference in setter
+ The session assumed it owned a reference to it.
+ But it didn't get it, and that lead to invalid memory access.
+
+ Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=802574
+
+ Be more tolerant on NULL arrays
+ 2 places where we should be more carreful with NULL arrays, and we can
+ avoid potential crashes.
+
+2012-03-29 Hans de Goede <hdegoede@redhat.com>
+
+ usb-device-widget: Call set_active on the toggle_button, not the alignment
+ Since the gnome HIG-ifying of usb-device-widget.c, the vbox contains
+ alignments, which in turn contain a toggle_button, so calling
+ gtk_toggle_button_set_active directly on the vbox-containers childdren is
+ wrong.
+
+2012-03-29 Uri Lublin <uril@redhat.com>
+
+ usb-acl-helper: add a missing "break"
+
+2012-03-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: move codegen & proto to spice-common
+ With this iteration, all the spice_codegen.py/proto/marshaller
+ generation has been moved to spice-common.
+
+ The spice-common directory will ship spice-protocol, since it's needed
+ there too to build libspice-common.
+
+ Again, make distcheck passes. Build with mingw & fedora linux.
+
+2012-03-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Always release shm of primary surfaces
+ Always remove shared memory segment of primary surfaces when
+ destroying its canvas.
+
+ controllers: signal when a client is connected
+
+ controller: handle SEND_CAD message as a property
+
+2012-03-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix cursor not being shown in client mode in some cases
+ The following seems to happen:
+ - cursor-hide (for all cursor/display channels)
+ - cursor-set (for all cursor/display channels)
+
+ All cursor/display channels receive cursor-set events when the cursor
+ is changed, however, only current display cursor should be drawn in
+ server-mode. How to know which display?
+
+ So it will wait until cursor-move to draw it in server-mode on the
+ right display.
+
+ In the case of client-mode cursor, it doesn't matter since it will
+ depend on which client display the pointer is, so it can be changed
+ immediately.
+
+2012-03-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: fix make distclean going twice in vapi dir
+ Don't use DIST_SUBDIRS, it's not needed anyway.
+
+ build-sys: fix compilation of bindings
+ Hide symbol from API to fix pygobject.
+
+ Also vapigen chokes on "record" typename
+
+ SpiceClientGtk-3.0.gir:32.55-32.55: error: The type name `Gtk.BoxClass' could not be found <type name="Gtk.BoxClass" c:type="GtkBoxClass"/>
+
+ This seems to be a bug in symbol lookup in vapigen. Using a struct
+ typedef solves it.
+
+ doc: gtk-doc cleanup
+ Fix all the unused symbols and a few warnings (a lot left)
+
+ Add SPICE_DISABLE_DEPRECATED guard
+
+ build-sys: improve maintainer clean
+
+ build-sys: use new git.mk
+
+2012-03-19 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Hide cursor when it is on a different screen in server mode
+ When the cursor shape is changed, all the cursor channels are
+ updated. The current code assumed that the "set" of the shape should
+ show the cursor, but it should stay hidden instead.
+
+ Also, when the cursor is hidden, we must invalidate its current
+ region to redraw display.
+
+ Fix: https://bugzilla.redhat.com/show_bug.cgi?id=804308
+
+2012-03-18 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Do not grab display widget
+ We used to gtk_grab_add() after mouse grab to limit the mouse events
+ to the display. But it isn't necessary if the display has its own
+ window, since gdk_pointer_grab() will be limited to it.
+
+ Note the widget has the keyboard focus & is focused, so this doesn't
+ affect keyboard events.
+
+ However, this allows application to keep global accelerators
+ functionning if they want to (like virt-viewer with custom key
+ bindings).
+
+ Notify agent-connected property change
+
+ Improve spice_main_set_display_enabled()
+ Check given display id is within the range of array.
+ Allows to be call with -1 to turn set all displays.
+
+ Fix non-semi-seamless migration in spicy
+ The windows are destroyed during non-semi-seamless migrations, but the
+ gtk session and connected handlers remains. When a property changes
+ again on it, it will signal a destroyed window and lead to a crash.
+
+ The signal handler should be disconnected when the window is
+ destroyed. Since we have N numbers of handlers, it's easier to use
+ spice_signal_connect_object() helper to handle this for us by turning
+ spice_window structure into a basic GObject.
+
+ That GObject code could be improved, but that wasn't the goal of this
+ patch.
+
+ Use given color depth in monitor configuration
+ The main channel only relied on
+ VD_AGENT_DISPLAY_CONFIG_FLAG_SET_COLOR_DEPTH to set color depth when
+ connecting to a guest. However, that doesn't seem to be
+ enough. Instead send given color depth with monitor configuration.
+
+ Fix --spice-color-depth option not "apparently" working.
+
+2012-03-16 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build-sys: if stow is installed, default prefix to it
+ This is going to make life easier for stow users, including myself.
+
+ build: fix build with glib < 2.32
+ Using GMutex as a static mutex is only possible since 2.32.
+
+ Add a G_GNUC_NORETURN to a function that exits
+
+2012-03-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ use common submodule
+
+ Fix incorrect array size check
+
+2012-03-14 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Move undef FORTIFY below config.h
+ It used to be below, then was moved on top of all, but now it's
+ defined in config.h. Hopefully below config.h is the right
+ place. config.h should never have direct includes anyway.
+
+2012-03-14 Hans de Goede <hdegoede@redhat.com>
+
+ buildsys: Disable some warnings
+ Mostly so that they don't turn into errors when building from source:
+ -Wno-missing-field-initializers:
+ Because this has to be close to the most stupid warning gcc has ever produced
+ -Wno-deprecated-declarations
+ Because we use some deprecated functions to avoid #ifdef hell while maintaining
+ compat with older gtk / glib versions
+
+ usbredir: Check for existing usb channels after libusb init
+ Currently trying to view a usbredir enabled vm from virt-manager causes
+ virt-manager to crash. This crash is caused by the following happening:
+
+ -virt-manager sets up the session, including connecting all the channels
+ -a spice-gtk internal code path calls spice_usb_device_manager_get()
+ -spice_usb_device_manager_get calls channel_new on all already connected
+ usb channels
+ -channel_new does:
+ spice_usbredir_channel_set_context(SPICE_USBREDIR_CHANNEL(channel),
+ self->priv->context);
+ -But self->priv->context has not been set yet (so is NULL) -> segfault!
+
+ This patch fixes this by moving the iterating over already connected
+ usb channels to after the setting of self->priv->context. Note this means
+ that the channels will no longer get checked when there is no USB_REDIR
+ support. That is not a problem since spice_usb_device_manager_initable_init
+ will return FALSE in that case anyways.
+
+2012-03-14 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Use GTK_DISABLE_DEPRECATED to avoid inclusion of problematic headers
+ /usr/i686-w64-mingw32/sys-root/mingw/include/gtk-2.0/gtk/gtkitemfactory.h:47:1: error: function declaration isn't a prototype [-Werror=strict-prototypes]
+
+ Fix 'libintl_printf' is an unrecognized format function
+ ../common/lz.h:18:5: error: 'libintl_printf' is an unrecognized format function type [-Werror=format]
+
+ Remove deprecation warnings
+
+2012-03-14 Daniel P. Berrange <berrange@redhat.com>
+
+ Disable -Wwrite-strings for Python binding
+ The code generator for the python binding generates code which
+ throws away const-ness on strings. Disable the -Wwrite-strings
+ warning to avoid failing on this auto-generated code.
+
+2012-03-13 Daniel P. Berrange <berrange@redhat.com>
+
+ Replace %02hhx with %02x in UUID format
+ Use of 'hh' in the UUID format string is not required. Furthermore
+ it causes errors on Mingw32, where the 'hh' modifier is not supported
+
+ Import GNULIB's GCC warning macros
+ GNULIB has a helpful module 'manywarnings' which makes it easy
+ to turn on every single GCC warning. The general goal is that
+ every possible GCC warning should be enabled, except for certain
+ blacklisted warnings.
+
+ This imports the GNULIB m4 macros, and updates configure.ac to
+ use this new capability. As & when new GCC warnings are created,
+ the 'manywarnings.m4' can be refreshed from upstream GNULIB
+
+ * m4/manywarnings.m4, m4/warnings.m4: GNULIB warning macros
+ * configure.ac: Remove custom compiler warning checks
+ * m4/spice-compile-warnings.m4: Decide what GCC warnings to enable
+
+ Avoid 'goto' jumping over variable initialization
+ When a goto statement jumps over a variable declaration with an
+ initializer, the state of that variable is undefined. Move the
+ declaration further up, so that the goto doesn't jump over it.
+ This lets the compiler then warn, if the goto jump results in
+ use of undefined values.
+
+ Fix no-arg functions declared () to use (void)
+ * common/quic.h, common/rop3.h, common/sw_canvas.h: s/()/(void)/
+
+ Add missing includes & make some functions static
+ A number of functions were used without prior declaration. In
+ some cases this was due to missing include files. In other cases
+ the functions should have just been static.
+
+ Ideally this would allow -Wmissing-declarations to be enabled, but
+ the files generated by spice_codegen.py will still trip up on this.
+
+ Ensure all no-args methods are declared (void) not ()
+ * common/quic.c, common/rop3.c, common/sw_canvas.c,
+ gtk/spice-client-glib-usb-acl-helper.c: s/()/(void)/
+
+ Add printf format annotations to all '...' functions
+ To allow the compile to detect incorrect printf formats, any
+ var-args function should have a format annotation
+
+ * common/macros.h: Helper to define ATTR_PRINTF for code
+ which can't depend on glib
+ * common/canvas_base.c, common/lz.h, common/macros.h: Annotate
+ some var-args methods
+
+ Replace duplicated header declarations
+ The usb-helper-acl.h header file duplicated some declarations
+ already present in usb-device-manager.h
+
+ The channel-display.c file declared the object init function
+ which is already done by the GObject helper macros
+
+ * gtk/channel-display.c: Remove duplicate decl of init function
+ * gtk/usb-acl-helper.h: Remove duplicate decls
+
+ Remove arithmetic on void* pointers
+ Arithmetic on void * pointers is undefined by the C standard.
+ Convert the one case of this to use guint8 instead.
+
+ * gtk/channel-main.c: s/void */guint8 */
+
+ Fix some integer range checks which always evaluate false
+ There are some integer range checks which always evaluate false
+ due to use of unsigned integer types. One of these would prevent
+ detection of encoding errors from celt. The others are simply
+ no-ops.
+
+ * gtk/channel-record.c: Make 'frame_size' signed to allow detection
+ of celt encoding errors
+ * gtk/spicy.c: nkeys is an unsigned type, so checks for nkeys < 0 are bogus
+ * common/pixman_utils.c: SpiceROP is an enum & thus unsigned
+
+ Avoid warnings about empty conditional statement bodies
+ Add extra {} braces around if/else statements which only
+ call SPICE_DEBUG to avoid:
+
+ ../common/ssl_verify.c: In function 'verify_pubkey':
+ ../common/ssl_verify.c:87:50: warning: suggest braces around empty body in an 'else' statement [-Wempty-body]
+ ../common/ssl_verify.c: In function 'verify_hostname':
+ ../common/ssl_verify.c:254:53: warning: suggest braces around empty body in an 'if' statement [-Wempty-body]
+ ../common/ssl_verify.c: In function 'verify_subject':
+ ../common/ssl_verify.c:381:41: warning: suggest braces around empty body in an 'else' statement [-Wempty-body]
+
+ Fix deprecation warning handling
+ Various methods are deprecated by using the G_GNUC_DEPRECATED_FOR
+ macro. Unfortunately this macro was placed in the .c file impl,
+ instead of the .h file decl. Thus applications building against
+ SPICE-GTK would never see the deprecation warnings. At the same
+ time, building SPICE-GTK itself would trigger some of the warnings
+ preventing use of -Wdeprecated-declarations to detect use of
+ deprecated GTK functions.
+
+ The fix is in multiple parts
+
+ * Replace calls to G_GNUC_DEPRECATED_FOR with SPICE_DEPRECATED_FOR
+ * Move macros from .c to .h files
+ * Turn SPICE_DEPRECATED_FOR into a no-op if SPICE_NO_DEPRECATED
+ is defined
+ * Define SPICE_NO_DEPRECATED when building
+
+ Fix old style declaration where 'inline' came after return type
+ Fix a case of 'static int inline' to be 'static inline int'
+
+ Fix const-correctness of functions & add explicit casts
+ Some functions should be declared to take const char * instead
+ of plain char *. In other places we intentionally cast away
+ const-ness, so we should add explicit casts to stop compiler
+ warnings
+
+ Remove non-existant include directories from CFLAGS
+
+ Don't delete gtk-doc.make in distclean
+ gtk-doc.make is created by autogen.sh, therefore it should
+ not be deleted in distclean, only maintainerclean
+
+2012-03-08 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release v0.11
+
+ Update since annotation for some session properties
+
+2012-03-08 Hans de Goede <hdegoede@redhat.com>
+
+ channel-usbredir: Handle some more usbredirhost_read_guest_data errors
+
+2012-03-08 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Do not warn when starting spicy if usbredir is disabled
+
+ sasl: sasl authentication failure results in disconnection
+ When SASL auth failure happen, the Spice server disconnects the
+ client. Sadly, this is not easily distinguishable from an IO error.
+ However, since it happens during authentication phase it is better to
+ error out an authentication error.
+
+ sasl: lower visibility of normal debug message
+ Those two g_critical() can happen when collecting credentials for the
+ first time. It is not something to be warned about, but merely useful
+ for debugging
+
+ build: move @SPICE_GLIB_REQUIRES@ to Requires.private
+ The libraries listed in Requires aren't needed during build time, they
+ are library depedencies. And since this is only needed if linking
+ statically, we can safely move them to Requires.private.
+
+ Succesfully tested change with compilation against virt-viewer.
+
+ Later, this will also help fixing bug rhbz #799112.
+
+2012-03-06 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix semi-seamless migration handling
+ SPICE_MSGC_MAIN_MIGRATE_END was dropped because the main channel was
+ xmit_queue_blocked. When we swap the channels, we should also swap
+ xmit_queue.
+
+2012-03-05 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Warn if a message is dropped (before connection or after reset)
+ Since c2ba62666beaee526e1b4288f9bd66976ce780ef messages can be ignored
+ when a channel is reset. A warning can help explain why some messages
+ are dropped.
+
+ Support name & uuid
+ Allows a client to identify the server it is connected to.
+
+2012-02-29 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Add a spice-controller-dump testing tool
+ By default, start a controller listener.
+ If ran with --menu, start a foreign-menu listener.
+
+ Add controller foreign menu support
+
+ Fix a few warnings on windows build
+
+ Allow open_fd() to be called with -1
+ In this case, a valid fd will be requested via the
+ SpiceChannel::open-fd signal.
+
+2012-02-24 Hans de Goede <hdegoede@redhat.com>
+
+ buildsys: Don't link glib-compat.o into libspice-client-gtk.so
+ glib-compat.c was added to SPICE_GTK_SOURCES_COMMON since with the
+ new SpiceUsbDeviceWidget libspice-client-gtk now also uses G_TYPE_ERROR
+ and when compiling with an older glib this gets defined in glib-compat.o
+
+ However doing this turns out to be a very BAD idea, since having
+ glib-compat.o linked into 2 different libraries, each defining there
+ own private spice_error_get_type, leads to the "GError" type getting
+ registered twice with glib, which it does not like.
+
+ So instead of linking glib-compat into 2 different libraries, put it only
+ in libspice-client-glib and export spice_error_get_type from
+ libspice-client-glib (this is ofcourse intended for libspice-client-gtk
+ private use only).
+
+ Fix building with policykit < 0.101
+
+2012-02-23 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release v0.10
+
+ use :glz-window-size not :glz_window_size
+
+ build: fix build with recent mingw64
+ Christophe did similar patches for common/ directory in spice. Some
+ day, we should try to sync and move common/ to a spice-common
+ project...
+
+2012-02-22 Hans de Goede <hdegoede@redhat.com>
+
+ usbredir: Add awareness of host/guest side filtering
+
+ usbredir: Add a spice_usb_device_manager_can_redirect_device function
+ Add a spice_usb_device_manager_can_redirect_device function and use this
+ in SpiceUsbDeviceWidget to check if redirection is available.
+
+ usb-device-widget: Use an info_bar for error messages
+ And in general gnome-hig-ify usb-device-widget:
+ * Use spacing instead of padding so that there is no padding at the
+ outside/border of the widget, allowing the user to control the border size.
+ * Use multiple of 6 as spacing / indentation values
+ * Show the label left justified and bold, show the checkboxes (and the info
+ bar) 12 pixels indented from the label
+
+ configure: Fix "USB redirection support" summary on --disable-usbredir
+ When running "./configure --disable-usbredir" the
+ "USB redirection support" line in the summary at the end of ./configure
+ would be empty after "support" instead of ending with yes or no.
+
+ usbredir: Treat the user cancelling the policykit dialog as a cancel
+ Rather then treating it as any other error. This avoids showing an error
+ dialog after the user pressed cancel in the policykit dialog.
+
+ usbredir: Add device rejected errors
+
+2012-02-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ RFC: Use spice protocol as a submodule
+ Spice protocol contains only headers. We would like to be able to use
+ a protocol update without having to wait for the release, a git
+ submodule works well for this purpose.
+
+2012-02-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix make distcheck
+
+2012-02-20 Hans de Goede <hdegoede@redhat.com>
+
+ usbredir: Shrink the usb device selection dialog when devices are unplugged
+
+ usbredir: make channel lifetime equal to session lifetime
+
+ usbutil: Add support for getting strings from usb.ids
+ Unfortunately not all device makers go to the "trouble" of adding device
+ identification strings to a device's descriptors. This patch makes spice-gtk
+ translate vid/pid into strings if the device lacks the strings.
+
+ usbutil: Add a spice_usb_util_get_device_strings helper function
+
+ usb: Move various helper functions into usbutil.[c,h]
+
+2012-02-17 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Add controller ENABLE_SMARTCARD message
+
+2012-02-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ widget: fix mouse wrapping failing when the window is outside
+ Use a anchor mouse position after every move, similar to spicec to
+ avoid reaching transparent border on the screen.
+
+ We try to move to the center of the screen, but
+ gdk_display_warp_pointer () will move the cursor within the grabbed
+ window (so it still receives mouse events even on Windows)
+
+ Tested with Linux and Windows clients.
+
+ Fixes bug: https://bugs.freedesktop.org/show_bug.cgi?id=45595
+
+2012-02-13 Nicolas Prochazka <prochazka.nicolas@gmail.com>
+
+ Set keepalive on channel socket
+ Without keepalive on each connection(channel), channel is destroyed
+ after ip_conntrack_tcp_timeout_established timeout.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=45899
+
+2012-02-12 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Use an openssl BIO stream using GSocket
+ Until now, the BIO object used by openssl to read & write was using
+ the socket fd directly. But the mainloop integration is done with
+ GSocket.
+
+ On Windows, the read/write events are cleared after
+ g_socket_send()/receive() with private function
+ _win32_unset_event_mask. If the glib functions aren't cleared, glib
+ source will keep notifying of data available in or out. On Windows,
+ this causes a busy loop when doing SSL_read() for example (glib
+ POLL_IN data condition is reached and SSL_read() return needs data).
+
+ Instead, openssl should read/write using GSocket methods.
+
+2012-02-09 Daniel P. Berrange <berrange@redhat.com>
+
+ Don't warn if setsockopt(TCP_NDELAY) fails with errno==ENOTSUP
+ If connecting to a UNIX domain socket, it is expected that the
+ setsockopt(TCP_NDELAY) call will fail with errno=ENOTSUP, so don't
+ issue a warning in that case
+
+2012-02-08 Christophe Fergeau <cfergeau@redhat.com>
+
+ Link with usbredirparser
+ spice-gtk uses usbredirfilter_string_to_rules which is defined
+ in usbredirparser but does not link with it. This causes link errors
+ on some distributions. Fixes fdo bug #45761.
+
+2012-02-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Lower or silence some harmless debug messages
+
+2012-02-02 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ widget: allow defining a zoom-level
+ Add a "zoom-level" property. Maintain the given scaling ratio when
+ scaling is enabled.
+
+ If scaling is disabled, this property is ignored.
+
+ For example at 50%, this allows to fit a 640x480 desktop in a 320x240
+ widget and when resizing it to 640x512 to have a 1280x1024 desktop.
+
+ (this feature is required by virt-viewer)
+
+ widget: factor out update_size_request() and scaling_updated()
+ Factor out and simplify a little the code to allow easier addition of
+ zoom-level property.
+
+ The "set_display" parameter for recalc_geometry() seems to be useless,
+ since the code was apparently trying to set the guest to the given
+ d->width and d->height, but reseting it to the current value, which
+ cancel the effect.
+
+ We should fix the problem of setting the guest resolution at
+ display-init time in a follow-up patch since it probably never worked
+ with spice-gtk.
+
+2012-02-01 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Report the scaling is 1.0 if the widget isn't realized yet
+ To avoid a few warnings in some corner cases.
+
+ Do not grab/release the clipboard on guest without clipboard support
+ Add an agent capability check before calling those functions from
+ gtk-session. Avoid extra warnings.
+
+2012-01-31 Hans de Goede <hdegoede@redhat.com>
+
+ Release 0.9
+
+ Add a USB device selection widget
+ This patch adds a SpiceUsbDeviceWidget which apps can use to easily
+ add an UI to select USB devices to redirect (or unredirect).
+
+ See spicy for an example usage.
+
+2012-01-30 Hans de Goede <hdegoede@redhat.com>
+
+ usb-device-manager: Cleanup USB manufacturer and product strings
+ The strings returned by devices sometimes can benefit from some clean-up.
+
+2012-01-28 Hans de Goede <hdegoede@redhat.com>
+
+ spice-client-glib-usb-acl-helper: Fix mention of Lesser in license header
+
+ spice-client-glib-usb-acl-helper: ensure we set the acl on a chardev
+ Josh Bressers has been so kind to review the usb-acl-helper for possible
+ security issues. One of his recomendations was to ensure that the file
+ we're setting the acl on is a chardev.
+
+ spice-client-glib-usb-acl-helper: Fix memleak
+ Not really important given the short livedness of the process, but
+ still should be fixed.
+
+ configure: Add an option for building the acl helper as PIE
+ Josh Bressers has been so kind to review the usb-acl-helper for possible
+ security issues. One of his recomendations was to harden the usb-acl-helper
+ by building it as a Position Independent Executable.
+
+ configure.ac: s/x"$have_foo"/"x$have_foo"/
+ configure.ac was using 2 slightly different styles for have_foo tests:
+ if test x"$have_foo" = "xyes"; then
+ and:
+ if test "x$have_foo" = "xyes"; then
+
+ Switch to the latter style everywhere for consistency.
+
+ configure.ac: Cleanup policykit checks
+ * No need to set AM_CONDITIONAL WITH_POLKIT from the enable_usbredir tests, it
+ get sets from the enable_polkit tests in all paths
+ * Improve the help text: mention auto as option, policykit -> PolicyKit,
+ not yes but auto is the default
+ * Warn when building with usbredir support but not building the acl helper
+
+2012-01-24 Christophe Fergeau <cfergeau@redhat.com>
+
+ Add check for Perl::Text::CSV
+ This check is only added to configure.ac contrary to the pyparsing
+ patch.
+
+ Add check for pyparsing
+ Check both in configure.ac (after checking if we need to rebuild
+ the marshalling files) and in the python script using pyparsing
+ (for people modifying .proto files in tarballs)
+
+ Use PKG_CHECK_EXISTS for g-i has_symbol_prefix check
+ GOBJECT_INTROSPECTION_CHECK will alread test for the presence of
+ gobject-introspection. The PKG_CHECK_MODULES(GOBJECT_INTROSPECTION)
+ call only needs to set the has_symbol_prefix variable, so we can
+ use PKG_CHECK_EXISTS here, and let GOBJECT_INTROSPECTION_CHECK do
+ the rest of the work.
+
+ Autodetect usbredir and PolicyKit by default
+ Currently, usb redirection and policykit are enabled by default,
+ and configure will error out if the required dependencies cannot
+ be found. This commit changes the default behaviour, by default
+ usb redirection/policykit support is automatically enabled/disabled
+ depending on the availability of the needed dependencies. Passing
+ --enable-usbredir will error out if the dependencies for usb
+ redirection cannot be found, ditto for policykit. This should make
+ things nicer for people running configure or autogen.sh with no
+ argument.
+
+2012-01-24 Yonit Halperin <yhalperi@redhat.com>
+
+ Add command line options for setting the cache size and the glz window size
+ This options will help us tune and find the optimal values.
+
+ Change the setting of the images cache size and the glz window size
+ Set the default sizes to be the same as in the old linux spice client.
+ cache_size=20M pixels (instead of 32M), window_size=8M pixels for a 64MB
+ dev ram (instead of 16M pixels).
+
+2012-01-24 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: fix vapigen error and warnings
+ Thanks to Jeremy Bicha for the bug report and testing solution.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=45154
+
+2012-01-23 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ controller: use a controller listener abstraction
+ Add a wrapper file for named pipe and socket listener, so we can release
+ tarball with code compatible with windows and unix.
+
+ build: use AM_GLIB_GNU_GETTEXT
+ For some unknown reason, this set DATADIRNAME='share' on Windows,
+ which is what is expected.
+
+ Although some people say only IT_PROG_INTLTOOL is necessary, it gets
+ the path wrong in this case too.
+
+2012-01-18 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk-session: weak reference the session for clipboard cb
+ It seems Gtk is lacking a way to cancel a gtk_clipboard_request_*().
+
+ Although it seems like gtk_selection_remove_all() would solve that
+ problem, it will have nasty effect of destroying other pending
+ requests from others..
+
+ Let's make use of an extra weak reference object that will be nulled
+ when the session is destroyed.
+
+ This should help solving the follwing bug:
+ https://bugzilla.redhat.com/show_bug.cgi?id=743773
+
+ gtk-session: ignore destroy of outdated main channel
+ This solves clipboard sharing not working with a password protected
+ server, since new main channel are created for each connection
+ attempt.
+
+2012-01-17 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: allow out-of-tree building of python bindings
+
+2012-01-17 Hans de Goede <hdegoede@redhat.com>
+
+ spice-channel: Allow calling spice_msg_out_send from any context
+ spice_msg_out can be not only called from system context and usb event
+ handling thread context, but also from co-routine context. Calling from
+ co-routine context happens when a response gets send synchronously from
+ the handle_msg handler for a certain received packet. This happens with
+ certain usbredir commands.
+
+ This triggers the following assert in the coroutine code:
+ "GSpice-CRITICAL **: g_coroutine_wakeup: assertion `coroutine !=
+ g_coroutine_self()' failed"
+
+ This patch fixes this by making spice_msg_out_send callable from any
+ context and at the same time changing the code to not do unnecessary
+ wakeups.
+
+2012-01-16 Hans de Goede <hdegoede@redhat.com>
+
+ gtk/display: Get rid of old FSF address in copyright headers
+ rpmlint pointed this out while I was checking the new spice-gtk-0.8 package
+ for Fedora.
+
+2012-01-16 Christophe Fergeau <cfergeau@redhat.com>
+
+ Handle spice_audio_new failures
+ spice_audio_new can return a NULL pointer when there's a failure
+ during the initialization of the audio system. When this happens,
+ we shouldn't keep initializing the spice audio channel as if nothing
+ happened, but just stop the connection.
+ This can be tested by forcing the "self" variable to NULL in
+ spice_audio_new
+ This should fix https://bugzilla.redhat.com/show_bug.cgi?id=772118
+
+2012-01-16 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release 0.8
+
+ Generate ChangeLog and ship it in the tarball
+
+ Send grab-key signal even in mouse client mode
+
+2012-01-15 Hans de Goede <hdegoede@redhat.com>
+
+ usbredir: Add support for filtering out devices from auto-redirection
+ Note this patch adds a default filter filtering out HID devices, since
+ redirecting ie a mouse plugged into a laptop is usually not what the user
+ wants. Also sometimes usb keyboards/mice may experience a glitch causing
+ them to temporarily drop of the bus. If this happens when the spice-client
+ has focussed it used to redirect them to the vm when they re-appeared,
+ not good!
+
+2012-01-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix compilation on mingw/windows
+
+ Warn if windows keyboard hook failed
+
+ Don't release images after the tail gap
+ This fix a hang on an image lookup that has already been remved. It
+ only happens in multihead, when stressing a bit the displays.
+
+ The decoder assumed that the last added images is the tail of the
+ window. However, there are "gaps" in the window that will be filled by
+ other channels. Instead of taking the last added image as the current
+ up to date tail, let's take the reference to the last image before the
+ first gap as the up to date tail, and release from there.
+
+ The spicec code does things differently, perhaps it needs slightly
+ less memory at the cost of added complexity by maintaining list of
+ missing images and much more conditions/synchronization.
+
+ Grab focus before grabing keyboard
+ Make sure the display has the focus before grabing the keyboard for
+ the application.
+
+2012-01-12 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ wait for cached images that haven't been added to the cache yet
+ https://bugs.freedesktop.org/show_bug.cgi?id=44570
+
+ Log if condition wait got cancelled
+ https://bugs.freedesktop.org/show_bug.cgi?id=44570
+
+ Make g_coroutine_condition_wait() cancellable
+ https://bugs.freedesktop.org/show_bug.cgi?id=44570
+
+ Remove the non-interruptible version g_io_wait()
+ Use the common g_coroutine_socket_wait()
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=44570
+
+ Create a GCoroutine, get rid of wait_queue
+ https://bugs.freedesktop.org/show_bug.cgi?id=44570
+
+ Hide g_condition_wait_source, use GLib style convention
+ https://bugs.freedesktop.org/show_bug.cgi?id=44570
+
+ Lower connection error from warning to debug, it's normal to fail
+ We try several connections, so it's normal to fail for some.
+ No need to warn.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=44570
+
+ Lower our gtk+ requirement to 2.18, as we claim
+ Needed to build on RHEL6
+
+ Lower polkit requirement to 0.96
+
+ Lower our glib requirement to 2.22, as we claim
+ Required to build on RHEL, even upcoming 6.3
+
+2012-01-11 Yonit Halperin <yhalperi@redhat.com>
+
+ migration: swap serials and mini header support when swapping peers.
+
+ Add support for SPICE_COMMON_CAP_MINI_HEADER
+ Don't send/receive serial and sub_list when the server supports the
+ above cap.
+
+ spice-channel: support SPICE_MSG_LIST
+
+ configure: spice-protocol >= 0.10.1 (support mini header)
+
+2012-01-08 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Wait for channels before invalidating images
+ https://bugs.freedesktop.org/show_bug.cgi?id=44179
+
+ Implement SPICE_MSG_WAIT_FOR_CHANNELS
+ https://bugs.freedesktop.org/show_bug.cgi?id=44179
+
+2012-01-07 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ add optional format string to spice_usb_device_get_description()
+
+2012-01-07 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ build: oops, fix previous commit
+
+2012-01-06 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ build: fix compilation with --disable-usbredir
+
+2012-01-05 Alon Levy <alevy@redhat.com>
+
+ spice-session: support uri with colon
+ With this patch if you use:
+ spice://<host>:<port>
+
+ it will be treated the same as:
+ spice://<host>?port=<port>
+
+ You will also get a warning for the following double port definitions:
+ spice://<host>:<port1>?port=<port2>
+ spice://<host>:<port1>:<port2>
+
+ (similar to the double key warnings introduced in the previous commits)
+
+ spice-session/spice_uri_parse: fail if a key is seen twice
+
+2012-01-04 Hans de Goede <hdegoede@redhat.com>
+
+ Makefile: Ensure the acl helper is installed before making it suid root
+ On my system when running make install, after installing the libraries it
+ first executes install-binPROGRAMS:
+
+ /bin/sh ../libtool --mode=install /usr/bin/install -c spicy snappy spicy-st
+ libtool: install: /usr/bin/install -c .libs/spicy /usr/bin/spicy
+ libtool: install: /usr/bin/install -c .libs/snappy /usr/bin/snappy
+ libtool: install: /usr/bin/install -c .libs/spicy-stats /usr/bin/spicy-stats
+
+ Then the install-exec-hook:
+
+ make install-exec-hook
+ make[6]: Entering directory `/home/hans/projects/spice/spice-gtk/gtk'
+ chown root /usr/bin//spice-client-glib-usb-acl-helper
+ chmod u+s /usr/bin//spice-client-glib-usb-acl-helper
+
+ And only then does it install the actual helper by executing
+ install-aclPROGRAMS:
+
+ /bin/sh ../libtool --mode=install /usr/bin/install -c spice-client-glib-usb
+ libtool: install: /usr/bin/install -c spice-client-glib-usb-acl-helper /usr/bin
+
+ Which means that the install-exec-hook runs too early, either there is no
+ spice-client-glib-usb-acl-helper for it to make suid root, or if there is it
+ will later get overwritten and its rights will get reset.
+
+ The problem is that install-fooPROGRAMS gets run as part of install-data,
+ not install-exec. So we can fix this by changing the code to make the helper
+ suid root run from install-data-hook.
+
+ usbredir: Don't directly use g_mutex_foo()
+ In glib <= 2.30 g_mutex_foo() are macro's so dereferencing them directly
+ does not work.
+
+2012-01-03 Hans de Goede <hdegoede@redhat.com>
+
+ usbredir: Don't call spice_usbredir_channel_disconnect on channel reset
+ channel_reset gets called from spice_channel_disconnect, and
+ spice_usbredir_channel_disconnect calls spice_channel_disconnect
+ (so as to disconnect the channel when a usb device gets disconnected).
+
+ So calling spice_usbredir_channel_disconnect from channel_reset leads to
+ undesirable recursion. More over calling spice_usbredir_channel_disconnect
+ disconnects / closes both the channel and *the usb device* and closing the
+ usb device on migration is not what we want.
+
+ Note that currently migration of usbredir channels does not work, and this
+ patch does not fix this, but it does fix a regression when disconnecting
+ usb devices normally (by unplugging them for example).
+
+ usbredir: Give devices a user friendly description
+ Before this patch devices were described like this to the user:
+ USB device at 2-14
+ After this patch the description is:
+ SanDisk Cruzer Blade [0781:5567] at 2-14
+
+ usbredir: Drop our embeddied GUsb copy
+ No that we no longer use GUsbSource we're hardly using any code from GUsb,
+ so drop our embeddied GUsb copy and do the last few things (device
+ enumeration through gudev) ourselves.
+
+ usbredir: Remove spice_usb_device_manager_get main_context argument
+ Now that we no longer use a GUsbSource this is no longer needed.
+
+ Note this is a change to our public API, but that is ok since we have not
+ yet done an official release with usbredir support.
+
+ usbredir: Handle usb events from a thread
+ This solves various latency issues with USB handling.
+
+ usbredir: Add locking callbacks for libusbredirhost
+ This is a preparation patch for handling usb packet completion in a
+ separate thread.
+
+2011-12-22 Hans de Goede <hdegoede@redhat.com>
+
+ usbredir: Create USB event source on demand
+ This is a preparation patch for handling usb packet completion in a
+ separate thread.
+
+ usbredir: Use new libusbredirhost write flush callback
+ The new (in usbredir-0.3.2) usbredirhost_open_full()
+ function allows us to be notified whenever usb packets completing
+ result in data to be send to the host. This removes the need for using
+ g_usb_source_set_callback and seeing if there is data to write on
+ any of the usb channels each time some usb event happens.
+
+ This also bumps the minimum needed libusbredirhost version to 0.3.2
+
+ usbredir: USB channels can not be read only
+ A usbredir channel must always be bi-directional. spice-server
+ allows only one client to connect even when in multi-client mode. Since
+ usually there are multiple usb channels available, it is allowed for one client
+ to use one channel, while another client uses another usb channel.
+
+ usbredir: Stop setting private data explictly to NULL on init
+ This is not necessary and as we get more private data it becomes
+ unyieldly.
+
+ spice-channel: Allow spice_msg_out_send to be called from multiple threads
+ This is a preparation patch for handling usb packet completion in a
+ separate thread.
+
+ spice-channel: setsockopt TCP_NODELAY
+ spicec does this for all channels, and it seems like a good idea to do the
+ same in spice-gtk.
+
+2011-12-22 Christophe Fergeau <cfergeau@redhat.com>
+
+ Disable vala bindings unless --enable-vala is used
+ Currently, building vala bindings from a tarball is broken because
+ spice-client-glib-2.0.deps is missing from the tarball. This commit
+ adds it to EXTRA_DIST and also makes sure the vala bindings don't
+ get built/installed unless --enable-vala has been passed to configure.
+ This means vala must be installed to build the vala bindings from a
+ tarball. Fixes fdo bug #44000.
+
+ Revert previous vala-related commits
+ They were work in progress and not meant to be committed, apologies
+ for the noise :-/
+
+ Only install vala bindings when using --enable-vala
+
+ More distcheck fixes
+
+2011-12-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: ship vala files & fix make distcheck
+ Disable usbredir, since it wants to install file in /.
+
+ Disable vala for distcheck for 2 reasons: not needed after dist and
+ binding build issue.
+
+ Ship with spice-gtk-3.0 vala bindings
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=44000
+
+2011-12-22 Christophe Fergeau <cfergeau@redhat.com>
+
+ Make path to the USB ACL helper configurable
+ It's currently installed in $bindir, but this patch makes it possible
+ for distros like fedora to install it in $libexecdir/spice/
+
+2011-12-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: remove unused common/win/my_getopt
+
+2011-12-22 Jani Välimaa <wally@mageia.org>
+
+ build: string format fix
+ https://bugs.freedesktop.org/show_bug.cgi?id=44019
+
+2011-12-19 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: depends on spice-protocol 0.9.1
+
+ Support semi-seamless migration
+ Yonit Halperin described the flow, that I followed:
+
+ (1) when client_migrate_info is called SPICE_MSG_MAIN_MIGRATE_BEGIN is
+ sent to the client.
+
+ Then, the client should link to the target server (SpiceLinkMess),
+ i.e., connect all the channels, but it shouldn't poll from the target,
+ only from the source. You can refer to RedClient::Migrate class. The
+ connection id in the link message should be the id of the connection
+ to the source server.
+
+ (2) The client sends to the source server
+ SPICE_MSGC_MAIN_MIGRATE_(CONNECTED|CONNECT_ERROR)
+
+ (3) When migration completes SPICE_MSG_MAIN_MIGRATE_(END|CANCEL) is
+ sent to the client.
+
+ (3.1) In case of SPICE_MSG_MAIN_MIGRATE_CANCEL, the client closes the
+ connections to the target.
+
+ (3.2) In case of SPICE_MSG_MAIN_MIGRATE_END, the client should reset
+ all the data that is related to the connection to the source and
+ complete the transition to the target server (without sending
+ ATTACH_CHANNELS, and without guest display initialization via agent).
+
+ Then, the client sends SPICE_MSG_MAIN_MIGRATE_END to the target.
+
+ main: Handle semi-seamless MIGRATION_BEGIN
+
+ display: try to reuse exisiting primary surface
+
+ Add channel_reset method
+ This new private method is to reset the channel to its initial state,
+ used by semi-seamless migration
+
+ gio-coroutine: add a few more run-time checks
+
+ Update protocol and messages for semi-seamless migration
+
+2011-12-19 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ windows: initialize co->ret to not randomly release fiber
+
+2011-12-18 Frédéric Péters <fpeters@0d.be>
+
+ add explicit links against libraries that are directly used
+
+2011-12-16 Hans de Goede <hdegoede@redhat.com>
+
+ spice-channel: cleanup, remove spice_channel_send_msg()
+ There are only 2 callers, both of which want it to do a different thing,
+ making the callers do this directly allows us to remove
+ spice_channel_send_msg(); and gets rid of the weirdness where we've a
+ function which can be called in both co-routine and system context.
+
+ spice-channel: Move read only check to spice_channel_write_msg()
+ This is a preparation patch for removing spice_channel_send_msg().
+
+ Note that this means that buffered writes won't get checked until they are
+ actually send by the co-routine.
+
+ spice-channel: Move setting of header->size to spice_channel_write_msg()
+ Just a small cleanup patch.
+
+ spice-channel: replace the xmit buf by a queue of SpiceOutMsg-s
+ This has a number of advantages:
+ -It significantly simplifies the code
+ -It avoids memcpy-ing all the write data one more time
+ -It avoids malloc / realloc / free of the xmit buffer
+ (this gets replaced by gslice alloc / free for the queue elements)
+
+ Make sure spice_channel_iterate_write() always flushes *all* pending writes
+ This patch changes 1 line, and fixes 2 bugs in this one line:
+ 1) We keep the xmit_buffer around for reuse (re-filling) later, so checking
+ if we've a xmit_buffer to determine wether we should do a write is wrong,
+ instead we should check if the xmit_buffer has data in it.
+ 2) If the write blocks, and we switch to another co-routine context, this
+ context may queue more writes, we check for this and throw away the
+ buffer we've been consuming when this happens, since the other context
+ will then have allocated a new buffer. But when this happens, we do *not*
+ consume the new buffer. So the queued data will not get transmitted
+ until the co-routine gets woken up by either another write, or by
+ receiving data to read.
+ This patch fixes this by changing the if to a while.
+
+ Note that the code in question gets completely removed by the next patch in
+ this series. As I noticed this while rewriting the code in question, still
+ I decided to do a separate patch to fix this to:
+ 1) Document this issue in the old code
+ 2) Otherwise the move from the if to the while will happen in the new code
+ which may confuse readers of that patch.
+
+ spice_msg_out[_send_internal]: Take ownership of the passed SpiceMsgOut
+ All callers of spice_msg_out[_send_internal] unref the message immediately
+ after calling spice_msg_out[_send_internal]. This patch changes the
+ semantics so that spice_msg_out[_send_internal] takes ownership and it
+ is responsible for unref-ing the passed in SpiceMsgOut.
+
+ This is a preparation patch for changing the buffered write code
+ to use a queue of SpiceMsgOut-s, rather then memcpy the message contents
+ into an intermediate buffer.
+
+ channel-smartcard: unref in flight messages as soon as they are sent
+ This is a preparation patch for making spice_msg_out_send() take ownership
+ of the passed in msg.
+
+2011-12-15 Hans de Goede <hdegoede@redhat.com>
+
+ smartcard_message_complete_in_flight cleanup error checking
+ smartcard_message_complete_in_flight should never get called if there
+ is no message in flight (priv->in_flight_message != NULL).
+
+2011-12-14 Hans de Goede <hdegoede@redhat.com>
+
+ spice-channel: cleanup, get rid of wait_interruptible variable
+ The private wait_interruptible channel variable is not used anywhere,
+ except in one test, which is useless since it never gets set.
+
+ Disable mouse accelleration when grabbing the mouse (in server mode)
+ Otherwise accel will be applied twice, once by the client and then once
+ more by the guest. Unfortunately there seems to be no gdk / gtk API for this
+ so this patch uses direct libX11 calls.
+
+2011-12-14 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ windows: fix broken left shift
+ On Windows, the received key when pressing left shift is VK_SHIFT 0x10
+
+2011-12-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Wrap in window, because windows doens't receive mouse events outside it
+
+ windows: clip pointer when grabbed, so it stays inside widget
+
+2011-12-12 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix crash on mouse server mode grab with gtk2
+ With gtk3 gdk_cursor_unref = g_object_unref. But not with older
+ version. Let's be consitent with the rest of the code and use
+ cursor_unref().
+
+ build: add missing smartcard manager in python binding
+ Probably broken since the manually edited defs files have been removed
+
+2011-12-10 Hans de Goede <hdegoede@redhat.com>
+
+ spice-widget: rename mouse_update to update_mouse_mode.
+ We already have update_mouse_pointer and update_mouse_grab, so having
+ a mouse_update function without specifying what "part" of the mouse handling
+ it exactly updates is confusing, rename it to update_mouse_mode to reflect
+ what it does and to match the other names.
+
+ spice-widget: cleanup mouse handling.
+ Some background on this patch, we currently behave
+ as follows in server mouse mode:
+
+ 1) When spicy first connects, a frozen guest cursor is shown
+ (no mouse events are send to the guest) and the client cursor
+ is set to the standard right pointer,
+
+ 2) When one clicks on / inside the spice-widget, the mouse is
+ grabbed, the client cursor is hidden and the guest pointer
+ becomes alive (gets events).
+
+ 3) On ungrab we move back to state 1)
+
+ Which is fine, but the code implementing it is somewhat convoluted.
+ We have update_mouse_pointer(), which does more then just update the mouse
+ pointer, it also calls try_mouse_grab(), and we've update_mouse_grab(),
+ which calls update_mouse_pointer() rather then try_mouse_grab().
+
+ * I. lets look at what we currently have in update_mouse_pointer(): *
+
+ case SPICE_MOUSE_MODE_SERVER:
+ if (!d->mouse_grab_active) {
+ if (gdk_window_get_cursor(window) != NULL)
+ gdk_window_set_cursor(window, NULL);
+ } else {
+ try_mouse_grab(display);
+ }
+ break;
+
+ Now lets invert the test to make it more readable:
+
+ case SPICE_MOUSE_MODE_SERVER:
+ if (d->mouse_grab_active) {
+ try_mouse_grab(display);
+ } else {
+ if (gdk_window_get_cursor(window) != NULL)
+ gdk_window_set_cursor(window, NULL);
+ }
+ break;
+
+ Hmm, so if we're grabbing the mouse, we try to grab the mouse
+ -> does not make sense, esp not since try_mouse_grab() has:
+
+ if (d->mouse_grab_active)
+ return;
+
+ So we can drop the else block.
+
+ But why the if? Well that would be because when we're grabbing
+ the windows should have a blank cursor. But where does that get set?
+
+ The blank cursor gets set in do_pointer_grab(), by specifying a blank
+ cursor as the cursor to show as long as the grab is active.
+
+ Since that cursor will be active as long as we're grabbing, so we can
+ drop the if (!d->mouse_grab_active) check as well.
+
+ And with the mouse_grab_active check gone, we no longer need to call
+ update_mouse_pointer() from try_mouse_ungrab().
+
+ * II. lets look at update_mouse_grab() *
+
+ So currently when the mouse should be grabbed according to the
+ mouse-grab and disable-inputs properties, update_mouse_grab() calls
+ update_mouse_pointer(), which as discussed above does nothing with the grab,
+ as the code path calling try_mouse_grab() is dead code. The right thing to do
+ would of course be to have update_mouse_grab() call try_mouse_grab() in this
+ case.
+
+ But, that would mean that as soon as the property is changed the cursor will
+ get torn away from whereever it is and get grabbed, which may not always
+ be desirable. To fix this this patch also moves the mouse_have_pointer
+ and keyboard_have_focus checks from mouse_update() to try_mouse_grab()
+
+
+ foo
+
+2011-12-09 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: fix build issue because of double declaration
+ Patch based on Mageia, provided by Olav Vitters.
+
+ https://bugzilla.freedesktop.org/show_bug.cgi?id=43457
+
+2011-12-09 Michael Chudobiak <mjc@avtechpulse.com>
+
+ use "connection" instead of "connexion"
+
+2011-12-09 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Take the grab when mouse switching to client mode
+ Only when the widget has the focus and the pointer is over the widget
+
+ Do not send ungrab key sequence to the server
+
+ Don't leak cursor shape objects
+
+ Refresh mouse shape/visibility when changing mouse mode
+ This fixes the dynamic mode changing when running/quitting the agent.
+
+ Correctly hide client pointer (in server mode)
+ The hide cursor event happen when the widget is not yet
+ realized. Forcing realize may fail if the widget is not yet embedded
+ for example. Instead, let's update the cursor whenever there is a
+ draw().
+
+ v2: do not call gdk_window_set_cursor() with the same cursor
+
+ Document the pointer ungrab for drag-n-drop in multihead
+
+ Draw mouse with cairo in server mode
+
+ Ignore the first mouse click when taking the grab
+
+ Grab on the display too
+ Without this additional grab, the pointer grab was effective for the
+ whole application
+
+ Add a get_blank_cursor() helper
+
+ Use the border margin from recalc_geometry()
+
+ Do not send pointer motion of 0x0
+
+ Warn with the connect connect socket error
+
+ Fix controller with newer vala
+
+2011-12-05 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: vapi bindings only available if HAVE_INTROSPECTION
+
+ controller: use SPICE_XPI_NAMEDPIPE first
+
+2011-12-02 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: do not clean spice-client-glib-2.0.deps
+
+ build: fix linking with -Wl,--as-needed -Wl,--no-undefined etc..
+ Mageia is using linker flags and miss symbols when linking.
+ The error can be reproduced with:
+
+ make LDFLAGS="-Wl,--as-needed -Wl,--no-undefined -Wl,-z,relro -Wl,-O1 -Wl,--build-id -Wl,--enable-new-dtags"
+
+ Based on patch by Christophe Fergeau.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=43416
+
+2011-12-02 Hans de Goede <hdegoede@redhat.com>
+
+ usb-device-manager: Don't g_warning on autoconnect failure
+ We already emit a signal for this, either the app using spice-client-glib
+ listens to this signals and does something with it, or it is not interested
+ in this happening, at which point logging a g_warning for it is not really
+ useful.
+
+ spicy: Don't show an error dialog on a cancelled device open
+ If for example the user plugs in a new device, then gets the policykit agent
+ authentication dialog and then unplugs the device, spice-gtk will cancel
+ the acl-helper request, which in turn will dismiss the policykit agent
+ authentication dialog. Which is all a nice and smooth user experience,
+ except that when this happens spicy throws a dialog with an error
+ that the open was cancelled. Since a cancel usually is done deliberately
+ (such as on the user unpluging the device) no error dialog should be thrown
+ for it.
+
+ channel-usbredir: Call the acl helper without first trying to open the device
+ Normally opening the USB device without first calling the helper will fail,
+ except when the process using spice-gtk is running as root.
+
+ So the current code which first tries to open the USB device before calling
+ the helper is optimizing for an exception rather then for the default code
+ path. More over it also causes libusb to print the following errors to stderr:
+ libusb:error [op_open] libusb couldn't open USB device /dev/bus/usb/002/017: Permission denied.
+ libusb:error [op_open] libusb requires write access to USB device nodes.
+
+ So this patch changes things to first call the helper and only then try
+ to open the device node.
+
+ This patch also modifies the helper to not call policykit when called by
+ a root process, since the set_facl which it will do, if policykit says it
+ is ok, is a no-op for root anyways. Instead it directly returns a success
+ status without doing anything when called by a root process.
+
+2011-12-02 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ string formatting fixes
+ Patch based on Mageia, provided by Olav Vitters.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=43456
+
+2011-12-01 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Move auto-connect logic in Audio base class
+
+ Make UsbDeviceManager main-context a boxed property
+
+2011-11-26 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ Fix get_type() with --disable-smartcard
+ It's quite a bad hack, but I can't think of anything really better
+
+ Without this patch, g-ir-scanner introspection hangs with:
+ GLib-GObject-CRITICAL **: g_boxed_type_register_static: assertion `boxed_copy != NULL' failed
+
+ GLib-CRITICAL **: g_once_init_leave: assertion `result != 0' failed
+
+ GLib-GObject-WARNING **: gsignal.c:1585: parameter 1 of type `<invalid>' for sig
+ nal "SpiceSmartcardManager::reader_added" is not a value type
+
+2011-11-23 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Do not send specific messages in read-only
+
+ Check if msg are permitted to be sent in read-only
+
+ Add read-only property on sessions
+ It is useful to have a way to prevent sending commands in read-only
+ sessions (think of multi-client)
+
+ No clipboard sharing allowed in this case in gtk-session.
+
+ Add disable-inputs on Spice widget
+
+ cleanup: the try_grab() functions should take a SpiceDisplay
+
+ Fix a few g-ir-scanner warnings
+
+ Export spice_g_signal_connect_object
+ The helper needs to be accessible from spice-client-gtk too.
+
+ Regenerate map-file correctly
+ We should use update-map-file instead of modifying it manually
+
+2011-11-21 Hans de Goede <hdegoede@redhat.com>
+
+ Release our keyboard grab when we're going to invoke the usb acl helper
+ The usb acl helper asks policykit, which may want to interact with the
+ user through the policykit agent, which wants to grab the keyboard, if
+ we then have the keyboard grabbed, the agent says authentication has failed,
+ policykit rejects the helper opening up the acl and usbredir won't work.
+
+ Unfortunately the only way to work around this is to temporarily release our
+ own keyboard grab, not pretty but as discussed on irc, this is the "best"
+ solution.
+
+2011-11-16 Hans de Goede <hdegoede@redhat.com>
+
+ Add a suid root helper to open usb device nodes
+ spice-client needs to be able to open the device nodes under /dev/bus/usb
+ to be able to redirect a usb device to the guest. Normally opening these
+ nodes is only allowed by root. This patch adds a suid root helper which
+ asks policykit if it is ok to grant raw usb device access, and if policykit
+ says it is ok, opens up the acl so that the spice-client can open the device
+ node.
+
+ As soon as spice-client closes the stdin of the helper, the helper removes
+ the extra rights. This ensures that the acl gets put back to normal even if
+ the spice client crashes. Normally the spice-client closes stdin directly
+ after opening the device node.
+
+ channel-usbredir: Make spice_usbredir_channel_connect async
+ With the (upcoming) introduction of the usb device node acl helper, which
+ uses policykit, spice_usbredir_channel_connect() may take a long time as
+ it will be waiting for the helper, which will be waiting for policykit which
+ may be interacting with the user -> Make spice_usbredir_channel_connect() async
+
+ Note that this patch only changes spice_usbredir_channel_connect's
+ API to use the standard GIO async API, it is not actually async after this
+ patch since it does not yet call the acl helper.
+
+ usb-device-manager: Make spice_usb_device_manager_connect_device async
+ With the (upcoming) introduction of the usb device node acl helper, which
+ uses policykit, spice_usbredir_channel_connect() may take a long time as
+ it will be waiting for the helper, which will be waiting for policykit which
+ may be interacting with the user. So spice_usbredir_channel_connect() will
+ need to become async, and since spice_usb_device_manager_connect_device
+ calls spice_usbredir_channel_connect it thus also needs to become async.
+
+ Note that this patch only changes spice_usb_device_manager_connect_device's
+ API to use the standard GIO async API, it is not actually async after this
+ patch since spice_usbredir_channel_connect is not yet async.
+
+ channel-usbredir: Move usb device opening into a helper function
+ This is a preparation patch for adding the usb device node acl helper
+
+ channel-usbredir: Do disconnect from dispose instead of from finalize
+
+ channel-usbredir: Fixup and simplify #ifdef USE_USBREDIR handling
+ glib does not like it when objects have a private data size of 0, so don't
+ declare any private data when compiling without USE_USBREDIR set.
+
+ Correct Since tag for SpiceSession:enable-usbredir:
+ This was introduced post 0.7, and given the major changes done in git
+ sofar the next release will be 0.8 rather then 0.7.1
+
+2011-11-09 Christophe Fergeau <cfergeau@redhat.com>
+
+ Use correct GLib macros
+
+2011-11-07 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Mark deprecated props/signals/functions
+
+ Remove g_object_{set,get}_data() usage
+ This is not really clean, as it may conflict with client usage
+
+ Drop useless memset
+ Private data in GObject's is initialized to 0's upon constuction
+
+ Use G_PARAM_CONSTRUCT for property initial value
+
+2011-11-05 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Add missing include of spice-audio
+
+ Add session enable-audio property
+ Create audio channels only if enable-audio is TRUE
+
+ SpiceAudio stream name default to get_application_name()
+
+ Add spice_audio_get()
+ We are going to deprecate spice_audio_new()
+ some day. There are a few know problems:
+ - SpiceAudio is an abstract class,
+ so it can't have a ctor
+ - SpiceAudio should be a singleton,
+ associated with the session lifetime
+ - SpiceSession should have a enable-audio property,
+ internal code should be able to access the audio object
+
+ That way of getting the audio object is similar to the smartcard manager and usb manager.
+
+2011-11-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Return NULL if taking screenshot fails
+ It can happen if the display is not yet ready.
+ This change just removes a couple of warnings.
+
+ Fix package `SpiceClientGLib-2.0' not found
+
+2011-11-02 Tiziano Müller <tiziano.mueller@stepping-stone.ch>
+
+ Correctly parse RFC-conform URIs separating the host and the arguments by a '/'
+ Little patch to make spice-gtk accept RFC-conform URLs of the form
+ "spice://host/?port=5901".
+
+ I didn't add '/' to the list of the other characters to ignore (?;&)
+ by intention since an URL like spice://host/?port=5901/somotherstuff
+ should not be valid, resp. the password may contain '/' because the
+ string is already unescaped at that point.
+
+ Unfortunately glib does not seem to have functions to 'explode' an URI
+ which would be really helpful.
+
+ Cheers,
+ Tiziano
+
+2011-11-02 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk-session: add more checks
+
+2011-10-28 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Add missing spice-gtk-session.h in spice-widget.h
+
+2011-10-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Add vapi bindings generation
+
+2011-10-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Fix missing dispose() chain-up
+
+2011-10-19 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ do not segfault if link message header size is set to 0
+ https://bugs.freedesktop.org/show_bug.cgi?id=41988
+
+2011-10-11 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Add SPICE_NOGRAB environment variable for debugging
+
+ gtk: channel-event emit an enum
+ This doesn't break ABI, as int and enum are compatible at glib level.
+
+ gtk: warn if argument is invalid instead of crash
+
+2011-10-10 Hans de Goede <hdegoede@redhat.com>
+
+ Add spice-gtk-session-priv.h to make dist output
+ Brown paper bag bug number 2 wrt spice-gtk-session-priv.h, sorry about this.
+
+ Add missing spice-gtk-session-priv.h file
+ This file was missing from the previous commit, my bad.
+
+ Make auto-usbredir a session setting rather then a per display setting
+
+ spicy: Stop using SpiceDisplay's deprecated clipboard methods
+
+ SpiceDisplay: mark clipboard properties and functions as deprecated
+ The SpiceGtkSession ones should be used instead.
+
+ SpiceDisplay: Don't set auto-clipboard on construction
+ The auto-clipboard setting now lives in the SpiceGtkSession, if that
+ was changed to FALSE (from the default of TRUE) and later a SpiceDisplay
+ was created for this session that would change it back to TRUE again because
+ it would set it to its default from its constructor. This patch fixes this.
+
+ Remove auto-generated .gitignore files from git
+ Auto-generated files do not belong in git. Having these in git causes
+ changes to them accidentally ending up in other commits.
+
+ Fix compilation of python bindings
+ This was broken by the addition of SpiceGtkSession.
+
+2011-10-07 Hans de Goede <hdegoede@redhat.com>
+
+ decode-glz: Handle needing glz images before they have arrived
+ With multi monitor guests, it is possible for a glz-image to refer to
+ bits from another glz-image which has not arrived yet! This can happen
+ because each monitor has its own display channel, and thus its own socket,
+ but they share the glz dict. Thus things can arrive out of order, with a
+ glz-image on display 1 arriving before the glz-image on display 2 which it
+ refers too.
+
+ This triggers the:
+ g_return_val_if_fail(w->images[slot]->hdr.id == id - dist, NULL);
+
+ In glz_decoder_window_bits(), which is what caused me to debug this, once
+ the out order thing was clear, so was the fix.
+ If w->images[slot]->hdr.id == id - dist is not true, we need to wait for the
+ correct image to arrive.
+
+ The out of order issue with multiple monitors can also trigger the
+ g_warn_if_reached() in glz_decoder_window_resize(), so remove that.
+
+ SpiceDisplay: Pass on notify signal from GtkSession for GtkSession properties
+ Since some SpiceDisplay properties are now just a pass through to the
+ equivalent SpiceGtkSession property, we also need to pass on the notify
+ signal for these, so interested users can get notified of them changing.
+
+ Use this in spicy to ensure that changes to SpiceGtkSession (and thus per
+ session rather then per window) properties get reflected in all windows for
+ a multimonitor guest.
+
+ usb-device-manager: One instance per session instead of a singleton
+ Since usb device manager keeps track of which usb channels there are and
+ if they have usb devices attached there should be one usb-device-manager
+ instance per session, rather then one global singleton.
+
+ Tying the usb-device-manager to the session also allows us to get rid of
+ spice_usb_device_manager_[un]register_channel and the need for SpiceDisplay
+ to call these.
+
+2011-10-06 Hans de Goede <hdegoede@redhat.com>
+
+ SpiceDisplay: Add a constructor and construction properties
+ With SpiceDisplay now passing through auto-clipboard settings to
+ SpiceGtkSession, it needs to have its SpiceSession and SpiceGtkSession
+ private members initalized at construction time, as
+ spice_display_set_property() gets called at construction time.
+
+ Currently its SpiceSession and SpiceGtkSession are NULL when that
+ happens leading to the g_object_set() calls in spice_display_set_property()
+ triggering g_return_if_fail statements inside glib and rightly complaining
+ loudly.
+
+ This patch fixes this by making the SpiceSession and channel ID construction
+ properties and passing them to the g_object_new call in spice_display_new.
+
+ Move clipboard handling to SpiceGtkSession
+ This fixes copy and paste with multi-monitor guests. There still is
+ one small issue left with this patch, changing the setting for auto-clipboard
+ in one spicy window, does not get reflected in the Options menu of the
+ other spicy windows.
+
+ This can be fixed by listening to the notify signal, this also requires
+ SpiceDisplay to listen to property changes on its SpiceGtkSession and
+ then do a g_object_set on itself to update its own property (and also
+ emit its own notify signal.
+
+ I'll write a separate patch for this.
+
+ Add a SpiceGtkSession Class
+ This initial commit of the SpiceGtkSession Class only adds the empty
+ class and the 1:1 linkage to SpiceSession through 2 new private methods
+ added to SpiceSession: spice_session_{get|set}_gtk_session.
+
+ The following commits will move things which are currently per SpiceDisplay,
+ but which really should be global, such as the clipboard, over to
+ SpiceGtkSession.
+
+2011-10-04 Hans de Goede <hdegoede@redhat.com>
+
+ Fixup some headers so that they include headers the depend up on.
+ Otherwise they cannot be included unless other headers are included
+ first (and in the right order).
+
+2011-09-30 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: Add missing <package> and <c:include> in gir
+ This is required for source-level binding, such as Vala.
+
+2011-09-30 Hans de Goede <hdegoede@redhat.com>
+
+ spice_codegen: Always write a channels entry for an ifdef-ed channel
+ Before this patch, if a channel is defined conditionally in spice.proto
+ (because it depends on external headers like the smartcard channel),
+ spice_codegen would write an entry to the channels array in
+ spice_get_*_channel_parser which would only take up a place in the array
+ if the ifdef condition is true, thus moving up all other intializers
+ one place when it is not true. This was causing issues (crashes) when building
+ spice-gtk with the combination of usbredir support enabled and smartcard
+ support disabled.
+
+ This patch fixes this by adding #else { NULL, 0 }, to the generated code.
+
+ Thanks to coolper chen <lixin.chen@saicocch.com> for reporting this!
+
+2011-09-23 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: move G_DEFINE_BOXED in glib-compat.h and fix build with old glib
+
+ pulse: use spice_g_signal_connect_object
+ Disconnect all handlers when either emitter or observer is gone.
+ That should help https://bugzilla.redhat.com/show_bug.cgi?id=737202
+
+ util: add spice_g_signal_connect_object
+ This is a copy of telepathy-glib tp_g_signal_connect_object.
+
+ That function allows to connect object's signals without
+ having to worry much about emitter/observer lifetime.
+
+ It handles automatic disconnection for us, no need to track
+ all the handlers id. Nice!
+
+2011-09-02 Hans de Goede <hdegoede@redhat.com>
+
+ gtk/Makefile.am: Better explicit deps fro autogenerated files
+ Auto-generated files need explicit deps on them to ensure things
+ are build in the right order when doing things like make -j200:
+ 1) We had an explicit deps on spice-marshal.h, but only for spice-channel.c,
+ but others need it to
+ 2) autogen.c files need autogen.h, note this is done in a separate make
+ statement, since the deps of the actual build rule are used during the
+ generation!
+ 3) Group all the autogen explicit deps together
+
+ configure.ac: Update minimum required spice-protocol to 0.9.0
+ This is needed for usbredir support.
+
+ gtk/continuation.c: undef _FORTIFY_SOURCE earlier
+ We need to undef _FORTIFY_SOURCE before our first include, so as to
+ avoid the extra checks it does on longjmp which don't play well with
+ our coroutine stuff.
+
+ gtk/controller/Makefile.am: Add explicit rules for autogenerated files
+ The autogenerated files are part of make dist, without these explicit
+ rules doing "./autogen.sh && make dist" on a clean git checkout
+ will fail because it wants them but does not know how to build them.
+
+ gtk/Makefile.am: Remove a bunch of .c files from EXTRA_DIST
+ automake is smart enough to add _SOURCES files to make dist's result even
+ if there compilation is depending on an AM conditional, and we are already
+ depending on this for the smartcard / usb files, so lets depend on it for
+ the other ones too.
+
+ gtk/Makefile.am: Don't include auto-generated files into make dist tarbal
+ We have various files which are auto-generated which currently get included
+ into the tarbal, yet they are part of CLEANFILES, so the first make clean
+ removes them, which is rather weird. Use nodist_foo_SOURCES to make them
+ not end up in the tarbal.
+
+ generated_[de]marshallers[1].c, are special as autogenerating those on
+ end user builds would mean requiring the end user to have pyparser installed,
+ so we add them to EXTRA_DIST and remove them from CLEANFILES. It may seem
+ weird to have them in nodist_... and then add them to EXTRA_DIST,
+ but this patch also adds an explict depenency on the autogenerated files
+ to the non autogerated ones:
+ $(libspice_client_glib_2_0_la_SOURCES): spice-glib-enums.h
+
+ Leaving generated_[de]marshallers[1].c in libspice_client_glib_2_0_la_SOURCES,
+ would cause it to get a dep on autogenerated files, and thus get regenerated
+ itself no matter what, defeating the purpose of having them in dist in the
+ first place.
+
+2011-09-01 Hans de Goede <hdegoede@redhat.com>
+
+ spice_usb_device_get_description fixups
+ 1) Fix spice_usb_device_get_description compilation when building without
+ usb support
+ 2) Don't return "Unknown" when the device param is NULL, the caller should
+ g_free the returned string, so we cannot return a const string
+ 3) Fix the existing callers to actually g_free the result of
+ spice_usb_device_get_description. To avoid code duplication this patch
+ makes usb-device-manager prefix the error it gets from the usbredir-channel,
+ so that users of the auto-connect-failed signal can use the error as is.
+
+ usbredir: provide out own libusb_strerror for now
+ libusb_strerror is not going upstream because of i18n worries, provide
+ our own for now.
+
+ usb-device-manager: Add a auto-connect-failed signal
+ And use it in spicy to inform users of auto redirect failures (usually due
+ to insufficient rights on the /dev/bus/usb device nodes).
+
+ usb-device-manager: Add a spice_usb_device_get_description() method
+ This is just a place holder for now. A better implementation requires
+ gusb changes, and I hope there will be an official gusb release by the
+ time I get around to fixing this up.
+
+ Drop VOID:BOXED user marshaller
+ We were generating a user marshaller for VOID:BOXED, but there is a standard
+ marshaller for that, use that instead.
+
+2011-08-31 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ doc: various improvements
+
+ doc: update to include USB redirection
+
+2011-08-30 Hans de Goede <hdegoede@redhat.com>
+
+ Remove spice-client-gtk.defs from git (as it is auto-generated)
+ spice-client-gtk.defs gets autogenerated (but only when building for
+ gtk2). Having it in git means having to keep it in sync with the public
+ API manually, which requires doing a gtk2 build before committing each
+ time one makes changes to the public API.
+
+ As with any autogenerated files, this really does not belong in git,
+ removing it from git removes the need for the manual syncing.
+
+ Also add it to make clean, and change gtk/Makefile.am so that
+ the contents on EXTRA_DIST don't depend on how ./configure was run
+ making "make dist"-s result depend on ./configure flags is not a good idea.
+
+ Remove gtk/.gitignore
+ gtk/.gitignore gets autogenerated and thus should not be part of git.
+
+ It currently being part of git is esp. annoying since depending on
+ wether you're building for gtk2 or gtk3, lines like:
+ /SpiceClientGtk-2.0.gir
+ /SpiceClientGtk-2.0.typelib
+ /libspice-client-gtk-2.0.la
+
+ Keep disappearing from it, leading to these changes accidentally
+ getting included into whatever commit your working on.
+
+ spice_gstaudio: s/SpiceGstAudio/SpiceGstaudio
+ We should either have SpiceGstAudio && spice_gst_audio or
+ SpiceGstaudio && spice_gstaudio, not SpiceGstAudio && spice_gstaudio
+ like we have today. This patch fixes this by replacing SpiceGstAudio
+ with SpiceGstaudio. We can do this since this is only used internally.
+
+ Rename my_foo private datatypes to MyFooPrivate
+ We were using the gobject standard notation of MyFooPrivate everywhere
+ except for 3 places, this brings these 3 into sync, with what we do elsewhere.
+
+ Add auto_usbredir property to spice-widget
+
+ spice-session: at a spice_session_has_channel_type method
+
+ Add an USB device manager
+
+ Add an usbredir channel
+
+ Add a private copy of gusb
+ While working on usb redirection support for spice-gtk I needed some
+ code to integrate libusb into glib's mainloop amongst other things. I ended
+ up borrowing code from colord for this. Richard (the colord author) and I
+ quickly agreed that doing generic glib bindings for libusb is a good idea,
+ akin to the gudev bindings for libudev we've called our WIP on this gusb:
+ https://gitorious.org/gusb
+
+ Since this very much is a WIP, the API is nowere near stable, so for now
+ we bundle a copy of this code with spice-gtk. When gusb has an official
+ release out the door with a stable API we should switch to that.
+
+ spice.proto: Add usbredir channel
+
+ spice-channel: Reset SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION on disconnect
+ Our disconnect handler clears the common_caps array so that a new
+ connection starts with a clean slate. But in our constructor we set
+ the SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION in common_caps as starting
+ cap. Do the same on disconnect, so the behavior of a re-using a channel
+ after disconnect is the same as using a fresh channel.
+
+2011-08-17 Hans de Goede <hdegoede@redhat.com>
+
+ spice-channel: fix writing a byte twice when a write blocks
+ When a write blocks, and thus ret == -1 (and the gerror matches EAGAIN) we
+ still do offset += ret, causing the last written byte to be send twice.
+ Lets not do that :)
+
+ spice-widget: release_keys on focus out
+ This fixes alt getting stuck in the guest when the user alt-tabs away from the
+ spice-widget (thus making it see the alt press but not the release) and then
+ closing it without giving it the focus back (by using the windows close button
+ for example).
+
+ Note that doing this on focus out (when we know we may be missing key releases
+ afterwards) makes a lot more sense then doing this on focus in, and with
+ the release_keys on focus out I don't really see a reason any more to do it
+ on focus in. But I'm leaving it in on focus in just in case, it certainly
+ cannot hurt there.
+
+ spice-widget: remove keyboard_grab_count / keyboard_grab_time hack
+ With the filtering of focus in / out events caused by grabs we should no
+ longer need this.
+
+ spice-widget: ignore focus in / out events caused by keyb ungrab/grab
+ As documented in XGrabKeyboard(3): "The XGrabKeyboard function actively grabs
+ control of the keyboard and generates FocusIn and FocusOut events."
+
+ Note that for some reason this only happens when we call XGrabKeyboard
+ from our enter_event / leave_event callbacks and not from our focus_in /
+ focus_out callbacks? Either way we still need to filter these out.
+
+ Filtering these out fixes 4 issues:
+ 1) keyboard_have_focus now no longer gets unset when the keyboard is grabbed,
+ making USB auto redirection when focussed actually work
+ 2) Before this patch, if you pressed alt and then (accidentally) moved the
+ cursor out of the spice-widget window before pressing a second key,
+ the focus in event would clear the keyboard status causing the guest to no
+ longer see alt as pressed and register the second key press as a regular
+ keypress rather then as alt-foo.
+ 3) It allows us to remove the keyboard_grab_count / keyboard_grab_time hack
+ from try_keyboard_grab, although since we are no longer doing an
+ ungrab on focus out, this likely could have been removed before.
+ I will do this in a separate patch for easier reverting if necessary.
+
+ spice-channel: Fix a possible race triggered by spice_channel_iterate_write
+ Fix a race between spice_channel_buffered_write and
+ spice_channel_iterate_write.
+
+2011-08-17 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ data: fix spicy.nsis.in to include right libraries
+
+ build: fixes build with gtk3 on win32
+
+ build: warn and instruct if valac is missing
+
+ gtk: implement coroutines using Windows fibers
+
+2011-08-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ use _setjmp/_longjmp to speed up coroutine switching
+ As described in http://www.1024cores.net/home/lock-free-algorithms/tricks/fibers
+
+2011-07-29 Christophe Fergeau <cfergeau@redhat.com>
+
+ mjpeg: don't leak last stream image
+ When a stream is destroy, the memory allocated to handle the mjpeg
+ decoding is freed by calling stream_mjpeg_cleanup. However, the
+ memory allocated to contain the last uncompressed stream image
+ wasn't freed.
+
+ mjpeg: remove wrong g_return_if_fail
+ After calling jpeg_read_scanlines, spice-gtk checks that we read
+ the amount of lines we expected, and if not, it returns early.
+ This is doubly wrong:
+
+ * jpeg_read_scanlines is documented as returning at most the number
+ of lines requested, but it also warns that an application shouldn't
+ rely on getting exactly the number of scanlines requested. In this
+ case, if rec_outbuf_height is bigger than 1, we'll get a short read
+ on the last line of odd-sized images, thus triggering the
+ g_return_if_fail
+
+ * returning from this function without calling jpeg_abort will cause
+ libjpeg to abort next time we use it because jpeg_start_decompress
+ was called before
+
+ This commit removes this check and early return.
+
+ mjpeg: restrict use of i and j
+ Using i and j as variable names that are used from one loop to the
+ other isn't really readable, and makes the code more fragile than
+ it could be. This commits adds a "lines_read" variable which is more
+ expressive than "j", restricts "j" lifetime to the loop where it's
+ used, and it removes the "i" variable and uses counters provided
+ by libjpeg to iterate all the image lines.
+ It also has the side-effect that if jpeg_read_scanlines returns a short
+ read (less lines than expected are read), "dest" won't go out of sync but
+ will be set to the right place at the end of the loop.
+
+ mjpeg: properly abort decompression in error path
+ spice-gtk jpeg decompression code honors libjpeg's recommended size
+ for its output buffer to improve performance. However, when this
+ recommended size is too big, it just gives up on the decompression
+ process by returning early from the function. But since
+ jpeg_start_decompress has been called to compute this recommended
+ size, the decompression must be aborted before returning, otherwise
+ libjpeg will get in an inconsistent state and will abort next time
+ we try to use it.
+ This commit also moves the check that the recommended size isn't
+ too big out of the decompression loop because it shouldn't changed
+ during decompression.
+
+2011-07-28 Christophe Fergeau <cfergeau@redhat.com>
+
+ fix integer marshalling helpers on big endian
+ They were trying to convert the destination pointer to an integer before
+ trying to dereference it. The initial conversion was meant to be a cast
+ to a pointer of the right size, not to an integer.
+
+ fix typo in big endian code path
+ uint63_t should be uint64_t
+
+2011-07-26 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: fix libtool versionning
+ As pointed out by Daniel P. Berrange:
+ "Arrggh ! There's a typo there. You want '-version-info' not
+ '-version-number'. The latter directly sets the major/minor
+ soname values hence why you keeping seeing incompatible versions :-("
+
+2011-07-18 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Release v0.7
+
+ build: update library version
+ client-glib interfaces have been changed or added, but binary compatibility has been preserved, change to current+1:0:age+1
+
+ client-gtk updated code, same API: increment revision.
+
+ build: fix make distcheck
+
+ build: fix introspection warnings
+ The only one left is related to GOptionGroup, which is not boxed.
+
+ gtk/controller: fail if SPICE_XPI_SOCKET is not provided
+ Instead of trying to connect to a '(null)' socket.
+
+2011-07-17 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: snappy/spicy-stats move connection option to main group
+
+ gtk: update spicy to use new option API
+
+ gtk: add spice_get_option_group()
+
+ gtk: add color-depth and disable-effects options
+
+2011-07-16 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add spice_strv_contains in util-priv.h
+
+ build: fix .pc Requires
+
+2011-07-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: avoid doing GdkWindow operations if widget is not realized
+
+ gtk: honour CURSOR_FLAGS_NONE by hiding cursor
+
+ gtk: comment channel_new() returns a weak reference
+ And add a few sanity checks.
+
+ gtk: add glz_decoder_window_clear, to recycle decoder
+
+2011-07-14 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: rework widget destroy/dispose()
+ Make sure to remove handlers during dispose.
+ Destroy is purely a gtk+ thing, so let the widget do the job.
+
+ This solves a refcount/crash issue found with virt-manager.
+
+2011-07-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/doc: improve the generated gtk-doc a bit
+
+ Merge remote-tracking branch 'teuf/master'
+
+2011-07-13 Christophe Fergeau <cfergeau@redhat.com>
+
+ document SpiceSession properties
+
+ smartcard: add smartcard API doc
+
+2011-07-12 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/spicy: remove false warning
+
+2011-07-12 Daniel P. Berrange <berrange@redhat.com>
+
+ gtk: remove double symbol definition
+
+ gtk/pulse: fix memory leak
+
+2011-07-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/spicy: allow setting color depth
+
+ gtk/spicy: add disable-effects option
+
+2011-07-07 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/smartcard: make smartcard init async
+
+ gtk: add SPICE_CLIENT_ERROR
+
+ gtk/debug: put package version in session_init
+
+2011-07-06 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: remove surface cache, why do we need it?
+
+2011-07-05 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/channel-cursor: refcount display_cursor, make explicit the life of rgba
+
+ gtk/smartcard-manager: remove useless trailing ;
+
+2011-07-05 Christophe Fergeau <cfergeau@redhat.com>
+
+ cursor: don't leak uncached cursors
+ When the cursor channel creates a new cursor, if the message
+ indicates not to cache it, the cursor is leaked after being used.
+ This commit fixes that, though I'm not really satisfied with it.
+
+ ==22568== 378,432 bytes in 162 blocks are definitely lost in loss record 7,699 of 7,699
+ ==22568== at 0x4A0649D: malloc (vg_replace_malloc.c:236)
+ ==22568== by 0x4E624CF: spice_malloc (mem.c:88)
+ ==22568== by 0x4E4F1C4: set_cursor (channel-cursor.c:323)
+ ==22568== by 0x4E4FA29: cursor_handle_set (channel-cursor.c:469)
+ ==22568== by 0x4E4FD19: spice_cursor_handle_msg (channel-cursor.c:548)
+ ==22568== by 0x4E30292: spice_channel_recv_msg (spice-channel.c:1641)
+ ==22568== by 0x4E3062A: spice_channel_iterate_read (spice-channel.c:1776)
+ ==22568== by 0x4E307F9: spice_channel_iterate (spice-channel.c:1820)
+ ==22568== by 0x4E30EE4: spice_channel_coroutine (spice-channel.c:1968)
+ ==22568== by 0x4EE48A2: coroutine_thread (coroutine_gthread.c:77)
+ ==22568== by 0x302E4683A5: g_thread_create_proxy (gthread.c:1955)
+ ==22568== by 0x302C807AF0: start_thread (pthread_create.c:305)
+
+2011-07-05 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: s/SmartCard/Smartcard/g
+
+ gtk: total-read-bytes is ulong
+ As pointed out by Christophe on the ML.
+
+2011-07-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: remove warning if !USE_SMARTCARD
+
+ Merge commit 'refs/merge-requests/16' of ssh://gitorious.org/spice-gtk/spice-gtk into merge-requests/16
+
+2011-07-02 Alon Levy <alevy@redhat.com>
+
+ gtk: add spicy-stats test app
+
+ spice-channel: add property total-bytes-read
+
+ spice-channel: export spice_channel_type_to_string
+
+2011-07-01 Christophe Fergeau <cfergeau@redhat.com>
+
+ prepend smartcard cmdline options with --smartcard
+ This is consistent with what spicec does, and is also less
+ confusing since other certificates can be passed on the command
+ line (for client/server host authentication).
+
+ add --smartcard option to spicy
+ People starting spicy will not always want their smartcard data
+ to be forwarded to the guest they're connecting to. Currently,
+ smartcard events are unconditionnally forwarded to the server if
+ spicy was compiled with smartcard support. This commit adds a
+ --smartcard option that must be used in order to enable smartcard
+ support in the client. By default, smartcard data won't be forwarded
+ to the server unless this option is specified.
+
+2011-06-28 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/smartcard: make cacard dependency optional without breaking API
+
+2011-06-26 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/smartcard: remove g_assert
+
+2011-06-24 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ TODO: update
+
+ build-sys: fix disable-smartcard broken earlier
+
+2011-06-23 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/smartcard: add a couple of debug
+
+ gtk/smartcard: simplify a little spice_smartcard_manager_init_libcacard
+
+2011-06-23 Christophe Fergeau <cfergeau@redhat.com>
+
+ use new @ifdef directive for smartcard messages
+ We don't want to conditionally compile the smartcard messages
+ depending on whether USE_SMARTCARD is set or not, we can now use
+ the @ifdef attribute for that.
+
+ handle @ifdef on messages and channels
+
+ allow attributes on channel elements in .proto files
+ We want to be able to add an @ifdef annotation to optional messages
+ For example, we want to compile in the smartcard messages only if
+ libcacard is available
+
+ add ifdef/endif methods to spice code generator
+ These methods will be needed to be able to make some fields optional
+ in spice.proto
+
+ fix compilation when libcacard isn't installed
+
+ set menu actions sensitivity for software smartcards
+ Make sure menu actions are only sensitive when we are using a
+ software smartcard reader, and properly update the sensitivity
+ depending on the presence or not of a software smartcard in the
+ software reader.
+
+ add smartcard actions to spicy
+ Add code to add/remove a software smartcard in spicy UI. These
+ 2 entries were added as items in the Input menu. They are not
+ grayed out for now if there is no software reader available.
+
+ add software smartcard reader support
+
+ use user-provided certificates when init'ing libcacard
+
+ read certificate information from command line
+ When using a software card reader, one needs to pass 3 certificates
+ to be used to simulate the smartcard (and optionnally the path to
+ a certificate database). This commit adds support for --certificates
+ and --certificate-db command line options to do that.
+
+ add smartcard properties to SpiceSession
+ To handle software smartcards, we need to be able to pass the
+ certificates to use for the smartcard as well as the database where
+ these certificates can be found. This commit adds "certificates"
+ and "certificate-db" properties to make this possible.
+
+ handle smartcard channel in SpiceWidget
+
+ handle smartcard channel in spice_channel_new
+
+ initialize libcacard
+
+ don't always serialize messages sent to the server
+ The communication between spice clients and servers on the smartcard
+ channel can be initiated either by the client or by the server.
+ It's initiated by the client for smartcard reader events (reader
+ hot(un)plug, card insertion/removal), or it can be initiated by the
+ server when it wants to query the certificates available on the
+ smartcard.
+ When communication is initiated by the client, we want to serialize
+ the messages we sent, ie we don't want to send a message if we
+ haven't received yet the answer to the previous message.
+ However, when it's the server which initiates the communication,
+ we don't want to use this serializing mechanism.
+
+ This commit adds a "serialize_msg" boolean to be able to disable
+ message sending serialization as needed.
+
+ forward APDU requests from server to smartcard reader
+ These requests are sent by the server when trying to read the
+ certificates from the smartcard.
+
+ handle messages from spice server
+
+ serialize sending of smartcard channel messages
+ Messages sent to the spice server by the smartcard channel have to
+ be serialized: before sending a message, the channel has to wait
+ for the server answer to the previous message. Add a GQueue to be
+ able to queue several messages to the server while we wait for the
+ answer to an earlier message.
+ I think the reason why that serialization is needed is to be able
+ to deterministically assign IDs to readers on reader addition. We
+ have no way to match a message from the spice server with the
+ message to the server that triggered this reply, which means that
+ if we could send several reader additions to the server without
+ waiting for answers, when the server answers, we wouldn't know
+ which reader it's trying to assign an ID to.
+
+ send messages to spice server on reader/card events
+
+ add basic callbacks for smartcard events
+ Now that the smartcard manager sends event for smartcard readers,
+ the smartcard channel has to do something with them. For now, we just
+ add basic callbacks which don't try to forward these events to the
+ spice server. However, we start adding the glue needed to handle
+ the fact that plugging of smartcard readers and creation of these
+ readers in the spice server will be asynchronous.
+ After receiving a "reader addition" command, the spice server sends
+ back an ID to identify this reader which must be used in all other
+ requests (card insertion, removal and reader removal) to identify
+ this reader. However, if the server is slow to send back this ID,
+ there's a window when we can get additional events for the reader
+ that is being added that we can't send right away to the server
+ because we don't know the ID to use. That's why we add the various
+ pending_* hashes in this commit, to be able to keep track of the
+ requests that will have to be sent once the spice server has
+ assigned an ID to the reader.
+
+ add smartcard bits to spice.proto
+
+2011-06-22 Christophe Fergeau <cfergeau@redhat.com>
+
+ emit signals in reaction to libcacard events
+
+ add signals for smartcard events
+ Add signals which will be emitted when a reader appears/disappears,
+ or when a smartcard is inserted/removed.
+
+ add boxed type for VReader
+ VReader is a type defined in libcacard which contains all the
+ information we need ot handle card readers. Since it's refcounted,
+ we can make it a boxed type for use in signals.
+
+ add smartcard monitor GSource
+ This source gets events from libcacard and inserts them into
+ a regular glib mainloop. The smartcard manager will then emit
+ signals in reaction to the events it got from libcacard.
+
+2011-06-22 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ build-sys: some minor cleanup
+
+2011-06-22 Christophe Fergeau <cfergeau@redhat.com>
+
+ add --enable-smartcard configure flag
+
+ add smartcard channel and smartcard manager skeletons
+
+ improve debug log on coroutine start
+
+ factor base message handling in SpiceChannel
+ Currently, every channel has to define all the server messages it
+ handles, including the "generic" ones. Since it's error prone (easy
+ to forget the handling of default messages in new sources), it's
+ better to move this handling to the base channel class, and to call
+ the parent method when the message is unknown in the ::handle_msg
+ method.
+
+ On top of this, another factoring that can be done is to make the
+ message handling function generic instead of reimplementing it in
+ every class. Each class would only have to register its own
+ (class-specific) set of handlers.
+
+ Conflicts:
+
+ gtk/channel-playback.c
+ gtk/channel-record.c
+
+ display more options in default --help
+ When running spicy --help, very few options are shown. I didn't
+ notice at first that it was possible to specify the spice server
+ host/port/... showing them in the default help output should make
+ these options more obvious.
+
+2011-06-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: get rid of duplicated channel_desc table
+
+ gtk/gstaudio: add volume control support
+
+2011-06-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/audio: announce volume capability
+
+ add git .mailmap
+
+ gtk/pulse: add volume control support
+
+ common: add volume messages
+
+ spice.proto: updated with volume messages
+
+ playback/record: add audio volume properties
+
+2011-06-17 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/controller: add accel menuitem property
+
+ gtk/controller: change namespace to SpiceCtrl
+
+2011-06-17 Christophe Fergeau <cfergeau@redhat.com>
+
+ gtk/spicy: fix buttons in connect dialog
+ Use proper button order (confirmation should be bottom right) and
+ use a "Connect" button instead of "Ok".
+
+2011-06-14 Alon Levy <alevy@redhat.com>
+
+ channel-display: destroy_stream: fail if streams is NULL
+
+2011-06-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/controller: fix connection events on namedpipe
+ Strangely, Wine was working fine with the NamedPipe handle itself.
+
+ But WinXP wants the Event handle, obviously.
+
+2011-06-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/controller: build win32 controller pipe name
+
+2011-06-09 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: rule out clicks in outside region
+ Not so great change: we should have a grab on the pointer when
+ pressing, to receive the release event even if outside the
+ region. Unfortunately, grabs are single widget for now.
+
+ gtk: oops, forgot to put signal detail first
+
+2011-06-08 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ gtk/widget: keep a ref on the session
+ This is to make more explicit that the session isn't owned by the
+ widget display, but rather shared.
+
+ Also, it makes it easier to deal with dispose() since there is
+ explict referencing.
+
+ gtk/session: allow spice_session_disconnect() to be called several times
+
+ gtk/channel: add more runtime check, and make sure any pending idle associated are removed
+
+2011-06-07 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Merge commit 'refs/merge-requests/14' of ssh://gitorious.org/spice-gtk/spice-gtk into merge-requests/14
+
+2011-06-07 Christophe Fergeau <cfergeau@redhat.com>
+
+ add really basic GDK GnomeRR backend
+ It doesn't know about available resolutions, nor about clones,
+ rotations, ..., it can't trigger resolution changes, but hopefully
+ it will be enough for basic GnomeRR support in the mac port.
+
+ configure.ac: add defines for windows and osx
+ Check for gtk+-win32/gtk+-osx to know when we should define
+ HAVE_WINDOWS/WITH_DISPLAY_WINDOWS and HAVE_QUARTZ/WITH_DISPLAY_QUARTZ
+
+ This is better than the old scheme that blindly tried to detect
+ libx11, and chose between x11/windows depending on only this
+ test.
+ We probably should check that only one of windows/x11/quartz is
+ enabled at once.
+ NB: for now the QUARTZ defines are not used since we will be
+ using a generic GnomeRR backend instead of having our own
+ OSX backend.
+
+ configure.ac: only check for X11 libs on X11 builds
+ No need to try to detect xrandr or xkb headers when we won't be
+ doing an X11 build. This is even detrimental on Mac OSX when
+ we want to attempt a native build but have the xkb headers installed.
+
+ configure.ac: simplify --with-x11 processing a bit
+
+ configure.ac: improve X11 detection
+ Use gtk-x11-[23].0.pc to detect whether we want an x11 build or
+ not. Don't AC_SUBST X11_CFLAGS and X11_LIBS since they are unused.
+
+ configure.ac: group all X11 checks
+ Gather all x11 related checks in the same place
+
+2011-06-07 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/win32: interecept low level keys - fix alt-tab and such
+
+ gtk: improve gstaudio backend
+ Do not timestamp gst audio buffers, since they are continuous anyway
+ and it fixes directsoundsink stuttering
+
+ Also, add a new SPICE_GST_AUDIOSINK environment variable to play with
+ sink parameters
+
+ build/win32: they broke libjpeg again
+
+2011-06-06 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/win32: gtk maps LAlt & LCtrl to Alt and Ctrl keycode, but they are missing from keymaps.csv
+
+2011-06-05 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: update spicy.nsis installer
+
+2011-06-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: fix windows build with recent mingw64
+
+2011-06-02 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: remove unused c++ check
+
+ gtk/spicy: add rudimentary grab-sequence configuration setting
+
+2011-05-28 Christophe Fergeau <cfergeau@redhat.com>
+
+ fix miscellaneous memleaks
+ Fix various memleaks that were reported by valgrind.
+
+ plug a memleak in ChannelMain::_channel_new
+ ChannelMain::_channel_new was leaking memory in an error path.
+ Unconditionnally free the used memory, which has the added benefit
+ of making the code simpler.
+
+2011-05-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: load ca-file if SPICE_SESSION_VERIFY_SUBJECT
+ Fix SSL verify to work like spicec, not sure what I am doing there, but it works.
+
+ gtk: update python binding generated file
+
+ gtk: log spice-gtk version when creating a session
+
+2011-05-25 Christophe Fergeau <cfergeau@redhat.com>
+
+ fix make distcheck
+
+ make perl-Text-CSV optional for tarball builds
+ Ship the files generated using perl-Text-CSV in the tarball so that
+ end-users (as in "people compiling from a tarball") won't need to
+ have perl-Text-CSV installed.
+
+2011-05-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/spicy: free some more objects when quitting
+
+2011-05-25 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
+
+ Connect on recent connection item activation
+ Now (commit 27df918) that we already gather connection information when
+ user (single)-clicks a recent connection item, we can safely use the
+ selected recent connection when user activates (double-clicks) it.
+
+ RecentChooser should act on single-click
+ Fill-in the connection dialog fields as soon user selects a recent
+ connection.
+
+ Minor coding-style fix
+ Don't use mix of tabs and spaces.
+
+ Get rid of redundant argument
+
+ Minor clean-up
+ Prefer 'if/else' over 'switch' when dealing with only 2 possibilities.
+
+2011-05-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Merge branch 'merge-requests/11'
+
+2011-05-25 Christophe Fergeau <cfergeau@redhat.com>
+
+ sync protocol files with spice
+
+ remove duplicate headers from Makefile.am
+ Headers needed for map-file generation were listed twice, once in
+ libspice_client_glibinclude_HEADERS and once in _SOURCES. It's ok
+ to only have them in _HEADERS. Order channel names alphabetically
+ while I'm touching this part of Makefile.am
+
+ remove G_GNUC_CONST from get_type functions
+ These functions call g_type_register_* the first time they are
+ called which is not G_GNUC_CONST so this attribute can't be used
+ here. This had the side effect of making these functions not appear
+ in sym-file after running make update-sym-file.
+
+2011-05-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add SSL ciphers session property
+
+2011-05-24 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ THANKS: update
+
+ Merge commit 'refs/merge-requests/10' of ssh://gitorious.org/spice-gtk/spice-gtk into merge-requests/10
+
+2011-05-23 Christophe Fergeau <cfergeau@redhat.com>
+
+ add const to arrays in marshalling functions
+
+ fix copy & paste error in ptypes.py
+
+ remove duplicate #include
+
+ fix wrong comment in spice_spice_channel_send_msg
+
+ s/interruptable/interruptible
+
+2011-05-23 Daniel P. Berrange <berrange@redhat.com>
+
+ Fix missing OS-X keymapping for letter 'A'
+ The keymap-gen.pl script was not correctly distinguishing
+ keycodes with a value of '0', from undefined keycodes. All
+ were skipped. This meant that the mapping for OS-X ANSI_A
+ key was lost (since it has value 0).
+
+ For similar reasons the XQuartz mapping for the letter A
+ was also lost.
+
+ * src/keymap-gen.pl: Fix handling of 0 vs undef for keycodes
+ * src/keymaps.csv: Remove bogus 0x0 entry in OS-X keymap
+
+ Add missing keytable entry for KEY_KATAKANAHIRAGANA
+ * src/keymaps.csv: Add XT code for KEY_KATAKANAHIRAGANA
+
+2011-05-23 Christophe Fergeau <cfergeau@redhat.com>
+
+ include stddef.h in continuation.h
+ It uses size_t so it needs it to get a definition for this type.
+ If it's not there, this causes build breakage on OS X
+
+2011-05-23 Attila Sukosd <attila.sukosd@gmail.com>
+
+ define MAP_ANON as MAP_ANONYMOUS if needed
+ Mac OS X doesn't have MAP_ANONYMOUS, only MAP_ANON, so use MAP_ANON
+ when MAP_ANONYMOUS isn't defined.
+
+2011-05-23 Christophe Fergeau <cfergeau@redhat.com>
+
+ ssl_verify: include <string.h>
+ ssl_verify.c is using memcmp which comes from string.h, this was
+ breaking compilation with -Werror -Wall on Mac OS X
+
+ link with gthread when appropriate
+ The corouting gthread code and spicy are using gthread functions
+ but were no linked against the gthread library. This causes build
+ failures on older glibs where gthread isn't mandatory when using
+ glib.
+
+ gnome-rr: use g_object_notify instead of g_object_notify_by_spec
+ The latter was added in glib 2.26, and we only require glib 2.22
+
+2011-05-23 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ display: fix build error GLib <2.26
+ https://bugs.freedesktop.org/show_bug.cgi?id=37443
+
+2011-05-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/controller: correctly close namedpipe after calling close()
+
+ gtk/controller: add some missing clean up of namedpipe
+
+2011-05-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/controller: forgot to dispose stream as well
+
+ controller: stick to 2.22 API
+
+2011-05-16 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: fix build with latest mingw
+
+2011-05-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/controller: got NamedPipe basic working
+
+2011-05-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/controller: start NamedPipe support (compile with mingw32)
+
+2011-05-11 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: restore correctly UI elements visibility state
+
+2011-05-10 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
+
+ gtk: some code cleanup
+
+2011-05-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: spicy - leave fullscreen when grab sequence is pressed
+ Workaround since accels are now disabled.. Ideally we either have a
+ different key sequence or we use Vinagre UI
+
+ gtk: fix spicy grab key sequence
+
+ gtk: warn on invalid key sequence
+
+ gtk: add grab-keys-pressed signal
+
+ gtk: don't ungrab keyboard on focus-ous
+ Mainly to avoid the crazy loop:
+ focus-in > grab -> focus-out -> ungrab -> focus-in
+ on kde & gnome-shell.
+
+ gtk: keyboard handling improvements
+ - spicy: disable accels/mnemonics when grabbed
+
+ gtk: extra check only compiled if !NDEBUG
+
+2011-05-09 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: get rid of a useless warning
+
+ gtk: return RGB -> BGRX color conversion for non-turbo jpeg
+
+2011-05-08 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: use faster jpeg decompression by default
+
+2011-05-08 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ gtk: warn if received invalid frame timestamp
+
+2011-05-07 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ gtk: speed up mjpeg decompression
+ Remove custom rgb->argb functions, and remove fancy post-proc (which I
+ don't think were applied, but we now do the same as spicec)
+
+ gtk: sync audio with gst backend
+
+2011-05-06 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ build: update README with depedencies
+
+ gtk: warn unsupported channel type with a description
+
+2011-05-06 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: adjust overall playback latency to 100ms
+ The previous parameters didn't adjust overall latency. Adjusted to
+ 100ms overall latency lower cpu load, and improve video flickering
+
+ (damn /me suck at PulseAudio client-side...)
+
+2011-05-04 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: fix SASL auth failed
+ Signal correctly to the client that AUTH failed.
+
+ Before, we only had a IO error on channel disconnection.
+
+2011-05-03 Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
+
+ configure.ac: Use gtk+ 3.0 be default
+ Hi Zeeshan!!
+
+2011-05-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ TODO: fix wrong mouse ungrabbing for dragndrop
+
+2011-04-27 Christophe Fergeau <cfergeau@redhat.com>
+
+ configure.ac: remove setting default C(XX)FLAGS
+ automake/autoconf already set them for us to -g -O2 if there are
+ no flags defined.
+
+ configure.ac: use AC_LANG_SOURCE
+ Recent autoconf complains when AC_COMPILE_IFELSE is used without
+ using AC_LANG_SOURCE to generate the code snippet to compile. Add
+ the missing AC_LANG_SOURCE call to SPICE_CC_TRY_FLAG to make it
+ quiet.
+
+ configure.ac rework introspection detection
+ When running autogen.sh without having gobject-introspection, this
+ should give a slightly nicer error message. It currently errors out
+ with
+ gtk/Makefile.am:450: HAVE_INTROSPECTION does not appear in AM_CONDITIONAL
+
+ After the patch the error will be
+ checking for GOBJECT_INTROSPECTION... yes
+ ./configure: line 21307: syntax error near unexpected token `0.6.7'
+ ./configure: line 21307: `GOBJECT_INTROSPECTION_CHECK(0.6.7)'
+
+2011-04-18 Christophe Fergeau <cfergeau@redhat.com>
+
+ spicy: disable Ctrl+W/Close keyboard shortcut
+ The keyboard shortcut for the Close gtk action isn't disabled,
+ which leads to spicy closing when trying to use Ctrl+W in the guest.
+ All other problematic shortcuts are disabled, but in this case the
+ disabling was commented out. Reenable it to prevent people from
+ accidentally closing spicy when pressing ctrl+w
+
+ spicy: fix keyboard shortcuts in comments
+ The various action entries have a comment about the keyboard
+ shortcut that is being disabled. However, all these comments were
+ copied from the "Quit" action and were all referring to Ctrl-Q.
+ This commit puts the right keyboard shortcuts in the comments
+
+ spicy: remove non-needed keyboard shortcut disabling
+ GTK_STOCK_CONNECT doesn't have an associated keyboard shortcut
+ so there is no need to explicitly disable it.
+
+2011-04-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ NEWS: update for v0.6
+
+ TODO: update
+
+ gtk/display: move some RANDR code to X11 file
+
+ build: fix make distcheck
+
+2011-04-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ Merge commit 'refs/merge-requests/6' of git://gitorious.org/spice-gtk/spice-gtk into merge-requests/6
+
+ gtk/map-file: fix spice_main_send_monitor_config function name
+
+2011-04-11 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ gtk/controller: fix build with non-default arguments
+
+2011-04-11 Christophe Fergeau <cfergeau@redhat.com>
+
+ gtk: fix "set but not used" gcc 4.6 warnings
+ Since we are compiling with -Werror, this was breaking compilation.
+
+2011-04-11 Alon Levy <alevy@redhat.com>
+
+ python_modules/codegen.py: fix indent error in an unused function
+
+ demarshaller/marshaller fix gcc 4.6.0
+ python_modules/demarshal.py and marshal.py fixes for gcc 4.6.0
+ warning about set but unused variables. The fixes disable creating
+ of variables mem_size when they are not used (demarshall) and
+ declaring a src variable when the message doesn't use it (marshal).
+
+ You need to touch *.proto after applying this (should add a Makefile
+ dependency).
+
+ codegen: avoid creating out if not used (fix gcc 4.6.0 warning)
+
+ mingw32 build: python_modules/marshal: use unsigned for for_loop index variable
+
+2011-04-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/spicy: do not show again toolbar when going full-screen, if mark received
+
+ gtk: calling connect() on a connecting channel is fine
+ This avoid problems where different display shares the same input
+ channel and try to connect two times.
+
+ gtk: allow to drag-and-drop between displays / windows
+
+ gtk/controller: install spice-controller library
+
+2011-04-09 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ common: fix build error of used uninitialized
+ CC sw_canvas.lo
+ cc1: warnings being treated as errors
+ ../common/sw_canvas.c: In function 'canvas_draw_text':
+ ../common/sw_canvas.c:1037:16: error: 'pos.x' may be used uninitialized in this function
+ ../common/sw_canvas.c:1037:16: error: 'pos.y' may be used uninitialized in this function
+ make[4]: *** [sw_canvas.lo] Error 1
+
+2011-04-08 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ TODO: update
+
+ build: fix gtk/controller/Makefile valac line which had custom.vapi
+
+ Merge commit 'refs/merge-requests/5' of git://gitorious.org/spice-gtk/spice-gtk into merge-requests/5
+
+ gtk: don't send MonitorConfig after agent start
+ We don't know yet what will be the guest previous configuration.
+
+ Ie, what should we send otherwise? Current hardware configuration?
+ This works badly with windowed mode, where we expect the same windows
+ to be displayed on reconnection.
+
+ gtk: introduce more complete spice_main_send_monitor_config()
+ Since it's unclear yet how MonitorConfig should be used depending on
+ use case (full-screen vs windowed) we prefer to make a public api so
+ that the client implementation can send it when it is the most
+ appropriate time.
+
+ gtk: add disable-display-position
+
+ gtk: remove unnecessary invalidate mark signal
+
+ gtk: send FALSE mark when destroying the primary surface after 1s...
+ This is similar to what is done in spicec.
+
+ gtk: hide the cursor after setting it
+ So that when we move the cursor again, we can show the right one
+
+ gtk/spicy: hide the display if mark is FALSE
+
+ gtk/spicy: update status of all windows
+
+ gtk/spicy: only show window when we receive the mark
+
+ gtk: not having a window is not critical, if the widget is not yet shown
+
+2011-04-08 Hans de Goede <hdegoede@redhat.com>
+
+ gtk: fixup clipboard_by_guest tracking
+ clipboard_by_guest tracking was used more or less for 2 things, to keep track
+ if the agent has clipboard data ready to send, and to see if we have done a
+ clipboard_set_with_data on behalf of the guest agent.
+
+ This patch splits the tracking of the 2, fixing several issues:
+ 1) spice_display_paste_from_guest would not work if since receiving
+ the grab from the agent some other app has copied something to
+ the client clipboard.
+ 2) We would do a clipboard_clear unconditionally even if we were
+ not the clipboard owner in the client (iow some other app has
+ done a clipboard_set_with_data since out last one).
+
+ This patch changes the meaning of the clipboard_by_guest boolean to just
+ track if we've done a clipboard_set_with_data on behalf of the guest
+ and are the last one to have a done a clipboard_set_with_data (iow we are the
+ client os' clipboard owner). It adds a checks to clipboard_release to
+ only call clipboard_clear if we are the current ownerm fixing 1).
+
+ This patch uses nclip_targets to keep track of the agent having data
+ available which we could paste, fixing 2).
+
+ gtk: Clear hasdata when we do a clipboard_set_with_data
+ When we call gtk_clipboard_set_with_data to set the client clipboard
+ to the targets reported as available by the agent, the clipboard no
+ longer has data in the sense that it has data which is interesting
+ for spice_display_copy_to_guest, so clear clip_hasdata whenever we
+ call gtk_clipboard_set_with_data,
+
+ gtk: receiving a grab from the agent implies releasing our own
+ By setting d->clip_grabbed[selection] to FALSE when we receive a grab from
+ the agent, we can remove the weird "if (!d->clipboard_by_guest[selection])"
+ check from clipboard_owner_change, and we fix spice_display_copy_to_guest not
+ working in the following case:
+ 1) autoclipboard share disabled
+ 2) Copy something to the clipboard in the client
+ 3) Send it to the guest by calling spice_display_copy_to_guest
+ 4) Copy something to the clipboard in the guest
+ 5) Tried to send the client clipboard to the guest again by calling
+ spice_display_copy_to_guest (again).
+
+ 5) would not work because d->clip_grabbed[selection] would still be true in
+ spice-gtk's view, where as the agent no longer sees the clipboard as grabbed
+ by the client since it send a grab itself.
+
+ gtk: use a separate var to keep track of self caused new clipboard owner events
+ Also change 0/1 to FALSE/TRUE in touched code. spice-widget seems to be
+ using all 3 of: 0/1 false/true and FALSE/TRUE for booleans. The glib convention
+ is FALSE/TRUE.
+
+2011-04-05 Hans de Goede <hdegoede@redhat.com>
+
+ gtk: take selection into account in clipboard_release
+
+2011-04-05 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: only release clipboard when neither guest nor client own it
+ 08:55 < hansg> elmarco, this is from vdagent.log with debugging enabled. What is happening is that the last thing done was a primary
+ selection in the client, so vdagent owns the clipboard in the guest (on behalf of spice-gtk), then something gets selected
+ inside the guest, the agent sends a grab to spice-gtk, which then does a gtk_clipboard_set_with_data, this triggers an
+ clipboard_owner_change which sends a release message to the agent
+ 08:56 < hansg> To which the agent then responds by dropping it, and logging:
+ 08:56 < hansg> primary: received release while not owning client clipboard
+ 09:11 < elmarco> hansg: but this bug we are talking about is not related to multi-clipboard right?
+ 09:11 < elmarco> and it's only a warning in vdagent, things works as expected otherwise, right?
+ 09:11 < elmarco> the bug was thee before I suppose
+ 09:12 < hansg> right, they work because vdagent is diligent and sees the client sends a release while it is not owning the clipboard. The
+ diligence is mainly there in case things race though (release on client racing with a grab on guest), not to make things
+ work with buggy clients :)
+ 09:13 < hansg> wrt: <elmarco> hansg: d->clip_grabbed is only for client-side grab, iirc
+ 09:13 < elmarco> ok, I think it's just an obscure area of the spec, where basically, we don't define exactly the "state machine"
+ 09:13 < elmarco> so the client is releasing his last client-side grab, because he had one before, but now, it is a guest grab
+ 09:13 < hansg> True (not exactly definging the state machine)
+ 09:14 < hansg> So to try again wrt the d->clip_grabbed, what happens there (which has the same cause) is:
+ 09:14 < elmarco> so, what it should do is just don't release the clipboard if it is switching from client-side to guest
+ 09:15 < hansg> gtk/spice-widget.c: clipboard_grab gets called, and does:
+ 09:15 < hansg> Hmm, hold on, I see what you mean wrt d->clip_grabbed now
+ 09:16 < elmarco> to me, it looks like the client made a grab and to complete it's cycle, it should release his grab
+ 09:16 < elmarco> but the order of things confuse vdagent and we should agree on something and document it
+ 09:18 < hansg> elmarco, I need some time to take a somewhat closer look at the spice-gtk code in this area, give me 1/2 an hour and I'l
+ get back to you
+ 09:20 < elmarco> from client 1. grab -> 2. grab <- 3. release -> or 1. grab -> 2. grab <- 3. no release
+ 09:21 < elmarco> I think state should not be mixed between client grab / release -> and guest grab/release <-
+ 09:22 < elmarco> so, overriding client grab by guest grab should release client grab
+ 09:23 < hansg> spicec and the linux agent both assume that after sending a grab they won't get back a release (for that selection). The
+ purpose of the release is to tell the OS that the agent resp, client no longer own the clipboard (by setting the owner to
+ None under X11), so that other apps can disable their paste menu item, etc. There is no need to do that (and actually
+ doing so would be a bug) if an other app now owns the clipboard. So if the other side claim
+ 09:23 < hansg> s ownership of the clipboard there is no need to tell it you're releasing your side, since it already assume you have
+ 09:24 < hansg> Scenarios to keep in mind are:
+ 09:24 < hansg> Seen from the client side:
+ 09:28 < hansg> client grabs clipboard
+ 09:28 < hansg> some app on guest becomes owner, guest sends grab, assume client release
+ 09:29 < hansg> some app on guest asks agent for clipboard data -> tells it to go away since the client no longer the owner
+ 09:29 < hansg> If it would not assume the release, there would be a window where it would think the client still owns the clipboard and
+ forward potential request to the client, even though the client no longer owns the clipboard
+ 09:30 < hansg> The thing to keep in mind is that the delivery of messages is not instant, so there is some window where the 2 sides are
+ out of sync.
+ 09:30 < hansg> I can see the logic in how you're advocating to do things, but that is not how they are currently done and I'm reluctant
+ to change this
+ 09:33 < elmarco> hansg: yeah, I don't think one solution or the other affect user experience, for me there is no gap if the client and
+ agent agrees, it's only protocol/implementation details
+ 09:33 < elmarco> since there was prior implementation, we can decide to follow it
+
+2011-04-04 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: fix multi-head support by sync the display cache
+ An image may come later from a different channel, even if it is referenced by another image.
+
+ gtk: add some debugging in glz decoder and avoid crashes
+
+ gtk: display now use the cache from the session
+
+2011-04-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: the caches are shared with the session
+
+ common: get rid of abort() in canvases
+
+ common: remove unnecessary outdated c++ debug
+
+2011-04-01 Christophe Fergeau <cfergeau@redhat.com>
+
+ configure.ac: remove detection of WARN_UNUSED_RESULT
+ spice-gtk configure.ac has some code to detect if the compiler has
+ a special attribute to tag some functions so that they generate a
+ warning when their return value isn't checked. However, this test
+ is broken (the gcc attribute name is "warn_unused_result", not
+ "__warn_unused_result__" and WARN_UNUSED_RESULT is unused anyway
+ since spice-protocol provides SPICE_GNUC_WARN_UNUSED_RESULT. Thus
+ we can just drop that block of code from configure.ac
+
+2011-04-01 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ adding THANKS
+
+2011-04-01 Christophe Fergeau <cfergeau@redhat.com>
+
+ configure.ac: remove unused tests
+ configure.ac had -fvisibility detection, but it's not used by
+ spice-gtk. It also has a --enable-static-linkage flag which isn't
+ used anywhere apart from in configure.ac, so remote this too. I
+ think the same effect as --enable-static-linkage can be achieved
+ using make LDFLAGS="-all-static" since we are using libtool.
+
+2011-03-31 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: correct CLIPBOARD_LAST so that array are sized correctly
+
+ gtk: show cursor when cursor-move
+
+ gtk: fix handling of incoming large clipboard data
+ The main fix was probably the agent_msg_pos guin8 -> guint, although I
+ modified the code for more clarity
+
+ gtk: multi-clipboard improvements
+
+2011-03-30 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: fix make dist
+
+ gtk/controller: add XPI controller code
+
+ build: provide a conditional for WIN32
+
+ build fixup
+
+ build: install spice-protocol.vapi
+
+ build: check for vala if necessary
+
+2011-03-28 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: remove some debugging, update TODO
+
+ Revert "gtk/display: remove unused mode name"
+ This reverts commit 33ef5a9368534f7fcb77ef60d8811ae08a707e4f.
+
+2011-03-23 Christophe Fergeau <cfergeau@gmail.com>
+
+ gtk/display: be more paranoid about potentially NULL pointer
+ If things don't go as expected in gnome_rr_config_ensure_primary
+ (for example we don't find any usable output), we may end up
+ trying to dereference a NULL pointer. It's better to check
+ top_left is not NULL before using it.
+
+ gtk: don't attempt to dereference NULL pointer
+ In spice_channel_handle_migrate there's an explicit check for
+ data being NULL. However, we subsequently dereference it twice
+ even when it can be NULL. Add explicit checks to avoid that.
+
+ gtk: remove unused variables
+ They were spotted by the clang static analyzer.
+
+2011-03-23 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/spicy: WIN32 support resolution update
+
+ gtk/spicy: WIN32 GTK icon theme fallback in recentmanager is buggy
+
+ gtk/display: implement windows backend
+
+ gtk/display: remove unused mode name
+
+2011-03-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/display: avoid use of g_assert, we are trying to make a library
+
+ gtk/display: split x11/windows backend
+ For better or worse..
+
+2011-03-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/display: start splitting display x11/windows backend
+
+2011-03-19 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/display: fix build with win32
+
+ TODO: update
+
+ gtk: fix warning when building without sasl
+
+ gtk/spicy: fix win32 build
+
+ build: clean up some unused autoconf.ac
+
+2011-03-17 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ README: minor sasl dependency update
+
+ gtk/channel: return if pubkey is NULL
+ Patch suggested by Alon Levy.
+
+ http://lists.freedesktop.org/archives/spice-devel/2011-March/002943.html
+
+ build: fix a copy&paste typo
+
+ spicy: change current output resolution in fullscreen
+
+ gtk/display: add rr_config_dump
+
+ gtk: import display configuration from gnome-desktop
+
+2011-03-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: fix crash when clipboard_primary owner change
+ Clean up handler when destroyed.
+
+ /usr/local/stow/virt-manager/share/virt-manager/virt-manager.py:450: Warning: g_type_instance_get_private: assertion `instance != NULL && instance->g_class != NULL' failed
+ gtk.main()
+
+ Program received signal SIGSEGV, Segmentation fault.
+ [Switching to Thread 0x7ffff7fd4720 (LWP 19098)]
+ 0x00007fffe8881ab2 in get_selection_from_clipboard (d=0x0, cb=0x1df8510)
+ at spice-widget.c:996
+ 996 if (cb == d->clipboard) {
+ (gdb) bt
+ at spice-widget.c:996
+ 0x30f5750, data=0x1ea3000) at spice-widget.c:1114
+ 0x0, n_param_values=2, param_values=0x1e96a90, invocation_hint=
+ 0x7fffffffd280) at gclosure.c:767
+ detail=0, instance=0x1df8510, emission_return=0x0, instance_and_params=
+ 0x1e96a90) at gsignal.c:3252
+ instance=<value optimized out>, signal_id=<value optimized out>,
+
+ gtk: map-file missig test_common_capability
+
+2011-03-02 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ TODO: update
+
+ gtk: add display width/height properties
+
+2011-03-01 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add multiple selection clipboard sharing
+
+2011-02-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add SASL support
+
+ build: fix spice-client-gtk-3.0.pc requires
+
+2011-02-19 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add private spice_session_get_{password,host,cert_subject}()
+
+ gtk: add error block to spice_channel_recv_link_msg()
+
+ gtk: add spice_channel_flush_sasl()
+
+ gtk: add spice_channel_read_sasl()
+
+ build: add --with-sasl build option (from gtk-vnc)
+
+ gtk: share clipboard images
+
+ gtk: split agent msg to VD_AGENT_MAX_DATA_SIZE if required
+ Fix clipboard sharing of large objects
+
+ gtk: add spice_channel_set_common_capability()
+
+ gtk: make it easier to debug test_capability
+
+ gtk: s/g_get_monotonic_clock/g_get_monotonic_time
+
+ common: add spice_channel_test_common_capability()
+
+2011-02-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ data: update spicy-for-windows.nsis
+
+2011-02-01 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk/spicy: add --version option
+
+2011-01-27 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ release 0.5
+
+ gtk: fix windows build
+
+ common: fix windows build
+
+ gtk: fix hitting wall / real screen borders
+
+2011-01-26 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add "migration-state" enum to make it easier to track migrations
+
+ gtk: when input channel is not ready, silently drop input events
+
+2011-01-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ common: sync with upstream
+
+ common: spice_memdup could accept NULL
+
+ gtk: spicy: add --host-subject argument
+
+ gtk: move channel verification parameter to session
+
+ gtk: rename s/spice-channel-enums/spice-glib-enums
+
+ gtk: add pubkey verification on migration
+
+ gtk: make use of common/ssl_verify.c
+
+ common: add ssl_verify.c common code
+
+ common: ring.h should include stddef for NULL usage
+
+ gtk: add 'pubkey' and 'cert-subject' properties
+
+2011-01-24 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add channel certificate 'verify' property
+
+ gtk: spicy: display connection dialog on TLS error
+
+ TODO, README: update
+
+ gtk: implement MIGRATE_CANCEL
+
+ gtk: track switch host idle source
+
+ gtk: add SpiceMainChannel::migration-started
+ With this signal, it is possible for the client to provide sockets to
+ a migrating session.
+
+2011-01-24 Tiziano Mueller <dev-zero@gentoo.org>
+
+ Use g_free instead of free in fail codepath as well. Warn if password is provided in the uri. Free allocated unencoded uri string.
+
+2011-01-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: handle seamless migrations
+
+ gtk: handle DISPLAY_RESET
+
+ gtk: add spice_session_new_from_session()
+ A light copy constructor for migration.
+
+ gtk: exit coroutine loop of a channel migrating
+
+ gtk: add spice_channel_swap(), swap connection details
+
+ gtk: use a callback to handle spice_channel_recv_msg()
+
+ gtk: add channel_up() helper and SPICE_CHANNEL_STATE_MIGRATING
+
+ gtk: use a session state on disconnection, be reentrant
+
+ gtk: add spice_session_set_port() private API, use it
+
+ TODO: add todo about mouse reaching borders
+
+ gtk: order to clarify what is swapped on migration
+
+ gtk: add private get_channel_{id,type}
+
+2011-01-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: cosmetic, make it look safer session_channel_destroy()
+ Although not necessary, this loop rewrite is easier to read, to see
+ that the function is safe: the function returns when removing the
+ item, so it was safe before but as well...
+
+ gtk: fix small mem-leak
+
+2011-01-19 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: default construction value in property parameter
+
+2011-01-18 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: remove scheme parsing, and tidy up the function
+
+ Merge commit 'refs/merge-requests/2' of git://gitorious.org/spice-gtk/spice-gtk
+
+ gtk: support reconnection during channel loop (coroutine regression)
+ This is needed for protocol downgrade, and TLS switching.
+
+2011-01-17 Tiziano Mueller <dev-zero@gentoo.org>
+
+ Add 'password' to recognized parameters in the uri.
+
+ Use glib's URI parse functions to properly identify the scheme and unescape the string.
+
+ Fixed implicitly declared toupper.
+
+2011-01-16 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: stay unconnected until the FD is provided by the client
+
+2011-01-15 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: fix distcheck
+
+2011-01-15 Daniel P. Berrange <berrange@redhat.com>
+
+ Fix rendering with GTK3
+ In GTK2 world there is an expose_event handler, so a choice
+ of the X11 or cairo backends can be used.
+
+ In GTK3 world only the draw_event exists, which must use
+ cairo
+
+ Disallow python module and X11 rendering with GTK3
+ In GTK3 the python binding is provided via introspection.
+ The X11 rendering code is not compatible with GTK3 since
+ all GTK3 drawing is cairo based and there is no expose_event
+ any more
+
+ Make keyboard code support multiple GDK backends
+ Adapt the keyboard code so that it builds with GTK2 and GTK3,
+ where the latter has multiple GDK backends
+
+ Fix use of GdkDrawable to be compat with GTK3
+ In GTK3, the GdkDrawable class is gone, leaving only GdkWindow.
+ The GdkDrawable class can be mostly avoided in Gtk2, thus
+ eliminating the compat problems with Gtk3. Only a couple of
+ compat calls need to be added to allow compilation on both.
+
+ Adapt build system to allow building with GTK3
+ The new configure flag '--with-gtk' can be used to choose
+ which GTK version to build against, defaulting to GTK2.
+ To enable GTK3 use
+
+ ./configure --with-gtk=3.0
+
+ The libspice-client-glib-2.0.la library is unchanged, building
+ against glib-2.0 at all times.
+
+ The GTK3 build will produce a libspice-client-gtk-3.0.la
+ The include files will also live in $prefix/spice-client-gtk-3.0
+ and the pkgconfig is called spice-client-gtk-3.0 too.
+
+ This allows for full parallel install of GTK2 and GTK3 builds
+
+2011-01-14 Daniel P. Berrange <berrange@redhat.com>
+
+ Include ABI version in library names.
+ To allow easy parallel install of spice-gtk builds against GTK2
+ and GTK3, include the ABI version in the library names.
+
+ libspice-gtk.la -> libspice-gtk-2.0.la
+ libspice-glib.la -> libspice-glib-2.0.la
+
+ The PyGtk module doesn't change because that is obsolete and
+ unused in GTK3 world.
+
+2011-01-14 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: spicy: make recent name similar to a URI without spice://
+
+ gtk: TLS add hostname verification
+
+ gtk: TLS fixes: URI parsing and coroutine regression
+
+2011-01-13 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: spicy: add recent connexions chooser in connect dialog
+
+ gtk: spciy: connect to selected recent item
+
+ gtk: spicy: display recent connexions in chooser list
+
+ data: add spice-mime, and spicy.desktop - disabled for now
+
+ gtk: spicy: correctly unref ui/accel objects
+
+ gtk: warn only if audio playback time is not monotonic
+
+2011-01-12 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ common: add ring_get_length() for debugging purposes
+
+ gtk: simplify debugging of coroutine-related path
+
+ gtk: handle MIGRATE_SWITCH_HOST
+
+2011-01-11 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: make channel_disconnect() a vmethod
+
+ gtk: remove useless g_object_get
+
+ gtk: allow calling spice_main_clipboard_release() even if agent is not connected
+
+ gtk: add some DEBUG related to migration
+
+2011-01-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: build x11 keyboard code with cairo backend
+
+2011-01-09 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: replace echo by AC_MSG_NOTICE, that way it's logged
+
+ build: get rid of _DEPENDENCIES and -lspice-client*
+ Suggested by Jürg Billeter.
+
+2011-01-08 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: be more careful when accessing GDK_WINDOW_XDISPLAY
+
+ gtk: emit ERROR_LINK when connecting to non-spice server
+
+ gtk: fix async reading... booo, that was *really* missing
+
+ update NEWS and TODO for v0.4
+
+2011-01-07 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: ignore clipboard owner signal when main channel disconnected
+
+ gtk: simplify CHANNEL_CLOSE event handling
+
+2011-01-05 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add missing set_delay() symbol to map-file
+
+ build: help libtool/koji install client-glib before client-gtk
+
+2011-01-04 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: fix reconnection from dialog in spicy
+ Closing the session while attempting a new one is a bad idea
+
+ gtk: s/warning/message on failed connect
+
+ build: win32: package libgstdirectsoundsrc.dll as well
+
+ gtk: gstaudio: add recording
+
+2011-01-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: gstaudio: timestamp appsrc buffer to be in sync with audio sink clock
+ If buffer are not timestamped with the current running time, they
+ arrive too late. GStreamer seems to deal with some compensation of
+ buffer jitter, but do not correct clock time. Late buffer are late and
+ not heard.
+
+2010-12-30 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: win32: refix jpeg_boolean to build on mingw
+ Same fix made by Alon Levy in spice.
+
+ Merge commit 'refs/merge-requests/1' of git://gitorious.org/spice-gtk/spice-gtk into integration
+
+ build: win32: add spicy-for-windows.exe scripts
+
+2010-12-29 Tiziano Mueller <dev-zero@gentoo.org>
+
+ jpeg_boolean is a mingw32-libjpeg specific thing. Use a define check rather than a version check.
+
+2010-12-29 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: win32: clean-up and GSocket quirks
+
+2010-12-28 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ build: search for .defs file under $(srcdir)
+
+2010-12-27 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: win32: fallback to g_get_home_dir() if g_getenv() failed
+
+ gtk: win32: channel_new() must be called in main context
+
+ gtk: win32: create a drawing context
+
+2010-12-23 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: pulse: reduce playback latency to 20ms
+
+ gtk: pulse: flush audio buffer on cork
+
+ gtk: synchronize video on mmtime
+
+ gtk: update mm time based on playback time+delay
+
+2010-12-22 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add private spice_channel_get_session()
+
+2010-12-22 Alon Levy <alevy@redhat.com>
+
+ gtk: handle server sending DRAW_COPY before MARK
+
+2010-12-21 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: spicy use shift+f12 for grab sequence
+
+ gtk: handle SPICE_CURSOR_FLAGS_NONE correctly
+
+ update NEWS, fix distcheck
+
+ gtk: improve mouse support in server mode with scaling enabled
+
+2010-12-20 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: fix cursor r/b colors being inverted
+
+ gtk: add support for SPICE_CURSOR_TYPE_COLOR{4,16,32}
+
+ gtk: improve 16bits color code, fix rendering glitches
+
+ gtk: fix scaling for x11 backend
+
+ gtk: spicy, save statusbar/toolbar display status
+ Fix https://bugs.freedesktop.org/show_bug.cgi?id=31991
+
+ gtk: fix scaling line artifacts
+
+ gtk: add a few precondition checks, and modify debug messages
+
+2010-12-18 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: fix a dead-lock in clipboard handling
+ In some condition (in virt-manager but not with spicy),
+ g_main_loop_run() will deadlock. Use GDK_THREAD_LEAVE () like
+ gtk_dialog_run() code.
+
+ Also, turn on clipboard sharing by default.
+
+2010-12-17 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: implement clipboard_paste_from_guest()
+
+ gtk: correctly return empty clipboard request
+
+ gtk: fix invalid memory access on palette cache
+ This fixes a valgrind error:
+
+ GSpice-Message: display_handle_stream_create: id 49
+ (lt-spicy:23948): GSpice-DEBUG: spice-channel-cache.h:107 cache_add: palette 26704 (1)
+ GSpice-Message: display_handle_stream_destroy: id 49
+ ==23948== Invalid read of size 4
+ ==23948== at 0x53C07E9: lz_plt8_to_rgb32_decompress (lz_decompress_tmpl.c:304)
+ ==23948== by 0x53C71FA: lz_decode (lz.c:661)
+ ==23948== by 0x53231AF: canvas_get_lz (canvas_base.c:834)
+ ==23948== by 0x5323747: canvas_get_image_internal (canvas_base.c:1109)
+ ==23948== by 0x5323BD0: canvas_get_image (canvas_base.c:1282)
+ ==23948== by 0x5325FDB: canvas_draw_copy (canvas_base.c:2196)
+ ==23948== by 0x531670A: display_handle_draw_copy (channel-display.c:967)
+ ==23948== by 0x53171B5: spice_display_handle_msg (channel-display.c:1130)
+ ==23948== by 0x52F3B4D: spice_channel_recv_msg (spice-channel.c:1026)
+ ==23948== by 0x52F3E61: spice_channel_iterate_read (spice-channel.c:1140)
+ ==23948== by 0x52F3F51: spice_channel_iterate (spice-channel.c:1163)
+ ==23948== by 0x52F44F7: spice_channel_coroutine (spice-channel.c:1272)
+ ==23948== Address 0x191c067c is 1,132 bytes inside a block of size 1,277 free'd
+ ==23948== at 0x4C27187: free (vg_replace_malloc.c:325)
+ ==23948== by 0x52F1D03: spice_msg_in_unref (spice-channel.c:363)
+ ==23948== by 0x52F3B60: spice_channel_recv_msg (spice-channel.c:1029)
+ ==23948== by 0x52F3E61: spice_channel_iterate_read (spice-channel.c:1140)
+ ==23948== by 0x52F3F51: spice_channel_iterate (spice-channel.c:1163)
+ ==23948== by 0x52F44F7: spice_channel_coroutine (spice-channel.c:1272)
+ ==23948== by 0x53CA1C9: coroutine_trampoline (coroutine_ucontext.c:52)
+ ==23948== by 0x53C9FBA: continuation_trampoline (continuation.c:43)
+ ==23948== by 0x5EED71F: ??? (in /lib64/libc-2.12.90.so)
+ ==23948== by 0xE7F2E7F: ???
+ ==23948==
+
+ The invalid pointer seems to come from an image palette that might not
+ be cached or ref'ed correctly:
+
+ at ../common/canvas_base.c:697
+ 0x7fffe45aab88) at ../common/canvas_base.c:705
+
+ gtk: wip gstreamer audio backend
+
+ gtk: wip scaling support
+
+ gtk/spicy: add scaling option
+
+ gtk: add cairo display backend
+
+ build: basic windows build support
+
+ common: add windows.h where required
+ This patch should be sent to upstream as well..
+
+ common: sync with upstream
+
+ gtk: make pulse audio backend optional
+
+ gtk: revert 16 bits multi-monitor config
+ The Linux vdagent doesn't like multi-monitor configuration.
+
+ build: add map-file in EXTRADIST
+
+ gtk: fix 16bits expose code when black borders >0
+
+ gtk: fix XShm error fallback code
+ XDestroyImage is attempting to free(ximage->data). However, data is
+ owned by the display channel.
+
+ gtk: avoid spurious set_display() calls
+
+ gtk: add support for 16 bits
+
+ gtk: fix video playback being distorted
+
+ gtk: fix windows qxl rendering and warnings
+ Based on experimentation with spicec, it is normal to get
+ surface_destroy() with unknown surface id. Also, it should be
+ considered as an added refcount when adding an existing image/pixmap
+ in the cache.
+
+2010-12-10 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: complete API documentation
+
+2010-12-09 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add g_object_notify_main_context()
+
+ gtk: continue API documentation
+
+2010-12-06 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: hide unwanted public symbols
+
+ gtk: s/vnc/spice/ grab_sequence, break API
+
+ gtk: remove old tcp.c code
+
+ TODO: update
+
+ Merge branch 'wip/coroutines'
+
+ gtk: first stab at gtk-doc documentation
+
+2010-12-05 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: WIP coroutines playback & record
+
+ gtk: WIP coroutines inputs
+
+ gtk: WIP coroutines display
+
+ gtk: WIP coroutines cursor
+
+ gtk: WIP coroutines main channel
+
+ gtk: WIP handle disconnect with coroutines
+
+ gtk: WIP tidy main_context_signal_emit() up
+ Add g_signal_emit_main_context() and make use of it
+
+ gtk: WIP make coroutine loop overridable
+
+ gtk: WIP add the support for system -> coroutine write
+
+ gtk: WIP spice-channel documentation
+
+ gtk: WIP enable TLS connection with coroutines
+
+ gtk: WIP use coroutines in spice-channel
+
+ gtk: WIP use coroutines and GSocket to connect
+
+ gtk: add coroutine utilities
+
+ gtk: fix an invalid clipboard memory copy
+
+ gtk: don't grab our own guest grab
+ Hack? There might be a better way to do that...
+
+ gtk: fix an invalid clipboard memory copy
+
+ gtk: don't grab our own guest grab
+ Hack? There might be a better way to do that...
+
+ build: add .gitignore
+
+ gtk: SPICE_DEBUG glz_decoder_window_resize message
+
+2010-12-03 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: fix crash when spicy configuration is empty
+
+ gtk: fix crash when spicy configuration is empty
+
+ gtk: remove invalid properties warning in spicy
+
+ build: spice-protocol >= 0.6.3 required
+
+ gtk: remove invalid properties warning in spicy
+
+ build: spice-protocol >= 0.6.3 required
+
+2010-12-02 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: visibility option for statusbar/toolbar in spicy
+
+ gtk: delay PA stream creation when context is ready
+
+ gtk: don't uncork new streams
+
+2010-12-01 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: save/restore spicy configuration
+ Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=31991
+
+ gtk: add CELT recording
+
+ gtk: add CELT playback
+
+2010-11-30 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add {session,channel}_open_fd()
+
+2010-11-29 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add channel.set_capability()
+
+ gtk: put some g_message() under SPICE_DEBUG
+
+ TODO: update
+
+ gtk: add clipboard sharing for text
+
+ gtk: add dispay config
+
+2010-11-26 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: progressive agent message recomposition
+
+ gtk: add jpeg decoder
+
+ gtk: add zlib decoder
+
+ build: fix make -j
+
+ build: re-enable -Wflags, and fix a few warnings
+
+ build: use git-version-gen
+
+2010-11-25 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ README: add a few missing dependencies
+
+ gtk: disconnect record stream when record_stop()
+ This behaviour is different than playback. The main difference is that
+ a playback stream will stay active, while the recording stream will be
+ removed: that way the GNOME volume control can notice the user there
+ is no active recording, by hiding the microphone icon.
+
+ Playback is more frequent (sounds events...) and it would be
+ unfriendly if the stream was removed/added every now and then from the
+ volume control list.
+
+ build: update build depedencies
+
+ build: update README
+
+ po: add fr translation
+
+ gtk: mark spice-cmdline strings as translatable
+
+ gtk: make snappy translatable
+
+ gtk: remove spice prefix in default signal handler
+
+ gtk: add raw audio recording
+
+2010-11-24 Marc-André Lureau <marcandre.lureau@redhat.com>
+
+ gtk: add channel_test_capability()
+
+ gtk: add save mm_time in session
+
+ add AUTHORS & TODO
+
+ i18: add basic support - mark translatable spicy strings
+
+ gtk: read remote caps
+
+ gtk: add a couple of new TODO
+
+ gtk: handle agent token
+
+ gtk: add SPICE_MSG_DISCONNECTING handler
+
+ gtk: don't send inputs before the channel is ready, or else it will eof
+
+ gtk: expose Audio object in python
+
+ gtk: fix MainChannel python bindings
+
+ gtk: ensure we sync key locks after connection
+
+ gtk: move audio stuff in client-glib
+
+ gtk: fix make distcheck
+
+ gtk: fix out of dir build
+
+ gtk: add missing copyright headers
+
+ README: move from gtk/ to /
+
+ build: install gtk and glib headers in different dirs
+ And various improvements
+
+ gtk: current code is blocking - remove O_NONBLOCK
+
+ gtk: add padding on common base classes: channe/session/widget
+
+ gtk: send the channel caps
+
+ gtk: uncomment some agent string-msg table entries
+ I don't know why it was commented.
+
+ gtk: sync keyboard lock (X11 only)
+
+ gtk: release keys on disconnect
+
+ gtk: fix getpixbuf colorspace
+
+ gtk: make spice_session_disconnect() reentrant
+
+ gtk: a channel own a ref on a session
+ This fix calling session_disconnect() in a main_channel_event() callback for instance.
+
+ gtk: add a couple of warning on invalid arguments in public methods
+
+ gtk: use sane default values for spice_audio_new()
+
+ gtk: passing seems wrong, it should be the context
+
+ gtk: adapted to be a working C library
+
+ gtk: handle display-mark
+
+ gtk: hack to handle scrolling
+
+ gtk: implement cursor_reset and plug a memleak
+
+ build: fix a few warnings reported by clang
+
+ gtk: add a flag to turn debug off, SPICE_DEBUG=1 to override
+
+ gtk: don't dereference NULL pointers in destroy
+ On some error conditions, that happens.
+
+ gtk: add get_pixbuf() for 8/8/8 surfaces
+
+ gtk: add display_send_keys() again, adapted from gtk-vnc..
+
+ gtk: signal keybard-grab status
+ Perhaps we should have grab/ungrab signals, instead of an int...
+
+ gtk: add support fro grab keys, based on gtk-vnc code
+
+ gtk: track when mouse/keyboard grab fail
+ Avoid sending mouse-grab true if the grab failed.
+
+ gtk: python module, register enums
+
+ gtk: untabify
+
+ gtk: use SPICE_DEBUG_CURSOR=1 for debugging
+
+ gtk: allow key repeatition
+
+ gtk: get rid of the remaining assert()
+
+ gtk: make more build silent
+
+ gtk: python module - add manualy defined bindings
+
+ gtk: fix a few gcc warnings
+
+ gtk: add pygtk module
+
+ gtk: remove spice_channel_id() function
+ The value can be retrieved by property
+
+ gtk: remove spice- prefix in signal name
+
+ gtk: remove spice-event
+ The abstraction was not really useful, a bit buggy, and a bit more restrictive
+
+ gtk: get rid of asserts, they are not good in libraries
+
+ gtk: use g_log functions instead of fprintf and custom handler
+
+ gtk: make spice_msg_out private
+
+ gtk: GObject Introspection support
+
+2010-11-23 Gerd Hoffmann <kraxel@redhat.com>
+
+ fix channel cleanup (unbreaks tls)
+
+ spicy: quit on connect failure
+
+ cursor tweaks
+
+ widget: server mouse fixups.
+
+ spicy: use uri for recent entries.
+
+ session: add uri property.
+
+ sound: add recording [not finished yet]
+
+ display: release cursors
+
+ drop+improve debug messages. make protocol a session not a channel property.
+
+ handle partial link message reads
+
+ display: release streams
+
+ display: release glz window bits
+
+ display: release surfaces
+
+ display: release cached palettes and images
+
+ move resize timer from widget to display channel
+
+ more object destruction fixes
+
+ misc object destruction fixes
+
+ spicy cleanup fixes
+
+ display: move IPC_RMID to avoid shm leaking
+
+ spicy: allocate all state storage
+
+ inputs fixups
+
+ spicy: use modifier signal, improve status line.
+
+ inputs: add modifier signal.
+
+ stream regions
+
+ spicy: use grab-mouse signal, set initial kbd focus
+
+ spice widget: some agent bits, add mouse-grab signal
+
+ some more agent bits
+
+ main channel signal fixup.
+
+ auit when the connect dialog is canceled.
+
+ handle VD_AGENT_ANNOUNCE_CAPABILITIES
+
+ mouse and agent interface tweaks.
+
+ connect dialog windup
+
+ spicy: started working on a fancy connect dialog.
+
+ switch snappy to glib command line parsing, factor out common spice options.
+
+ make option menu more verbose
+
+ switch spicy to glib command line parsing
+
+ add audio init wrapper, move pulse bits into gtk lib.
+
+ make spice_session_get_channels return a glist
+
+ rename spice_msg get/put functions to ref/unref
+
+ more clipboard bits
+
+ early cut+paste bits
+
+ zap sub-message debug printfs
+
+ display: handle inval-list message, fix image cacheing.
+
+ spice-channel: Handle incoming sub messages.
+
+ Add glib objects + gtk widgets for spice.
+
+2010-11-23 Marc-André Lureau <marcandre.lureau@gmail.com>
+
+ Initial import from SPICE
--- /dev/null
+ACLOCAL_AMFLAGS = -I m4
+NULL =
+
+SUBDIRS = spice-common src man po doc data
+
+if BUILD_TESTS
+SUBDIRS += tests
+endif
+
+if HAVE_INTROSPECTION
+if WITH_VALA
+SUBDIRS += vapi
+endif
+endif
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = \
+ spice-client-glib-2.0.pc \
+ $(NULL)
+
+if WITH_GTK
+pkgconfig_DATA += spice-client-gtk-3.0.pc
+endif
+
+if WITH_CONTROLLER
+pkgconfig_DATA += spice-controller.pc
+endif
+
+INTLTOOL_FILES = \
+ intltool-extract.in \
+ intltool-merge.in \
+ intltool-update.in \
+ $(NULL)
+
+DISTCLEANFILES = \
+ $(pkgconfig_DATA) \
+ intltool-extract \
+ intltool-merge \
+ intltool-update \
+ gnome-doc-utils.make \
+ po/.intltool-merge-cache \
+ $(NULL)
+
+EXTRA_DIST = \
+ build-aux/git-version-gen \
+ gtk-doc.make \
+ .version \
+ $(INTLTOOL_FILES) \
+ $(NULL)
+
+MAINTAINERCLEANFILES = \
+ ABOUT-NLS \
+ aclocal.m4 \
+ config.h.in \
+ m4/gtk-doc.m4 \
+ m4/intltool.m4 \
+ m4/libtool.m4 \
+ m4/ltoptions.m4 \
+ m4/ltsugar.m4 \
+ m4/ltversion.m4 \
+ m4/lt~obsolete.m4 \
+ build-aux/ar-lib \
+ build-aux/compile \
+ build-aux/config.guess \
+ build-aux/config.rpath \
+ build-aux/config.sub \
+ build-aux/depcomp \
+ build-aux/install-sh \
+ build-aux/ltmain.sh \
+ build-aux/missing \
+ build-aux/mkinstalldirs \
+ build-aux/test-driver \
+ po/Makefile.in.in \
+ gtk-doc.make \
+ $(NULL)
+
+# Generate the ChangeLog file
+# and insert it into the directory we're about to use to create a tarball.
+.PHONY: gen-ChangeLog gen-THANKS
+gen-ChangeLog:
+ if test -d .git || test -d ../.git; then \
+ $(top_srcdir)/build-aux/gitlog-to-changelog > $(distdir)/cl-t; \
+ rm -f $(distdir)/ChangeLog; \
+ mv $(distdir)/cl-t $(distdir)/ChangeLog; \
+ fi
+
+# see git-version-gen
+dist-hook: gen-ChangeLog gen-THANKS
+ echo $(VERSION) > $(distdir)/.tarball-version
+
+BUILT_SOURCES = $(top_srcdir)/.version
+$(top_srcdir)/.version:
+ echo $(VERSION) > $@-t && mv $@-t $@
+
+DISTCHECK_CONFIGURE_FLAGS = \
+ --enable-introspection \
+ --disable-vala \
+ --disable-usbredir \
+ --enable-gtk-doc \
+ --enable-werror \
+ --with-gtk=3.0 \
+ $(NULL)
+
+gen-THANKS:
+ $(AM_V_GEN)if test -d .git || test -d ../.git; then \
+ echo "The spice-gtk team would like to thank the following contributors:" > $(distdir)/t-t; \
+ echo >> $(distdir)/t-t; \
+ git log --format='%aN <%aE>' | sort -u >> $(distdir)/t-t; \
+ rm -f $(distdir)/THANKS; \
+ mv $(distdir)/t-t $(distdir)/THANKS; \
+ fi
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@BUILD_TESTS_TRUE@am__append_1 = tests
+@HAVE_INTROSPECTION_TRUE@@WITH_VALA_TRUE@am__append_2 = vapi
+@WITH_GTK_TRUE@am__append_3 = spice-client-gtk-3.0.pc
+@WITH_CONTROLLER_TRUE@am__append_4 = spice-controller.pc
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/ld-version.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/manywarnings.m4 \
+ $(top_srcdir)/m4/spice-compile-warnings.m4 \
+ $(top_srcdir)/m4/warnings.m4 \
+ $(top_srcdir)/spice-common/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps) $(am__DIST_COMMON)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = spice-client-glib-2.0.pc spice-client-gtk-3.0.pc \
+ spice-controller.pc
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
+DATA = $(pkgconfig_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+ $(LISP)config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+DIST_SUBDIRS = spice-common src man po doc data tests vapi
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+ $(srcdir)/spice-client-glib-2.0.pc.in \
+ $(srcdir)/spice-client-gtk-3.0.pc.in \
+ $(srcdir)/spice-controller.pc.in \
+ $(top_srcdir)/build-aux/ar-lib $(top_srcdir)/build-aux/compile \
+ $(top_srcdir)/build-aux/config.guess \
+ $(top_srcdir)/build-aux/config.sub \
+ $(top_srcdir)/build-aux/install-sh \
+ $(top_srcdir)/build-aux/ltmain.sh \
+ $(top_srcdir)/build-aux/missing AUTHORS COPYING NEWS README \
+ TODO build-aux/ar-lib build-aux/compile build-aux/config.guess \
+ build-aux/config.sub build-aux/install-sh build-aux/ltmain.sh \
+ build-aux/missing
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ if test -d "$(distdir)"; then \
+ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -rf "$(distdir)" \
+ || { sleep 5 && rm -rf "$(distdir)"; }; \
+ else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2
+GZIP_ENV = --best
+DIST_TARGETS = dist-bzip2 dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+ACL_HELPER_DIR = @ACL_HELPER_DIR@
+ACL_LIBS = @ACL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMMON_CFLAGS = @COMMON_CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GOBJECT2_CFLAGS = @GOBJECT2_CFLAGS@
+GOBJECT2_LIBS = @GOBJECT2_LIBS@
+GREP = @GREP@
+GSTAUDIO_CFLAGS = @GSTAUDIO_CFLAGS@
+GSTAUDIO_LIBS = @GSTAUDIO_LIBS@
+GSTVIDEO_CFLAGS = @GSTVIDEO_CFLAGS@
+GSTVIDEO_LIBS = @GSTVIDEO_LIBS@
+GST_INSPECT_1_0 = @GST_INSPECT_1_0@
+GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
+GTHREAD_LIBS = @GTHREAD_LIBS@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_REQUIRED = @GTK_REQUIRED@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+JPEG_LIBS = @JPEG_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUSB_HOTPLUG_CFLAGS = @LIBUSB_HOTPLUG_CFLAGS@
+LIBUSB_HOTPLUG_LIBS = @LIBUSB_HOTPLUG_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PHODAV_CFLAGS = @PHODAV_CFLAGS@
+PHODAV_LIBS = @PHODAV_LIBS@
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PNP_IDS = @PNP_IDS@
+POFILES = @POFILES@
+POLICYDIR = @POLICYDIR@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PULSE_CFLAGS = @PULSE_CFLAGS@
+PULSE_LIBS = @PULSE_LIBS@
+PYTHON = @PYTHON@
+RANLIB = @RANLIB@
+SASL_CFLAGS = @SASL_CFLAGS@
+SASL_LIBS = @SASL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_CFLAGS = @SPICE_CFLAGS@
+SPICE_GLIB_CFLAGS = @SPICE_GLIB_CFLAGS@
+SPICE_GLIB_REQUIRES = @SPICE_GLIB_REQUIRES@
+SPICE_GTK_CFLAGS = @SPICE_GTK_CFLAGS@
+SPICE_GTK_LOCALEDIR = @SPICE_GTK_LOCALEDIR@
+SPICE_GTK_MAJOR_VERSION = @SPICE_GTK_MAJOR_VERSION@
+SPICE_GTK_MICRO_VERSION = @SPICE_GTK_MICRO_VERSION@
+SPICE_GTK_MINOR_VERSION = @SPICE_GTK_MINOR_VERSION@
+SPICE_GTK_REQUIRES = @SPICE_GTK_REQUIRES@
+SPICE_PROTOCOL_CFLAGS = @SPICE_PROTOCOL_CFLAGS@
+SPICE_PROTOCOL_LIBS = @SPICE_PROTOCOL_LIBS@
+SSL_CFLAGS = @SSL_CFLAGS@
+SSL_LIBS = @SSL_LIBS@
+STOW = @STOW@
+STRIP = @STRIP@
+USBREDIR_CFLAGS = @USBREDIR_CFLAGS@
+USBREDIR_LIBS = @USBREDIR_LIBS@
+USB_IDS = @USB_IDS@
+USE_NLS = @USE_NLS@
+VALAC = @VALAC@
+VAPIDIR = @VAPIDIR@
+VAPIGEN = @VAPIGEN@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_LDFLAGS = @WARN_LDFLAGS@
+WARN_PYFLAGS = @WARN_PYFLAGS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+XGETTEXT = @XGETTEXT@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I m4
+NULL =
+SUBDIRS = spice-common src man po doc data $(am__append_1) \
+ $(am__append_2)
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = spice-client-glib-2.0.pc $(NULL) $(am__append_3) \
+ $(am__append_4)
+INTLTOOL_FILES = \
+ intltool-extract.in \
+ intltool-merge.in \
+ intltool-update.in \
+ $(NULL)
+
+DISTCLEANFILES = \
+ $(pkgconfig_DATA) \
+ intltool-extract \
+ intltool-merge \
+ intltool-update \
+ gnome-doc-utils.make \
+ po/.intltool-merge-cache \
+ $(NULL)
+
+EXTRA_DIST = \
+ build-aux/git-version-gen \
+ gtk-doc.make \
+ .version \
+ $(INTLTOOL_FILES) \
+ $(NULL)
+
+MAINTAINERCLEANFILES = \
+ ABOUT-NLS \
+ aclocal.m4 \
+ config.h.in \
+ m4/gtk-doc.m4 \
+ m4/intltool.m4 \
+ m4/libtool.m4 \
+ m4/ltoptions.m4 \
+ m4/ltsugar.m4 \
+ m4/ltversion.m4 \
+ m4/lt~obsolete.m4 \
+ build-aux/ar-lib \
+ build-aux/compile \
+ build-aux/config.guess \
+ build-aux/config.rpath \
+ build-aux/config.sub \
+ build-aux/depcomp \
+ build-aux/install-sh \
+ build-aux/ltmain.sh \
+ build-aux/missing \
+ build-aux/mkinstalldirs \
+ build-aux/test-driver \
+ po/Makefile.in.in \
+ gtk-doc.make \
+ $(NULL)
+
+BUILT_SOURCES = $(top_srcdir)/.version
+DISTCHECK_CONFIGURE_FLAGS = \
+ --enable-introspection \
+ --disable-vala \
+ --disable-usbredir \
+ --enable-gtk-doc \
+ --enable-werror \
+ --with-gtk=3.0 \
+ $(NULL)
+
+all: $(BUILT_SOURCES) config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @test -f $@ || rm -f stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+spice-client-glib-2.0.pc: $(top_builddir)/config.status $(srcdir)/spice-client-glib-2.0.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+spice-client-gtk-3.0.pc: $(top_builddir)/config.status $(srcdir)/spice-client-gtk-3.0.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+spice-controller.pc: $(top_builddir)/config.status $(srcdir)/spice-controller.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $@
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+install-pkgconfigDATA: $(pkgconfig_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
+ done
+
+uninstall-pkgconfigDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+ -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__post_remove_distdir)
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__post_remove_distdir)
+
+dist-lzip: distdir
+ tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+ $(am__post_remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__post_remove_distdir)
+
+dist-tarZ: distdir
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__post_remove_distdir)
+
+dist-shar: distdir
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__post_remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__post_remove_distdir)
+
+dist dist-all:
+ $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+ $(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lz*) \
+ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build/sub \
+ && ../../configure \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=../.. --prefix="$$dc_install_base" \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__post_remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(DATA) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-pkgconfigDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-pkgconfigDATA
+
+.MAKE: $(am__recursive_targets) all check install install-am \
+ install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+ am--refresh check check-am clean clean-cscope clean-generic \
+ clean-libtool cscope cscopelist-am ctags ctags-am dist \
+ dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \
+ dist-tarZ dist-xz dist-zip distcheck distclean \
+ distclean-generic distclean-hdr distclean-libtool \
+ distclean-tags distcleancheck distdir distuninstallcheck dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am \
+ uninstall-pkgconfigDATA
+
+.PRECIOUS: Makefile
+
+
+# Generate the ChangeLog file
+# and insert it into the directory we're about to use to create a tarball.
+.PHONY: gen-ChangeLog gen-THANKS
+gen-ChangeLog:
+ if test -d .git || test -d ../.git; then \
+ $(top_srcdir)/build-aux/gitlog-to-changelog > $(distdir)/cl-t; \
+ rm -f $(distdir)/ChangeLog; \
+ mv $(distdir)/cl-t $(distdir)/ChangeLog; \
+ fi
+
+# see git-version-gen
+dist-hook: gen-ChangeLog gen-THANKS
+ echo $(VERSION) > $(distdir)/.tarball-version
+$(top_srcdir)/.version:
+ echo $(VERSION) > $@-t && mv $@-t $@
+
+gen-THANKS:
+ $(AM_V_GEN)if test -d .git || test -d ../.git; then \
+ echo "The spice-gtk team would like to thank the following contributors:" > $(distdir)/t-t; \
+ echo >> $(distdir)/t-t; \
+ git log --format='%aN <%aE>' | sort -u >> $(distdir)/t-t; \
+ rm -f $(distdir)/THANKS; \
+ mv $(distdir)/t-t $(distdir)/THANKS; \
+ fi
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+v0.33
+=====
+
+- lz4 compression of USB channel
+- keyboard: pause key fixes, set keypress-delay to 0 on local socket
+- mouse: fix pointer grabbing in server mode
+- clipboard: fix copying text from old application without UTF8_STRING
+ target (motif)
+- file-xfer changes: grouping all transferred files per operation
+- new spice_file_transfer_task_get_{total_bytes,transferred_bytes} API
+ and associated properties
+- new SpiceChannel:socket property
+- fix rendering issues with CSD on Windows
+- fix gettext support, some translations updates
+- fix display refresh issue on f25 after resize (init egl only when
+ required)
+- many leaks and races fixes, new tests
+
+v0.32
+=====
+
+libspice-client-gtk API/ABI break: library soname/version has been
+bumped, and deprecated symbols have been removed. In practice, most
+of the API (in particular for language bindings) should be unchanged.
+
+- drop gtk+ 2.0 support
+- require gtk+ >= 3.12 and glib >= 2.36
+- add GStreamer as a backend for mjpeg, vp8 & h264 decoding
+ This allows the upcoming Spice server release to send video
+ regions with better codecs.
+- a number of spice-gtk structures are now private
+- spice-gtk widget is no longer a GtkDrawingArea but an opaque type
+ with only guarantee to be a GtkWidget
+- virgl: use GtkGlArea if possible (on wayland only atm)
+- virgl: various fixes (multiple display, resize, canvas-less support)
+- win-usbredir: use UsbDk backend when available and various
+ improvements
+- ensure that dnd file copy get cancelled
+- some JP and KR keyboard handling fixes on Windows
+- fix SASL GSSAPI
+- fix ipv6 proxy address handling
+- allow smaller widget with scaling enabled
+- add spice_main_request_mouse_mode() to request mouse mode
+- add SpiceGtkSession:sync-modifiers to change modifiers sync behaviour
+- various video decoding improvements
+- use GTask instead of GSimpleAsyncResult
+- misc bindings, leaks, warnings, and spelling fixes
+
+v0.31
+=====
+
+- NOTE: this is the last release to support gtk+ 2.0
+- add local GL scanout support for virtio-gpu/virgl guests
+- new file-transfer API, to be able to monitor transfers etc
+- new spice_display_change_preferred_compression() API
+- better authentication error reports
+- usbredir: drop isoc packets on low bandwidth (rhbz#1264156)
+- usbredir: add counter of free channels (rhbz#1298772)
+- add a toplevel include header spice-client-gtk.h
+- grab keyboard based on session focus (rhbz#1275231)
+- don't print error message on successful file transfer (rhbz#1265562)
+- allow simultaneous support for Pulse and GStreamer audio
+- remove GSlice usage
+- some BE endianness fixes
+- misc leak and use after-free fixes
+- documentation fixes
+
+v0.30
+=====
+- spice-protocol is no longer bundled with spice-gtk. Requires
+ spice-protocol >= 0.12.10
+- Handle single headed monitors that have a non-zero x, y config
+- various small improvements to 'spicy' test application
+- Fix build with automake < 1.13
+- various bug fixes and improvements
+- New API:
+ - spice_main_update_display_enabled()
+ - Add SpiceSession::preferred-compression property and
+ --spice-preferred-compression commandline switch (requires a
+ yet-to-be-released version of spice server)
+- ability to set the SpiceDisplay::keypress-delay property via a new
+ SPICE_KEYPRESS_DELAY environment variable
+
+v0.29
+=====
+
+- sync guest audio volume with client volume
+- use stream volume for PulseAudio source
+- on Windows, fail early during initialization if the usbclerk service
+ can't be reached
+- fix audio and usb managers to work with client provided fds
+- many crasher and bug fixes
+
+v0.28
+=====
+
+- webdav improvements:
+ - no longer spawn a server thread
+ - no longer use local TCP sockets & port
+ - provides read-only mode with SpiceSession:share-dir-ro
+ - requires libphodav-2.0 glib-2.0 >= 2.43.90 libsoup-2.4 >= 2.49.91
+- drop gstreamer 0.10 in favour of 1.0
+- add spice+unix://path connection support
+- accept URI with empty parameters value,
+ such as spice://localhost?port=5900&tls-port=
+- fixed lz4 support
+- silence some harmless warnings
+- misc API documentation improvements
+- switch-host migration fixes
+- learn to build --without-gtk
+- bugs and regressions fixes
+
+v0.27
+=====
+
+- add GStreamer 1.0 audio support
+- add LZ4 compression algorithm support
+- learn to release the keyboard grab on release keys pressed (ctrl+alt
+ by default), to let alt+f4/alt-tab and others for client side
+- session and channels life-cycle changes: a channel will no longer
+ hold a reference after session disconnection
+- migration fixes, fail early on client provided fds (this is left to
+ solve in the future)
+- fix support for Gtk+ 3.0 on Windows
+- clipboard size fixes
+- server-side pointer drawing on grab
+- new APIs:
+ spice_usb_device_get_libusb_device()
+ spice_session_is_for_migration()
+- build-sys improvements
+
+v0.26
+=====
+
+- allow transferring multiple files at once with dnd
+- avoid guest-side fd leak when transferring empty files
+ with dnd
+- add support for passing a username with SASL authentication
+- hide guest cursor when ungrabbing mouse in server mode
+- make sure client cursor is in the same position as the guest cursor when
+ ungrabbing mouse in server mode
+- add man page for command line options of application using spice-gtk
+- strip '\0' from text clipboard data
+- fix synchronization of keyboard modifiers
+- coroutine improvements
+- use http by default when SPICE_PROXY uri has no scheme
+
+v0.25
+=====
+
+- Fix SPICE_GTK_MICRO_VERSION define for default value
+- Make "phodav", the webdav server, an external dependency rather than
+ a submodule
+
+v0.24
+=====
+
+- support folder sharing, via WebDAV channel
+- add HTTPS proxy support (requires glib 2.28), and Basic auth
+- add SPICE_GTK_CHECK_VERSION macro
+- advertise SASL capability early (to help fips-enabled servers)
+- fix crash when releasing primary surface
+- fix a few memory leaks with SASL
+- fix spice_display_get_pixbuf() with offset area
+- build-sys improvements
+
+- note: until now, providing an invalid plain-port didn't error, and
+ was falling back silently on tls-port. With this release, an error
+ will be reported if the port can't be opened.
+
+v0.23
+=====
+
+- support Opus codec for audio channels
+- ssl: use tls 1.0 or better
+- support gdbus instead of dbus-glib when available
+- misc build-sys, compile and runtime fixes
+
+v0.22
+=====
+
+- improve inverted cursor support
+- use system-wide trust certificate store
+- make sasl support work with other method than MD5
+- fix some clipboard crasher, limit clipboard size
+- fix various regressions:
+ usbredir, alt-tab on win32, palette crash, agent notification, old
+ protocol support, sasl ending crash, gthread coroutine crash, close
+ sockets on migration, pulse backend crash
+- fix a few memory leaks
+- build-sys improvements
+
+v0.21
+=====
+
+- improve inverted cursor support
+- win32 usb redirected device uninstall fix
+- add support for libusb hotplug API
+- smartcard initialization fixes
+- c&p converts line-endings if necessary
+- rendering and overall performance improvements
+- build and bindings fixes
+
+v0.20
+=====
+
+- adaptive video streaming support (sync with PulseAudio backend only)
+- add spice_usb_device_manager_get_devices_with_filter()
+- add --spice-secure-channels to explicitely specify secure channels
+- multi-monitor, win32, USB redir fixes
+- add basic gtk+ wayland and broadway backend support
+- removed the GnomeRR code
+
+v0.19
+=====
+
+This is a bugfix only release, except the snappy name change
+- snappy has been renamed to spicy-screenshot
+- Several file-xfer fixes and improvements
+- Many win32 and USB redirection related fixes
+- Compile and work again with RHEL6 and older glib releases
+- misc fixes and improvements
+
+v0.18
+=====
+
+- Build fix with Gtk+ unstable.
+- MinGW build fixes with old headers
+- Fix USB coldplug race
+- Fixes rhbz#908057
+
+v0.17
+=====
+
+- Update spice-common with fedora 875348, 826036 fixes
+- Multi-monitor fixes (avoid monitor order shuffling, fix mouse offset
+ if monitor 0 is not at +0+0 and let agent do monitor offset)
+- Add support for VD_AGENT_CAP_SPARSE_MONITORS_CONFIG
+- Add controller & session "proxy" properties
+- Add drag and drop file copy support to send file to guest, you will
+ need capable agent to use that feature. Adds spice_main_file_copy_async()
+- Introspection fixes
+- Build fixes
+
+v0.16
+=====
+
+- Fix crash with SSL connection (#890464)
+- Send monitor config to the agent on spice_main_set_display_enabled() (#881072)
+- Fix channel leak and wrong condition in spice_channel_flush()
+- Build fixes
+
+v0.15
+=====
+
+- Add HTTP Proxy support (only with glib >= 2.26)
+- Add "port" channel support, to allow arbitrary communication on top
+ of spice connection
+- usb-redir: fix migration support
+- win32: various keyboard & mouse fixes
+- Add info message when USB dialog is empty
+- Fix initial black screen on some 16bits guest
+- Various bug fixes and improvements
+
+v0.14
+=====
+
+- Support for seamless migration
+- Improve scaling handling, add downscale-only property to give more
+ control over scaling
+- Better handle key press/release events in high-latency situations,
+ this should avoid unwanted key repetitions
+- Improve unescaping in URI parsing
+- Fix symbol versioning which was broken in 0.13
+- Fix for CVE-2012-4425
+- Various bug fixes and improvements
+
+v0.13
+=====
+
+- ABI break! SONAME has been bumped, all programs and libraries
+ linking to spice-gtk need to be recompiled against this version
+- Add support for USB device redirection on Windows
+- Add monitors config support (multiple monitors in same display)
+- Inhibit automount on GNOME desktop, to ease USB redirection
+- Better video support (reduce some glitches)
+- Misc migration fixes
+- Various bug fixes and improvements
+
+v0.12
+=====
+
+- Fix memory leak when guest is resized
+- Fix color-depth setting
+- Hide/Show cursor correctly when needed
+- Fix blue-tinted video with old Spice servers
+- Correct scroll-event not received with recent Gtk+
+- Fix various migrations issues
+- Allow to disable CELT encoding at runtime with SPICE_DISABLE_CELT
+- Various crash fixes (on pubkey, recording, clipboard)
+- Build changes (common submodule) and fixes
+
+v0.11
+=====
+
+- Fix semi-seamless migration regression
+- Add Spice session UUID and name support
+- Add foreign menu support to controller library
+- Add a simple controller testing tool spice-controller-dump
+- Build fixes
+
+v0.10
+=====
+
+- USB redir is now aware of host/guest side filtering
+- you can query spice_usb_device_manager_can_redirect_device()
+- fix the usbredir channel lifetime to be equal to session lifetime
+- set keepalive on channel socket
+- fix hangs on windows when using ssl chanels
+- add a SpiceDisplay::zoom-level to maintain a scaling ratio
+- add controller ENABLE_SMARTCARD option
+- remove a few warnings, ui improvements, build fixes
+
+v0.9
+====
+
+- Add command line options for setting the cache size and the glz window size
+- Add a USB device selection widget to libspice-client-gtk
+- Various bug fixes and code improvements
+
+v0.8
+====
+
+- add USB redirection support, see Hans comments in the log and that
+ post for details: http://hansdegoede.livejournal.com/11084.html
+- introduce SpiceGtkSession to deal with session-wide Gtk events, such
+ as clipboard, instead of doing it per display
+- many cursor and keyboard handling improvements
+- handle the new "semi-seamless" migration
+- support new Spice mini-headers
+- better coroutines: fibers on windows & jmp on linux
+- add Vala vapi bindings generation
+- many bug fixes and code improvements
+
+v0.7
+====
+
+- smartcard support
+- better video playback performance (jpeg-turbo & audio improvements)
+- support for audio volume (needs qemu support)
+- controller support for Windows (NamedPipe)
+- make perl-Text-CSV optional for tarball builds
+- new spice_get_option_group()/spice_set_session_option()
+- keyboard improvements, grab-sequence can be configured, various windows fixes
+- new tool spicy-stats, to collect informations during a session
+- bugfixes: memleak fixes, SASL fixes, crash with virt-manager
+- various build fixes, should build on MacOS as well now
+
+v0.6
+====
+
+- multi-head is working now!
+- change client resolution if guest can't
+- support sharing large clipboard, and images
+- multiple clibpoard selection
+- support SASL authentication
+- add experimental/unstable controller API
+- and a bunch of various smaller fixes
+
+v0.5
+====
+
+- Compatibility with gtk2 and gtk3
+- Migrations: seamless and switch host methods
+- SSL verification: public key, subject and host checks added
+- spice:// url parsing learned "password" argument
+- spicy: recent connexions UI added
+- various minor fixes
+
+v0.4
+====
+
+- sync video with pulseaudio backend
+- build with mingw, and run on Windows
+- various minor fixes
+
+v0.3
+====
+
+- fix Windows QXL driver support
+- fully asynchronous operations using coroutines
+ (thanks go to gtk-vnc devs)
+- cairo display (old XShm display can be enabled with --with-x11)
+- scaling support for cairo display
+- experimental audio support using GStreamer
+- API reference gtk-doc
+- more cursor type support
+- various fixes and cleanup
+
+v0.2
+====
+
+- gtk: disconnect record stream when record_stop()
+- README: add a few missing dependencies
+- build: use git-version-gen
+- build: re-enable -Wflags, and fix a few warnings
+- build: fix make -j
+- gtk: add zlib decoder
+- gtk: add jpeg decoder
+- gtk: progressive agent message recomposition
+- gtk: add dispay config
+- gtk: add clipboard sharing for text
+- TODO: update
+- gtk: put some g_message() under SPICE_DEBUG
+- gtk: add channel.set_capability()
+- gtk: add {session,channel}_open_fd()
+- gtk: add CELT playback
+- gtk: add CELT recording
+- gtk: save/restore spicy configuration
+- gtk: don't uncork new streams
+- gtk: delay PA stream creation when context is ready
+- gtk: visibility option for statusbar/toolbar in spicy
+
+v0.1.0
+======
+
+- desktop display, using GLZ compression
+- audio playback/recording with PulseAudio
+- video in mjpeg
+- python and gobject-introspection modules
+- spicy: a simple Gtk client
+- snappy: a command line screenshot tool
--- /dev/null
+spice-gtk
+=========
+
+A Gtk client and libraries for SPICE remote desktop servers.
+
+Please report bugs at: spice-devel@lists.freedesktop.org
+
+Project content
+---------------
+
+libspice-client-glib-2.0
+ provides glib objects for spice protocol decoding and surface rendering.
+ * SpiceSession (see spice-session.h).
+ * SpiceChannel (see spice-channel.h).
+ * SpiceAudio (see spice-audio.h).
+ * Various Spice<Type>Channel (see channel-<type>.h).
+
+libspice-client-gtk-3.0
+ provides gtk widget to show spice display and accept user input.
+ * SpiceDisplay (see spice-widget.h)
+
+spicy
+ a gtk test client. The recommended client for end user is
+ virt-viewer (http://git.fedorahosted.org/cgit/virt-viewer.git/)
+
+spicy-screenshot
+ Command line tool, connects to spice server and writes out a
+ screen shot.
+
+spicy-stats
+ Command line tool, connects to spice server and writes out a
+ summary of connection details, amount of bytes transferred...
+
+SpiceClientGlib and SpiceClientGtk GObject-introspection modules.
+
+Build dependencies:
+------------------
+
+. On Fedora use:
+
+dnf builddep spice-gtk
+
+. or install:
+
+gtk3-devel spice-protocol intltool
+openssl-devel pulseaudio-libs-devel pixman-devel
+gobject-introspection-devel libjpeg-turbo-devel zlib-devel
+cyrus-sasl-devel gtk-doc
+
+. The GStreamer backend needs:
+
+gstreamer1-devel gstreamer1-plugins-base-devel gstreamer1-plugins-good gstreamer1-plugins-bad-free
+
+. If you build from git, you'll also need:
+
+libtool automake vala vala-tools perl-Text-CSV
--- /dev/null
+The spice-gtk team would like to thank the following contributors:
+
+Alexander Bokovoy <abokovoy@redhat.com>
+Alexander Larsson <alexl@redhat.com>
+Alexandru Visarion <viorel.visarion@gmail.com>
+Alex Efros <powerman-asdf@yandex.ru>
+Alon Levy <alevy@redhat.com>
+Andrew Hughes <gnu.andrew@redhat.com>
+Arnon Gilboa <agilboa@redhat.com>
+Attila Sukosd <attila.sukosd@gmail.com>
+Benjamin Gilbert <bgilbert@cs.cmu.edu>
+Christophe Fergeau <cfergeau@redhat.com>
+Cody Chan <int64ago@gmail.com>
+Cole Robinson <crobinso@redhat.com>
+Colin Walters <walters@verbum.org>
+Daniel P. Berrange <berrange@redhat.com>
+David Jaša <djasa@redhat.com>
+Dietmar Maurer <dietmar@proxmox.com>
+Dmitry Fleytman <dmitry@daynix.com>
+Dunrong Huang <riegamaths@gmail.com>
+Eduardo Lima (Etrunko) <etrunko@redhat.com>
+Fabiano Fidêncio <fidencio@redhat.com>
+Francois Gouget <fgouget@codeweavers.com>
+Frédéric Péters <fpeters@0d.be>
+Frediano Ziglio <fziglio@redhat.com>
+Gerd Hoffmann <kraxel@redhat.com>
+Hans de Goede <hdegoede@redhat.com>
+Ian Stakenvicius <axs@gentoo.org>
+Ignacio Casal Quinteiro <icq@gnome.org>
+Jani Välimaa <wally@mageia.org>
+Jasper Lievisse Adriaanse <jasper@humppa.nl>
+Javier Celaya <javier.celaya@flexvdi.com>
+Jay.han <ezzzehxx@gmail.com>
+Jeremy White <jwhite@codeweavers.com>
+Jonathon Jongsma <jjongsma@redhat.com>
+Kirill Moizik <kmoizik@redhat.com>
+Lukas Venhoda <lvenhoda@redhat.com>
+Marc-André Lureau <marcandre.lureau@redhat.com>
+Marek Kasik <mkasik@redhat.com>
+Matthias Clasen <mclasen@redhat.com>
+Mattias Grönlund <mattias@gronlund.se>
+Michael Chudobiak <mjc@avtechpulse.com>
+Natanael Copa <ncopa@alpinelinux.org>
+Nicolas Prochazka <prochazka.nicolas@gmail.com>
+Pavel Grunt <pgrunt@redhat.com>
+Ryan Lortie <desrt@desrt.ca>
+Sandy Stutsman <sstutsma@redhat.com>
+Snir Sheriber <ssheribe@redhat.com>
+Søren Sandmann Pedersen <ssp@redhat.com>
+Takao Fujiwara <tfujiwar@redhat.com>
+Tiziano Müller <tiziano.mueller@stepping-stone.ch>
+Uri Lublin <uril@redhat.com>
+Victor Toso <me@victortoso.com>
+Victor Toso <victortoso@redhat.com>
+Visarion-Mingopol Alexandru <viorel.visarion@gmail.com>
+Yonit Halperin <yhalperi@redhat.com>
+Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
--- /dev/null
+* implement migration support with client fd
+
+See list of open upstream bugs:
+
+https://bugs.freedesktop.org/buglist.cgi?product=Spice&component=spice-gtk&resolution=---&list_id=281013
--- /dev/null
+# generated automatically by aclocal 1.15 -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# Copyright (C) 1995-2002 Free Software Foundation, Inc.
+# Copyright (C) 2001-2003,2004 Red Hat, Inc.
+#
+# This file is free software, distributed under the terms of the GNU
+# General Public License. As a special exception to the GNU General
+# Public License, this file may be distributed as part of a program
+# that contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+#
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995, 1996
+#
+# Modified to never use included libintl.
+# Owen Taylor <otaylor@redhat.com>, 12/15/1998
+#
+# Major rework to remove unused code
+# Owen Taylor <otaylor@redhat.com>, 12/11/2002
+#
+# Added better handling of ALL_LINGUAS from GNU gettext version
+# written by Bruno Haible, Owen Taylor <otaylor.redhat.com> 5/30/3002
+#
+# Modified to require ngettext
+# Matthias Clasen <mclasen@redhat.com> 08/06/2004
+#
+# We need this here as well, since someone might use autoconf-2.5x
+# to configure GLib then an older version to configure a package
+# using AM_GLIB_GNU_GETTEXT
+AC_PREREQ(2.53)
+
+dnl
+dnl We go to great lengths to make sure that aclocal won't
+dnl try to pull in the installed version of these macros
+dnl when running aclocal in the glib directory.
+dnl
+m4_copy([AC_DEFUN],[glib_DEFUN])
+m4_copy([AC_REQUIRE],[glib_REQUIRE])
+dnl
+dnl At the end, if we're not within glib, we'll define the public
+dnl definitions in terms of our private definitions.
+dnl
+
+# GLIB_LC_MESSAGES
+#--------------------
+glib_DEFUN([GLIB_LC_MESSAGES],
+ [AC_CHECK_HEADERS([locale.h])
+ if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES, 1,
+ [Define if your <locale.h> file defines LC_MESSAGES.])
+ fi
+ fi])
+
+# GLIB_PATH_PROG_WITH_TEST
+#----------------------------
+dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+glib_DEFUN([GLIB_PATH_PROG_WITH_TEST],
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# GLIB_WITH_NLS
+#-----------------
+glib_DEFUN([GLIB_WITH_NLS],
+ dnl NLS is obligatory
+ [USE_NLS=yes
+ AC_SUBST(USE_NLS)
+
+ gt_cv_have_gettext=no
+
+ CATOBJEXT=NONE
+ XGETTEXT=:
+ INTLLIBS=
+
+ AC_CHECK_HEADER(libintl.h,
+ [gt_cv_func_dgettext_libintl="no"
+ libintl_extra_libs=""
+
+ #
+ # First check in libc
+ #
+ AC_CACHE_CHECK([for ngettext in libc], gt_cv_func_ngettext_libc,
+ [AC_TRY_LINK([
+#include <libintl.h>
+],
+ [return !ngettext ("","", 1)],
+ gt_cv_func_ngettext_libc=yes,
+ gt_cv_func_ngettext_libc=no)
+ ])
+
+ if test "$gt_cv_func_ngettext_libc" = "yes" ; then
+ AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc,
+ [AC_TRY_LINK([
+#include <libintl.h>
+],
+ [return !dgettext ("","")],
+ gt_cv_func_dgettext_libc=yes,
+ gt_cv_func_dgettext_libc=no)
+ ])
+ fi
+
+ if test "$gt_cv_func_ngettext_libc" = "yes" ; then
+ AC_CHECK_FUNCS(bind_textdomain_codeset)
+ fi
+
+ #
+ # If we don't have everything we want, check in libintl
+ #
+ if test "$gt_cv_func_dgettext_libc" != "yes" \
+ || test "$gt_cv_func_ngettext_libc" != "yes" \
+ || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then
+
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CHECK_LIB(intl, ngettext,
+ [AC_CHECK_LIB(intl, dgettext,
+ gt_cv_func_dgettext_libintl=yes)])])
+
+ if test "$gt_cv_func_dgettext_libintl" != "yes" ; then
+ AC_MSG_CHECKING([if -liconv is needed to use gettext])
+ AC_MSG_RESULT([])
+ AC_CHECK_LIB(intl, ngettext,
+ [AC_CHECK_LIB(intl, dcgettext,
+ [gt_cv_func_dgettext_libintl=yes
+ libintl_extra_libs=-liconv],
+ :,-liconv)],
+ :,-liconv)
+ fi
+
+ #
+ # If we found libintl, then check in it for bind_textdomain_codeset();
+ # we'll prefer libc if neither have bind_textdomain_codeset(),
+ # and both have dgettext and ngettext
+ #
+ if test "$gt_cv_func_dgettext_libintl" = "yes" ; then
+ glib_save_LIBS="$LIBS"
+ LIBS="$LIBS -lintl $libintl_extra_libs"
+ unset ac_cv_func_bind_textdomain_codeset
+ AC_CHECK_FUNCS(bind_textdomain_codeset)
+ LIBS="$glib_save_LIBS"
+
+ if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then
+ gt_cv_func_dgettext_libc=no
+ else
+ if test "$gt_cv_func_dgettext_libc" = "yes" \
+ && test "$gt_cv_func_ngettext_libc" = "yes"; then
+ gt_cv_func_dgettext_libintl=no
+ fi
+ fi
+ fi
+ fi
+
+ if test "$gt_cv_func_dgettext_libc" = "yes" \
+ || test "$gt_cv_func_dgettext_libintl" = "yes"; then
+ gt_cv_have_gettext=yes
+ fi
+
+ if test "$gt_cv_func_dgettext_libintl" = "yes"; then
+ INTLLIBS="-lintl $libintl_extra_libs"
+ fi
+
+ if test "$gt_cv_have_gettext" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT,1,
+ [Define if the GNU gettext() function is already present or preinstalled.])
+ GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ glib_save_LIBS="$LIBS"
+ LIBS="$LIBS $INTLLIBS"
+ AC_CHECK_FUNCS(dcgettext)
+ MSGFMT_OPTS=
+ AC_MSG_CHECKING([if msgfmt accepts -c])
+ GLIB_RUN_PROG([$MSGFMT -c -o /dev/null],[
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: test 1.0\n"
+"PO-Revision-Date: 2007-02-15 12:01+0100\n"
+"Last-Translator: test <foo@bar.xx>\n"
+"Language-Team: C <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+], [MSGFMT_OPTS=-c; AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])])
+ AC_SUBST(MSGFMT_OPTS)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [case $host in
+ *-*-solaris*)
+ dnl On Solaris, if bind_textdomain_codeset is in libc,
+ dnl GNU format message catalog is always supported,
+ dnl since both are added to the libc all together.
+ dnl Hence, we'd like to go with DATADIRNAME=share and
+ dnl and CATOBJEXT=.gmo in this case.
+ AC_CHECK_FUNC(bind_textdomain_codeset,
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ ;;
+ *-*-openbsd*)
+ CATOBJEXT=.mo
+ DATADIRNAME=share
+ ;;
+ *)
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+ ;;
+ esac])
+ LIBS="$glib_save_LIBS"
+ INSTOBJEXT=.mo
+ else
+ gt_cv_have_gettext=no
+ fi
+ fi
+ ])
+
+ if test "$gt_cv_have_gettext" = "yes" ; then
+ AC_DEFINE(ENABLE_NLS, 1,
+ [always defined to indicate that i18n is enabled])
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is not GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext program is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+
+ AC_OUTPUT_COMMANDS(
+ [case "$CONFIG_FILES" in *po/Makefile.in*)
+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
+ esac])
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.ac.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(PO_IN_DATADIR_TRUE)
+ AC_SUBST(PO_IN_DATADIR_FALSE)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+# AM_GLIB_GNU_GETTEXT
+# -------------------
+# Do checks necessary for use of gettext. If a suitable implementation
+# of gettext is found in either in libintl or in the C library,
+# it will set INTLLIBS to the libraries needed for use of gettext
+# and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable
+# gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST()
+# on various variables needed by the Makefile.in.in installed by
+# glib-gettextize.
+dnl
+AU_DEFUN([GLIB_GNU_GETTEXT],
+ [AC_REQUIRE([AC_PROG_CC])dnl
+
+ GLIB_LC_MESSAGES
+ GLIB_WITH_NLS
+
+ if test "$gt_cv_have_gettext" = "yes"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ NEW_LINGUAS="$NEW_LINGUAS $presentlang"
+ fi
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
+ dnl find the mkinstalldirs script in another subdir but ($top_srcdir).
+ dnl Try to locate is.
+ MKINSTALLDIRS=
+ if test -n "$ac_aux_dir"; then
+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
+ fi
+ if test -z "$MKINSTALLDIRS"; then
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+ fi
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile.
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ ],
+ [[$0: This macro is deprecated. You should use upstream gettext instead.]])
+
+# AM_GLIB_DEFINE_LOCALEDIR(VARIABLE)
+# -------------------------------
+# Define VARIABLE to the location where catalog files will
+# be installed by po/Makefile.
+glib_DEFUN([GLIB_DEFINE_LOCALEDIR],
+[glib_REQUIRE([GLIB_GNU_GETTEXT])dnl
+glib_save_prefix="$prefix"
+glib_save_exec_prefix="$exec_prefix"
+glib_save_datarootdir="$datarootdir"
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+test "x$exec_prefix" = xNONE && exec_prefix=$prefix
+datarootdir=`eval echo "${datarootdir}"`
+if test "x$CATOBJEXT" = "x.mo" ; then
+ localedir=`eval echo "${libdir}/locale"`
+else
+ localedir=`eval echo "${datadir}/locale"`
+fi
+prefix="$glib_save_prefix"
+exec_prefix="$glib_save_exec_prefix"
+datarootdir="$glib_save_datarootdir"
+AC_DEFINE_UNQUOTED($1, "$localedir",
+ [Define the location where the catalogs will be installed])
+])
+
+dnl
+dnl Now the definitions that aclocal will find
+dnl
+ifdef(glib_configure_ac,[],[
+AC_DEFUN([AM_GLIB_GNU_GETTEXT],[GLIB_GNU_GETTEXT($@)])
+AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)])
+])dnl
+
+# GLIB_RUN_PROG(PROGRAM, TEST-FILE, [ACTION-IF-PASS], [ACTION-IF-FAIL])
+#
+# Create a temporary file with TEST-FILE as its contents and pass the
+# file name to PROGRAM. Perform ACTION-IF-PASS if PROGRAM exits with
+# 0 and perform ACTION-IF-FAIL for any other exit status.
+AC_DEFUN([GLIB_RUN_PROG],
+[cat >conftest.foo <<_ACEOF
+$2
+_ACEOF
+if AC_RUN_LOG([$1 conftest.foo]); then
+ m4_ifval([$3], [$3], [:])
+m4_ifvaln([$4], [else $4])dnl
+echo "$as_me: failed input was:" >&AS_MESSAGE_LOG_FD
+sed 's/^/| /' conftest.foo >&AS_MESSAGE_LOG_FD
+fi])
+
+
+dnl -*- mode: autoconf -*-
+dnl Copyright 2009 Johan Dahlin
+dnl
+dnl This file is free software; the author(s) gives unlimited
+dnl permission to copy and/or distribute it, with or without
+dnl modifications, as long as this notice is preserved.
+dnl
+
+# serial 1
+
+m4_define([_GOBJECT_INTROSPECTION_CHECK_INTERNAL],
+[
+ AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
+ AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
+ AC_BEFORE([LT_INIT],[$0])dnl setup libtool first
+
+ dnl enable/disable introspection
+ m4_if([$2], [require],
+ [dnl
+ enable_introspection=yes
+ ],[dnl
+ AC_ARG_ENABLE(introspection,
+ AS_HELP_STRING([--enable-introspection[=@<:@no/auto/yes@:>@]],
+ [Enable introspection for this build]),,
+ [enable_introspection=auto])
+ ])dnl
+
+ AC_MSG_CHECKING([for gobject-introspection])
+
+ dnl presence/version checking
+ AS_CASE([$enable_introspection],
+ [no], [dnl
+ found_introspection="no (disabled, use --enable-introspection to enable)"
+ ],dnl
+ [yes],[dnl
+ PKG_CHECK_EXISTS([gobject-introspection-1.0],,
+ AC_MSG_ERROR([gobject-introspection-1.0 is not installed]))
+ PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1],
+ found_introspection=yes,
+ AC_MSG_ERROR([You need to have gobject-introspection >= $1 installed to build AC_PACKAGE_NAME]))
+ ],dnl
+ [auto],[dnl
+ PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, found_introspection=no)
+ dnl Canonicalize enable_introspection
+ enable_introspection=$found_introspection
+ ],dnl
+ [dnl
+ AC_MSG_ERROR([invalid argument passed to --enable-introspection, should be one of @<:@no/auto/yes@:>@])
+ ])dnl
+
+ AC_MSG_RESULT([$found_introspection])
+
+ INTROSPECTION_SCANNER=
+ INTROSPECTION_COMPILER=
+ INTROSPECTION_GENERATE=
+ INTROSPECTION_GIRDIR=
+ INTROSPECTION_TYPELIBDIR=
+ if test "x$found_introspection" = "xyes"; then
+ INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0`
+ INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0`
+ INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0`
+ INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0`
+ INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)"
+ INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0`
+ INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0`
+ INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection
+ fi
+ AC_SUBST(INTROSPECTION_SCANNER)
+ AC_SUBST(INTROSPECTION_COMPILER)
+ AC_SUBST(INTROSPECTION_GENERATE)
+ AC_SUBST(INTROSPECTION_GIRDIR)
+ AC_SUBST(INTROSPECTION_TYPELIBDIR)
+ AC_SUBST(INTROSPECTION_CFLAGS)
+ AC_SUBST(INTROSPECTION_LIBS)
+ AC_SUBST(INTROSPECTION_MAKEFILE)
+
+ AM_CONDITIONAL(HAVE_INTROSPECTION, test "x$found_introspection" = "xyes")
+])
+
+
+dnl Usage:
+dnl GOBJECT_INTROSPECTION_CHECK([minimum-g-i-version])
+
+AC_DEFUN([GOBJECT_INTROSPECTION_CHECK],
+[
+ _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1])
+])
+
+dnl Usage:
+dnl GOBJECT_INTROSPECTION_REQUIRE([minimum-g-i-version])
+
+
+AC_DEFUN([GOBJECT_INTROSPECTION_REQUIRE],
+[
+ _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1], [require])
+])
+
+# nls.m4 serial 5 (gettext-0.18)
+dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014, 2016 Free Software
+dnl Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003.
+
+AC_PREREQ([2.50])
+
+AC_DEFUN([AM_NLS],
+[
+ AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE([nls],
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT([$USE_NLS])
+ AC_SUBST([USE_NLS])
+])
+
+dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+dnl serial 11 (pkg-config-0.29)
+dnl
+dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+dnl 02111-1307, USA.
+dnl
+dnl As a special exception to the GNU General Public License, if you
+dnl distribute this file as part of a program that contains a
+dnl configuration script generated by Autoconf, you may include it under
+dnl the same distribution terms that you use for the rest of that
+dnl program.
+
+dnl PKG_PREREQ(MIN-VERSION)
+dnl -----------------------
+dnl Since: 0.29
+dnl
+dnl Verify that the version of the pkg-config macros are at least
+dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
+dnl installed version of pkg-config, this checks the developer's version
+dnl of pkg.m4 when generating configure.
+dnl
+dnl To ensure that this macro is defined, also add:
+dnl m4_ifndef([PKG_PREREQ],
+dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
+dnl
+dnl See the "Since" comment for each macro you use to see what version
+dnl of the macros you require.
+m4_defun([PKG_PREREQ],
+[m4_define([PKG_MACROS_VERSION], [0.29])
+m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
+ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
+])dnl PKG_PREREQ
+
+dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
+dnl ----------------------------------
+dnl Since: 0.16
+dnl
+dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
+dnl first found in the path. Checks that the version of pkg-config found
+dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
+dnl used since that's the first version where most current features of
+dnl pkg-config existed.
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+fi[]dnl
+])dnl PKG_PROG_PKG_CONFIG
+
+dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------------------------------
+dnl Since: 0.18
+dnl
+dnl Check to see whether a particular set of modules exists. Similar to
+dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
+dnl
+dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+dnl only at the first occurence in configure.ac, so if the first place
+dnl it's called might be skipped (such as if it is within an "if", you
+dnl have to call PKG_CHECK_EXISTS manually
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_default([$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+dnl ---------------------------------------------
+dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
+dnl pkg_failed based on the result.
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes ],
+ [pkg_failed=yes])
+ else
+ pkg_failed=untried
+fi[]dnl
+])dnl _PKG_CONFIG
+
+dnl _PKG_SHORT_ERRORS_SUPPORTED
+dnl ---------------------------
+dnl Internal check to see if pkg-config supports short errors.
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])dnl _PKG_SHORT_ERRORS_SUPPORTED
+
+
+dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl --------------------------------------------------------------
+dnl Since: 0.4.0
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
+dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ AC_MSG_RESULT([no])
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+ ])
+elif test $pkg_failed = untried; then
+ AC_MSG_RESULT([no])
+ m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
+ ])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ $3
+fi[]dnl
+])dnl PKG_CHECK_MODULES
+
+
+dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl ---------------------------------------------------------------------
+dnl Since: 0.29
+dnl
+dnl Checks for existence of MODULES and gathers its build flags with
+dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
+dnl and VARIABLE-PREFIX_LIBS from --libs.
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
+dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
+dnl configure.ac.
+AC_DEFUN([PKG_CHECK_MODULES_STATIC],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+_save_PKG_CONFIG=$PKG_CONFIG
+PKG_CONFIG="$PKG_CONFIG --static"
+PKG_CHECK_MODULES($@)
+PKG_CONFIG=$_save_PKG_CONFIG[]dnl
+])dnl PKG_CHECK_MODULES_STATIC
+
+
+dnl PKG_INSTALLDIR([DIRECTORY])
+dnl -------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable pkgconfigdir as the location where a module
+dnl should install pkg-config .pc files. By default the directory is
+dnl $libdir/pkgconfig, but the default can be changed by passing
+dnl DIRECTORY. The user can override through the --with-pkgconfigdir
+dnl parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+ [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_INSTALLDIR
+
+
+dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
+dnl --------------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable noarch_pkgconfigdir as the location where a
+dnl module should install arch-independent pkg-config .pc files. By
+dnl default the directory is $datadir/pkgconfig, but the default can be
+dnl changed by passing DIRECTORY. The user can override through the
+dnl --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+ [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_NOARCH_INSTALLDIR
+
+
+dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------
+dnl Since: 0.28
+dnl
+dnl Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])dnl PKG_CHECK_VAR
+
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.15'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.15], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.15])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_AR([ACT-IF-FAIL])
+# -------------------------
+# Try to determine the archiver interface, and trigger the ar-lib wrapper
+# if it is needed. If the detection of archiver interface fails, run
+# ACT-IF-FAIL (default is to abort configure with a proper error message).
+AC_DEFUN([AM_PROG_AR],
+[AC_BEFORE([$0], [LT_INIT])dnl
+AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([ar-lib])dnl
+AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
+: ${AR=ar}
+
+AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
+ [AC_LANG_PUSH([C])
+ am_cv_ar_interface=ar
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
+ [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([am_ar_try])
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=ar
+ else
+ am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([am_ar_try])
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=lib
+ else
+ am_cv_ar_interface=unknown
+ fi
+ fi
+ rm -f conftest.lib libconftest.a
+ ])
+ AC_LANG_POP([C])])
+
+case $am_cv_ar_interface in
+ar)
+ ;;
+lib)
+ # Microsoft lib, so override with the ar-lib wrapper script.
+ # FIXME: It is wrong to rewrite AR.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__AR in this case,
+ # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+ # similar.
+ AR="$am_aux_dir/ar-lib $AR"
+ ;;
+unknown)
+ m4_default([$1],
+ [AC_MSG_ERROR([could not determine $AR interface])])
+ ;;
+esac
+AC_SUBST([AR])dnl
+])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "$am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each '.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
+])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+ [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+ am_maintainer_other[ make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer])],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+ alias in your environment])
+ fi
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
+ rm -rf conftest.dir
+
+ AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+ AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+# Autoconf support for the Vala compiler
+
+# Copyright (C) 2008-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the Vala compiler exists in $PATH. If it is found, the
+# variable VALAC is set pointing to its absolute path. Otherwise, it is
+# simply set to 'valac'.
+# Optionally a minimum release number of the compiler can be requested.
+# If the ACTION-IF-FOUND parameter is given, it will be run if a proper
+# Vala compiler is found.
+# Similarly, if the ACTION-IF-FOUND is given, it will be run if no proper
+# Vala compiler is found. It defaults to simply print a warning about the
+# situation, but otherwise proceeding with the configuration.
+#
+# AM_PROG_VALAC([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# --------------------------------------------------------------------------
+AC_DEFUN([AM_PROG_VALAC],
+ [AC_PATH_PROG([VALAC], [valac], [valac])
+ AS_IF([test "$VALAC" != valac && test -n "$1"],
+ [AC_MSG_CHECKING([whether $VALAC is at least version $1])
+ am__vala_version=`$VALAC --version | sed 's/Vala *//'`
+ AS_VERSION_COMPARE([$1], ["$am__vala_version"],
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])
+ VALAC=valac])])
+ if test "$VALAC" = valac; then
+ m4_default([$3],
+ [AC_MSG_WARN([no proper vala compiler found])
+ AC_MSG_WARN([you will not be able to compile vala source files])])
+ else
+ m4_default([$2], [:])
+ fi])
+
+m4_include([m4/gtk-doc.m4])
+m4_include([m4/intltool.m4])
+m4_include([m4/ld-version.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
+m4_include([m4/manywarnings.m4])
+m4_include([m4/spice-compile-warnings.m4])
+m4_include([m4/warnings.m4])
--- /dev/null
+#! /bin/sh
+# Wrapper for Microsoft lib.exe
+
+me=ar-lib
+scriptversion=2012-03-01.08; # UTC
+
+# Copyright (C) 2010-2014 Free Software Foundation, Inc.
+# Written by Peter Rosin <peda@lysator.liu.se>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+
+# func_error message
+func_error ()
+{
+ echo "$me: $1" 1>&2
+ exit 1
+}
+
+file_conv=
+
+# func_file_conv build_file
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv in
+ mingw)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_at_file at_file operation archive
+# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
+# for each of them.
+# When interpreting the content of the @FILE, do NOT use func_file_conv,
+# since the user would need to supply preconverted file names to
+# binutils ar, at least for MinGW.
+func_at_file ()
+{
+ operation=$2
+ archive=$3
+ at_file_contents=`cat "$1"`
+ eval set x "$at_file_contents"
+ shift
+
+ for member
+ do
+ $AR -NOLOGO $operation:"$member" "$archive" || exit $?
+ done
+}
+
+case $1 in
+ '')
+ func_error "no command. Try '$0 --help' for more information."
+ ;;
+ -h | --h*)
+ cat <<EOF
+Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
+
+Members may be specified in a file named with @FILE.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "$me, version $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test $# -lt 3; then
+ func_error "you must specify a program, an action and an archive"
+fi
+
+AR=$1
+shift
+while :
+do
+ if test $# -lt 2; then
+ func_error "you must specify a program, an action and an archive"
+ fi
+ case $1 in
+ -lib | -LIB \
+ | -ltcg | -LTCG \
+ | -machine* | -MACHINE* \
+ | -subsystem* | -SUBSYSTEM* \
+ | -verbose | -VERBOSE \
+ | -wx* | -WX* )
+ AR="$AR $1"
+ shift
+ ;;
+ *)
+ action=$1
+ shift
+ break
+ ;;
+ esac
+done
+orig_archive=$1
+shift
+func_file_conv "$orig_archive"
+archive=$file
+
+# strip leading dash in $action
+action=${action#-}
+
+delete=
+extract=
+list=
+quick=
+replace=
+index=
+create=
+
+while test -n "$action"
+do
+ case $action in
+ d*) delete=yes ;;
+ x*) extract=yes ;;
+ t*) list=yes ;;
+ q*) quick=yes ;;
+ r*) replace=yes ;;
+ s*) index=yes ;;
+ S*) ;; # the index is always updated implicitly
+ c*) create=yes ;;
+ u*) ;; # TODO: don't ignore the update modifier
+ v*) ;; # TODO: don't ignore the verbose modifier
+ *)
+ func_error "unknown action specified"
+ ;;
+ esac
+ action=${action#?}
+done
+
+case $delete$extract$list$quick$replace,$index in
+ yes,* | ,yes)
+ ;;
+ yesyes*)
+ func_error "more than one action specified"
+ ;;
+ *)
+ func_error "no action specified"
+ ;;
+esac
+
+if test -n "$delete"; then
+ if test ! -f "$orig_archive"; then
+ func_error "archive not found"
+ fi
+ for member
+ do
+ case $1 in
+ @*)
+ func_at_file "${1#@}" -REMOVE "$archive"
+ ;;
+ *)
+ func_file_conv "$1"
+ $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
+ ;;
+ esac
+ done
+
+elif test -n "$extract"; then
+ if test ! -f "$orig_archive"; then
+ func_error "archive not found"
+ fi
+ if test $# -gt 0; then
+ for member
+ do
+ case $1 in
+ @*)
+ func_at_file "${1#@}" -EXTRACT "$archive"
+ ;;
+ *)
+ func_file_conv "$1"
+ $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
+ ;;
+ esac
+ done
+ else
+ $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
+ do
+ $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
+ done
+ fi
+
+elif test -n "$quick$replace"; then
+ if test ! -f "$orig_archive"; then
+ if test -z "$create"; then
+ echo "$me: creating $orig_archive"
+ fi
+ orig_archive=
+ else
+ orig_archive=$archive
+ fi
+
+ for member
+ do
+ case $1 in
+ @*)
+ func_file_conv "${1#@}"
+ set x "$@" "@$file"
+ ;;
+ *)
+ func_file_conv "$1"
+ set x "$@" "$file"
+ ;;
+ esac
+ shift
+ shift
+ done
+
+ if test -n "$orig_archive"; then
+ $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
+ else
+ $AR -NOLOGO -OUT:"$archive" "$@" || exit $?
+ fi
+
+elif test -n "$list"; then
+ if test ! -f "$orig_archive"; then
+ func_error "archive not found"
+ fi
+ $AR -NOLOGO -LIST "$archive" || exit $?
+fi
--- /dev/null
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" "" $nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv/,$2, in
+ *,$file_conv,*)
+ ;;
+ mingw/*)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin/*)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine/*)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+ func_file_conv "$1"
+ if test -z "$lib_path"; then
+ lib_path=$file
+ else
+ lib_path="$lib_path;$file"
+ fi
+ linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+ lib=$1
+ found=no
+ save_IFS=$IFS
+ IFS=';'
+ for dir in $lib_path $LIB
+ do
+ IFS=$save_IFS
+ if $shared && test -f "$dir/$lib.dll.lib"; then
+ found=yes
+ lib=$dir/$lib.dll.lib
+ break
+ fi
+ if test -f "$dir/$lib.lib"; then
+ found=yes
+ lib=$dir/$lib.lib
+ break
+ fi
+ if test -f "$dir/lib$lib.a"; then
+ found=yes
+ lib=$dir/lib$lib.a
+ break
+ fi
+ done
+ IFS=$save_IFS
+
+ if test "$found" != yes; then
+ lib=$lib.lib
+ fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+ # Assume a capable shell
+ lib_path=
+ shared=:
+ linker_opts=
+ for arg
+ do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ eat=1
+ case $2 in
+ *.o | *.[oO][bB][jJ])
+ func_file_conv "$2"
+ set x "$@" -Fo"$file"
+ shift
+ ;;
+ *)
+ func_file_conv "$2"
+ set x "$@" -Fe"$file"
+ shift
+ ;;
+ esac
+ ;;
+ -I)
+ eat=1
+ func_file_conv "$2" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -I*)
+ func_file_conv "${1#-I}" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -l)
+ eat=1
+ func_cl_dashl "$2"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -l*)
+ func_cl_dashl "${1#-l}"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -L)
+ eat=1
+ func_cl_dashL "$2"
+ ;;
+ -L*)
+ func_cl_dashL "${1#-L}"
+ ;;
+ -static)
+ shared=false
+ ;;
+ -Wl,*)
+ arg=${1#-Wl,}
+ save_ifs="$IFS"; IFS=','
+ for flag in $arg; do
+ IFS="$save_ifs"
+ linker_opts="$linker_opts $flag"
+ done
+ IFS="$save_ifs"
+ ;;
+ -Xlinker)
+ eat=1
+ linker_opts="$linker_opts $2"
+ ;;
+ -*)
+ set x "$@" "$1"
+ shift
+ ;;
+ *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+ func_file_conv "$1"
+ set x "$@" -Tp"$file"
+ shift
+ ;;
+ *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+ func_file_conv "$1" mingw
+ set x "$@" "$file"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+ done
+ if test -n "$linker_opts"; then
+ linker_opts="-link$linker_opts"
+ fi
+ exec "$@" $linker_opts
+ exit 1
+}
+
+eat=
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+ func_cl_wrapper "$@" # Doesn't return...
+ ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ # So we strip '-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no '-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # '.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2015 Free Software Foundation, Inc.
+
+timestamp='2015-01-01'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches to <config-patches@gnu.org>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2015 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2015 Free Software Foundation, Inc.
+
+timestamp='2015-01-01'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2015 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv | ft32 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | riscv32 | riscv64 \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | visium-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2013-05-30.07; # UTC
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by 'PROGRAMS ARGS'.
+ object Object file output by 'PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputting dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'. Note that this directory component will
+# be either empty or ending with a '/' character. This is deliberate.
+set_dir_from ()
+{
+ case $1 in
+ */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+ *) dir=;;
+ esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+ base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+ echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+ # If the compiler actually managed to produce a dependency file,
+ # post-process it.
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependency.h'.
+ # Do two passes, one to just change these to
+ # $object: dependency.h
+ # and one to simply output
+ # dependency.h:
+ # which is needed to avoid the deleted-header problem.
+ { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+ sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+ } > "$depfile"
+ rm -f "$tmpdepfile"
+ else
+ make_dummy_depfile
+ fi
+}
+
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say). Also, it might not be
+## supported by the other compilers which use the 'gcc' depmode.
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The second -e expression handles DOS-style file names with drive
+ # letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+## Some versions of gcc put a space before the ':'. On the theory
+## that the space means something, we add a space to the output as
+## well. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like '#:fec' to the end of the
+ # dependency line.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+ | tr "$nl" ' ' >> "$depfile"
+ echo >> "$depfile"
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+xlc)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts '$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ aix_post_process_depfile
+ ;;
+
+tcc)
+ # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+ # FIXME: That version still under development at the moment of writing.
+ # Make that this statement remains true also for stable, released
+ # versions.
+ # It will wrap lines (doesn't matter whether long or short) with a
+ # trailing '\', as in:
+ #
+ # foo.o : \
+ # foo.c \
+ # foo.h \
+ #
+ # It will put a trailing '\' even on the last line, and will use leading
+ # spaces rather than leading tabs (at least since its commit 0394caf7
+ # "Emit spaces for -MD").
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+ # We have to change lines of the first kind to '$object: \'.
+ sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+ # And for each line of the second kind, we have to emit a 'dep.h:'
+ # dummy dependency, to avoid the deleted-header problem.
+ sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file. A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+ # Portland's C compiler understands '-MD'.
+ # Will always output deps to 'file.d' where file is the root name of the
+ # source file under compilation, even if file resides in a subdirectory.
+ # The object file name does not affect the name of the '.d' file.
+ # pgcc 10.2 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using '\' :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+ set_dir_from "$object"
+ # Use the source, not the object, to determine the base name, since
+ # that's sadly what pgcc will do too.
+ set_base_from "$source"
+ tmpdepfile=$base.d
+
+ # For projects that build the same source file twice into different object
+ # files, the pgcc approach of using the *source* file root name can cause
+ # problems in parallel builds. Use a locking strategy to avoid stomping on
+ # the same $tmpdepfile.
+ lockdir=$base.d-lock
+ trap "
+ echo '$0: caught signal, cleaning up...' >&2
+ rmdir '$lockdir'
+ exit 1
+ " 1 2 13 15
+ numtries=100
+ i=$numtries
+ while test $i -gt 0; do
+ # mkdir is a portable test-and-set.
+ if mkdir "$lockdir" 2>/dev/null; then
+ # This process acquired the lock.
+ "$@" -MD
+ stat=$?
+ # Release the lock.
+ rmdir "$lockdir"
+ break
+ else
+ # If the lock is being held by a different process, wait
+ # until the winning process is done or we timeout.
+ while test -d "$lockdir" && test $i -gt 0; do
+ sleep 1
+ i=`expr $i - 1`
+ done
+ fi
+ i=`expr $i - 1`
+ done
+ trap - 1 2 13 15
+ if test $i -le 0; then
+ echo "$0: failed to acquire lock after $numtries attempts" >&2
+ echo "$0: check lockdir '$lockdir'" >&2
+ exit 1
+ fi
+
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add 'dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in 'foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ set_dir_from "$object"
+ set_base_from "$object"
+
+ if test "$libtool" = yes; then
+ # Libtool generates 2 separate objects for the 2 libraries. These
+ # two compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir$base.o.d # libtool 1.5
+ tmpdepfile2=$dir.libs/$base.o.d # Likewise.
+ tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ # Same post-processing that is required for AIX mode.
+ aix_post_process_depfile
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/'"$tab"'/
+ G
+ p
+}' >> "$depfile"
+ echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for ':'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+ "$@" $dashmflag |
+ sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this sed invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process the last invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed '1,2d' "$tmpdepfile" \
+ | tr ' ' "$nl" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E \
+ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ | sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+#!/bin/sh
+# Print a version string.
+scriptversion=2010-06-14.19; # UTC
+
+# Copyright (C) 2007-2010 Free Software Foundation, Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
+# It may be run two ways:
+# - from a git repository in which the "git describe" command below
+# produces useful output (thus requiring at least one signed tag)
+# - from a non-git-repo directory containing a .tarball-version file, which
+# presumes this script is invoked like "./git-version-gen .tarball-version".
+
+# In order to use intra-version strings in your project, you will need two
+# separate generated version string files:
+#
+# .tarball-version - present only in a distribution tarball, and not in
+# a checked-out repository. Created with contents that were learned at
+# the last time autoconf was run, and used by git-version-gen. Must not
+# be present in either $(srcdir) or $(builddir) for git-version-gen to
+# give accurate answers during normal development with a checked out tree,
+# but must be present in a tarball when there is no version control system.
+# Therefore, it cannot be used in any dependencies. GNUmakefile has
+# hooks to force a reconfigure at distribution time to get the value
+# correct, without penalizing normal development with extra reconfigures.
+#
+# .version - present in a checked-out repository and in a distribution
+# tarball. Usable in dependencies, particularly for files that don't
+# want to depend on config.h but do want to track version changes.
+# Delete this file prior to any autoconf run where you want to rebuild
+# files to pick up a version string change; and leave it stale to
+# minimize rebuild time after unrelated changes to configure sources.
+#
+# It is probably wise to add these two files to .gitignore, so that you
+# don't accidentally commit either generated file.
+#
+# Use the following line in your configure.ac, so that $(VERSION) will
+# automatically be up-to-date each time configure is run (and note that
+# since configure.ac no longer includes a version string, Makefile rules
+# should not depend on configure.ac for version updates).
+#
+# AC_INIT([GNU project],
+# m4_esyscmd([build-aux/git-version-gen .tarball-version]),
+# [bug-project@example])
+#
+# Then use the following lines in your Makefile.am, so that .version
+# will be present for dependencies, and so that .tarball-version will
+# exist in distribution tarballs.
+#
+# BUILT_SOURCES = $(top_srcdir)/.version
+# $(top_srcdir)/.version:
+# echo $(VERSION) > $@-t && mv $@-t $@
+# dist-hook:
+# echo $(VERSION) > $(distdir)/.tarball-version
+
+case $# in
+ 1|2) ;;
+ *) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version" \
+ '[TAG-NORMALIZATION-SED-SCRIPT]'
+ exit 1;;
+esac
+
+tarball_version_file=$1
+tag_sed_script="${2:-s/x/x/}"
+nl='
+'
+
+# Avoid meddling by environment variable of the same name.
+v=
+
+# First see if there is a tarball-only version file.
+# then try "git describe", then default.
+if test -f $tarball_version_file
+then
+ v=`cat $tarball_version_file` || exit 1
+ case $v in
+ *$nl*) v= ;; # reject multi-line output
+ [0-9]*) ;;
+ *) v= ;;
+ esac
+ test -z "$v" \
+ && echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
+fi
+
+if test -n "$v"
+then
+ : # use $v
+elif test -d .git \
+ && v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
+ || git describe --abbrev=4 HEAD 2>/dev/null` \
+ && v=`printf '%s\n' "$v" | sed "$tag_sed_script"` \
+ && case $v in
+ v[0-9]*) ;;
+ *) (exit 1) ;;
+ esac
+then
+ # Is this a new git that lists number of commits since the last
+ # tag or the previous older version that did not?
+ # Newer: v6.10-77-g0f8faeb
+ # Older: v6.10-g0f8faeb
+ case $v in
+ *-*-*) : git describe is okay three part flavor ;;
+ *-*)
+ : git describe is older two part flavor
+ # Recreate the number of commits and rewrite such that the
+ # result is the same as if we were using the newer version
+ # of git describe.
+ vtag=`echo "$v" | sed 's/-.*//'`
+ numcommits=`git rev-list "$vtag"..HEAD | wc -l`
+ v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
+ ;;
+ esac
+
+ # Change the first '-' to a '.', so version-comparing tools work properly.
+ # Remove the "g" in git describe's output string, to save a byte.
+ v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
+else
+ v=UNKNOWN
+fi
+
+v=`echo "$v" |sed 's/^v//'`
+
+# Don't declare a version "dirty" merely because a time stamp has changed.
+git update-index --refresh > /dev/null 2>&1
+
+dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=
+case "$dirty" in
+ '') ;;
+ *) # Append the suffix only if there isn't one already.
+ case $v in
+ *-dirty) ;;
+ *) v="$v-dirty" ;;
+ esac ;;
+esac
+
+# Omit the trailing newline, so that m4_esyscmd can use the result directly.
+echo "$v" | tr -d "$nl"
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2013-12-25.23; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# 'make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+tab=' '
+nl='
+'
+IFS=" $tab$nl"
+
+# Set DOITPROG to "echo" to test this script.
+
+doit=${DOITPROG-}
+doit_exec=${doit:-exec}
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+is_target_a_directory=possibly
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t)
+ is_target_a_directory=always
+ dst_arg=$2
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) is_target_a_directory=never;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+# We allow the use of options -d and -T together, by making -d
+# take the precedence; this is for compatibility with GNU install.
+
+if test -n "$dir_arg"; then
+ if test -n "$dst_arg"; then
+ echo "$0: target directory not allowed when installing a directory." >&2
+ exit 1
+ fi
+fi
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call 'install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ if test $# -gt 1 || test "$is_target_a_directory" = always; then
+ if test ! -d "$dst_arg"; then
+ echo "$0: $dst_arg: Is not a directory." >&2
+ exit 1
+ fi
+ fi
+fi
+
+if test -z "$dir_arg"; then
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names problematic for 'test' and other utilities.
+ case $src in
+ -* | [=\(\)!]) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+ dst=$dst_arg
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test "$is_target_a_directory" = never; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ dstdir=`dirname "$dst"`
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ oIFS=$IFS
+ IFS=/
+ set -f
+ set fnord $dstdir
+ shift
+ set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+ set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ set +f &&
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+#! /bin/sh
+## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
+## by inline-source v2014-01-03.01
+
+# libtool (GNU libtool) 2.4.6
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4.6
+package_revision=2.4.6
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Run './libtool --help' for help with using this script from the
+# command line.
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# After configure completes, it has a better idea of some of the
+# shell tools we need than the defaults used by the functions shared
+# with bootstrap, so set those here where they can still be over-
+# ridden by the user, but otherwise take precedence.
+
+: ${AUTOCONF="autoconf"}
+: ${AUTOMAKE="automake"}
+
+
+## -------------------------- ##
+## Source external libraries. ##
+## -------------------------- ##
+
+# Much of our low-level functionality needs to be sourced from external
+# libraries, which are installed to $pkgauxdir.
+
+# Set a version string for this script.
+scriptversion=2015-01-20.17; # UTC
+
+# General shell script boiler plate, and helper functions.
+# Written by Gary V. Vaughan, 2004
+
+# Copyright (C) 2004-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# As a special exception to the GNU General Public License, if you distribute
+# this file as part of a program or library that is built using GNU Libtool,
+# you may include this file under the same distribution terms that you use
+# for the rest of that program.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Evaluate this file near the top of your script to gain access to
+# the functions and variables defined here:
+#
+# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+#
+# If you need to override any of the default environment variable
+# settings, do that before evaluating this file.
+
+
+## -------------------- ##
+## Shell normalisation. ##
+## -------------------- ##
+
+# Some shells need a little help to be as Bourne compatible as possible.
+# Before doing anything else, make sure all that help has been provided!
+
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
+fi
+
+# NLS nuisances: We save the old values in case they are required later.
+_G_user_locale=
+_G_safe_locale=
+for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test set = \"\${$_G_var+set}\"; then
+ save_$_G_var=\$$_G_var
+ $_G_var=C
+ export $_G_var
+ _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
+ _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
+ fi"
+done
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Make sure IFS has a sensible default
+sp=' '
+nl='
+'
+IFS="$sp $nl"
+
+# There are apparently some retarded systems that use ';' as a PATH separator!
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+
+## ------------------------- ##
+## Locate command utilities. ##
+## ------------------------- ##
+
+
+# func_executable_p FILE
+# ----------------------
+# Check that FILE is an executable regular file.
+func_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+}
+
+
+# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
+# --------------------------------------------
+# Search for either a program that responds to --version with output
+# containing "GNU", or else returned by CHECK_FUNC otherwise, by
+# trying all the directories in PATH with each of the elements of
+# PROGS_LIST.
+#
+# CHECK_FUNC should accept the path to a candidate program, and
+# set $func_check_prog_result if it truncates its output less than
+# $_G_path_prog_max characters.
+func_path_progs ()
+{
+ _G_progs_list=$1
+ _G_check_func=$2
+ _G_PATH=${3-"$PATH"}
+
+ _G_path_prog_max=0
+ _G_path_prog_found=false
+ _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
+ for _G_dir in $_G_PATH; do
+ IFS=$_G_save_IFS
+ test -z "$_G_dir" && _G_dir=.
+ for _G_prog_name in $_G_progs_list; do
+ for _exeext in '' .EXE; do
+ _G_path_prog=$_G_dir/$_G_prog_name$_exeext
+ func_executable_p "$_G_path_prog" || continue
+ case `"$_G_path_prog" --version 2>&1` in
+ *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
+ *) $_G_check_func $_G_path_prog
+ func_path_progs_result=$func_check_prog_result
+ ;;
+ esac
+ $_G_path_prog_found && break 3
+ done
+ done
+ done
+ IFS=$_G_save_IFS
+ test -z "$func_path_progs_result" && {
+ echo "no acceptable sed could be found in \$PATH" >&2
+ exit 1
+ }
+}
+
+
+# We want to be able to use the functions in this file before configure
+# has figured out where the best binaries are kept, which means we have
+# to search for them ourselves - except when the results are already set
+# where we skip the searches.
+
+# Unless the user overrides by setting SED, search the path for either GNU
+# sed, or the sed that truncates its output the least.
+test -z "$SED" && {
+ _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for _G_i in 1 2 3 4 5 6 7; do
+ _G_sed_script=$_G_sed_script$nl$_G_sed_script
+ done
+ echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
+ _G_sed_script=
+
+ func_check_prog_sed ()
+ {
+ _G_path_prog=$1
+
+ _G_count=0
+ printf 0123456789 >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo '' >> conftest.nl
+ "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ _G_count=`expr $_G_count + 1`
+ if test "$_G_count" -gt "$_G_path_prog_max"; then
+ # Best one so far, save it but keep looking for a better one
+ func_check_prog_result=$_G_path_prog
+ _G_path_prog_max=$_G_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test 10 -lt "$_G_count" && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out
+ }
+
+ func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
+ rm -f conftest.sed
+ SED=$func_path_progs_result
+}
+
+
+# Unless the user overrides by setting GREP, search the path for either GNU
+# grep, or the grep that truncates its output the least.
+test -z "$GREP" && {
+ func_check_prog_grep ()
+ {
+ _G_path_prog=$1
+
+ _G_count=0
+ _G_path_prog_max=0
+ printf 0123456789 >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo 'GREP' >> conftest.nl
+ "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ _G_count=`expr $_G_count + 1`
+ if test "$_G_count" -gt "$_G_path_prog_max"; then
+ # Best one so far, save it but keep looking for a better one
+ func_check_prog_result=$_G_path_prog
+ _G_path_prog_max=$_G_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test 10 -lt "$_G_count" && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out
+ }
+
+ func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
+ GREP=$func_path_progs_result
+}
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# All uppercase variable names are used for environment variables. These
+# variables can be overridden by the user before calling a script that
+# uses them if a suitable command of that name is not already available
+# in the command search PATH.
+
+: ${CP="cp -f"}
+: ${ECHO="printf %s\n"}
+: ${EGREP="$GREP -E"}
+: ${FGREP="$GREP -F"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+
+
+## -------------------- ##
+## Useful sed snippets. ##
+## -------------------- ##
+
+sed_dirname='s|/[^/]*$||'
+sed_basename='s|^.*/||'
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+
+# Same as above, but do not quote variable references.
+sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
+
+# Sed substitution that converts a w32 file name or path
+# that contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-'\' parameter expansions in output of sed_double_quote_subst that
+# were '\'-ed in input to the same. If an odd number of '\' preceded a
+# '$' in input to sed_double_quote_subst, that '$' was protected from
+# expansion. Since each input '\' is now two '\'s, look for any number
+# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'.
+_G_bs='\\'
+_G_bs2='\\\\'
+_G_bs4='\\\\\\\\'
+_G_dollar='\$'
+sed_double_backslash="\
+ s/$_G_bs4/&\\
+/g
+ s/^$_G_bs2$_G_dollar/$_G_bs&/
+ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
+ s/\n//g"
+
+
+## ----------------- ##
+## Global variables. ##
+## ----------------- ##
+
+# Except for the global variables explicitly listed below, the following
+# functions in the '^func_' namespace, and the '^require_' namespace
+# variables initialised in the 'Resource management' section, sourcing
+# this file will not pollute your global namespace with anything
+# else. There's no portable way to scope variables in Bourne shell
+# though, so actually running these functions will sometimes place
+# results into a variable named after the function, and often use
+# temporary variables in the '^_G_' namespace. If you are careful to
+# avoid using those namespaces casually in your sourcing script, things
+# should continue to work as you expect. And, of course, you can freely
+# overwrite any of the functions or variables defined here before
+# calling anything to customize them.
+
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+# Allow overriding, eg assuming that you follow the convention of
+# putting '$debug_cmd' at the start of all your functions, you can get
+# bash to show function call trace with:
+#
+# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+debug_cmd=${debug_cmd-":"}
+exit_cmd=:
+
+# By convention, finish your script with:
+#
+# exit $exit_status
+#
+# so that you can set exit_status to non-zero if you want to indicate
+# something went wrong during execution without actually bailing out at
+# the point of failure.
+exit_status=$EXIT_SUCCESS
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath=$0
+
+# The name of this program.
+progname=`$ECHO "$progpath" |$SED "$sed_basename"`
+
+# Make sure we have an absolute progpath for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+ progdir=`cd "$progdir" && pwd`
+ progpath=$progdir/$progname
+ ;;
+ *)
+ _G_IFS=$IFS
+ IFS=${PATH_SEPARATOR-:}
+ for progdir in $PATH; do
+ IFS=$_G_IFS
+ test -x "$progdir/$progname" && break
+ done
+ IFS=$_G_IFS
+ test -n "$progdir" || progdir=`pwd`
+ progpath=$progdir/$progname
+ ;;
+esac
+
+
+## ----------------- ##
+## Standard options. ##
+## ----------------- ##
+
+# The following options affect the operation of the functions defined
+# below, and should be set appropriately depending on run-time para-
+# meters passed on the command line.
+
+opt_dry_run=false
+opt_quiet=false
+opt_verbose=false
+
+# Categories 'all' and 'none' are always available. Append any others
+# you will pass as the first argument to func_warning from your own
+# code.
+warning_categories=
+
+# By default, display warnings according to 'opt_warning_types'. Set
+# 'warning_func' to ':' to elide all warnings, or func_fatal_error to
+# treat the next displayed warning as a fatal error.
+warning_func=func_warn_and_continue
+
+# Set to 'all' to display all warnings, 'none' to suppress all
+# warnings, or a space delimited list of some subset of
+# 'warning_categories' to display only the listed warnings.
+opt_warning_types=all
+
+
+## -------------------- ##
+## Resource management. ##
+## -------------------- ##
+
+# This section contains definitions for functions that each ensure a
+# particular resource (a file, or a non-empty configuration variable for
+# example) is available, and if appropriate to extract default values
+# from pertinent package files. Call them using their associated
+# 'require_*' variable to ensure that they are executed, at most, once.
+#
+# It's entirely deliberate that calling these functions can set
+# variables that don't obey the namespace limitations obeyed by the rest
+# of this file, in order that that they be as useful as possible to
+# callers.
+
+
+# require_term_colors
+# -------------------
+# Allow display of bold text on terminals that support it.
+require_term_colors=func_require_term_colors
+func_require_term_colors ()
+{
+ $debug_cmd
+
+ test -t 1 && {
+ # COLORTERM and USE_ANSI_COLORS environment variables take
+ # precedence, because most terminfo databases neglect to describe
+ # whether color sequences are supported.
+ test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
+
+ if test 1 = "$USE_ANSI_COLORS"; then
+ # Standard ANSI escape sequences
+ tc_reset='\e[0m'
+ tc_bold='\e[1m'; tc_standout='\e[7m'
+ tc_red='\e[31m'; tc_green='\e[32m'
+ tc_blue='\e[34m'; tc_cyan='\e[36m'
+ else
+ # Otherwise trust the terminfo database after all.
+ test -n "`tput sgr0 2>/dev/null`" && {
+ tc_reset=`tput sgr0`
+ test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
+ tc_standout=$tc_bold
+ test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
+ test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
+ test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
+ test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
+ test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
+ }
+ fi
+ }
+
+ require_term_colors=:
+}
+
+
+## ----------------- ##
+## Function library. ##
+## ----------------- ##
+
+# This section contains a variety of useful functions to call in your
+# scripts. Take note of the portable wrappers for features provided by
+# some modern shells, which will fall back to slower equivalents on
+# less featureful shells.
+
+
+# func_append VAR VALUE
+# ---------------------
+# Append VALUE onto the existing contents of VAR.
+
+ # We should try to minimise forks, especially on Windows where they are
+ # unreasonably slow, so skip the feature probes when bash or zsh are
+ # being used:
+ if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
+ : ${_G_HAVE_ARITH_OP="yes"}
+ : ${_G_HAVE_XSI_OPS="yes"}
+ # The += operator was introduced in bash 3.1
+ case $BASH_VERSION in
+ [12].* | 3.0 | 3.0*) ;;
+ *)
+ : ${_G_HAVE_PLUSEQ_OP="yes"}
+ ;;
+ esac
+ fi
+
+ # _G_HAVE_PLUSEQ_OP
+ # Can be empty, in which case the shell is probed, "yes" if += is
+ # useable or anything else if it does not work.
+ test -z "$_G_HAVE_PLUSEQ_OP" \
+ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
+ && _G_HAVE_PLUSEQ_OP=yes
+
+if test yes = "$_G_HAVE_PLUSEQ_OP"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_append ()
+ {
+ $debug_cmd
+
+ eval "$1+=\$2"
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_append ()
+ {
+ $debug_cmd
+
+ eval "$1=\$$1\$2"
+ }
+fi
+
+
+# func_append_quoted VAR VALUE
+# ----------------------------
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+if test yes = "$_G_HAVE_PLUSEQ_OP"; then
+ eval 'func_append_quoted ()
+ {
+ $debug_cmd
+
+ func_quote_for_eval "$2"
+ eval "$1+=\\ \$func_quote_for_eval_result"
+ }'
+else
+ func_append_quoted ()
+ {
+ $debug_cmd
+
+ func_quote_for_eval "$2"
+ eval "$1=\$$1\\ \$func_quote_for_eval_result"
+ }
+fi
+
+
+# func_append_uniq VAR VALUE
+# --------------------------
+# Append unique VALUE onto the existing contents of VAR, assuming
+# entries are delimited by the first character of VALUE. For example:
+#
+# func_append_uniq options " --another-option option-argument"
+#
+# will only append to $options if " --another-option option-argument "
+# is not already present somewhere in $options already (note spaces at
+# each end implied by leading space in second argument).
+func_append_uniq ()
+{
+ $debug_cmd
+
+ eval _G_current_value='`$ECHO $'$1'`'
+ _G_delim=`expr "$2" : '\(.\)'`
+
+ case $_G_delim$_G_current_value$_G_delim in
+ *"$2$_G_delim"*) ;;
+ *) func_append "$@" ;;
+ esac
+}
+
+
+# func_arith TERM...
+# ------------------
+# Set func_arith_result to the result of evaluating TERMs.
+ test -z "$_G_HAVE_ARITH_OP" \
+ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
+ && _G_HAVE_ARITH_OP=yes
+
+if test yes = "$_G_HAVE_ARITH_OP"; then
+ eval 'func_arith ()
+ {
+ $debug_cmd
+
+ func_arith_result=$(( $* ))
+ }'
+else
+ func_arith ()
+ {
+ $debug_cmd
+
+ func_arith_result=`expr "$@"`
+ }
+fi
+
+
+# func_basename FILE
+# ------------------
+# Set func_basename_result to FILE with everything up to and including
+# the last / stripped.
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ # If this shell supports suffix pattern removal, then use it to avoid
+ # forking. Hide the definitions single quotes in case the shell chokes
+ # on unsupported syntax...
+ _b='func_basename_result=${1##*/}'
+ _d='case $1 in
+ */*) func_dirname_result=${1%/*}$2 ;;
+ * ) func_dirname_result=$3 ;;
+ esac'
+
+else
+ # ...otherwise fall back to using sed.
+ _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
+ _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"`
+ if test "X$func_dirname_result" = "X$1"; then
+ func_dirname_result=$3
+ else
+ func_append func_dirname_result "$2"
+ fi'
+fi
+
+eval 'func_basename ()
+{
+ $debug_cmd
+
+ '"$_b"'
+}'
+
+
+# func_dirname FILE APPEND NONDIR_REPLACEMENT
+# -------------------------------------------
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+eval 'func_dirname ()
+{
+ $debug_cmd
+
+ '"$_d"'
+}'
+
+
+# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
+# --------------------------------------------------------
+# Perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# For efficiency, we do not delegate to the functions above but instead
+# duplicate the functionality here.
+eval 'func_dirname_and_basename ()
+{
+ $debug_cmd
+
+ '"$_b"'
+ '"$_d"'
+}'
+
+
+# func_echo ARG...
+# ----------------
+# Echo program name prefixed message.
+func_echo ()
+{
+ $debug_cmd
+
+ _G_message=$*
+
+ func_echo_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_IFS
+ $ECHO "$progname: $_G_line"
+ done
+ IFS=$func_echo_IFS
+}
+
+
+# func_echo_all ARG...
+# --------------------
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+
+# func_echo_infix_1 INFIX ARG...
+# ------------------------------
+# Echo program name, followed by INFIX on the first line, with any
+# additional lines not showing INFIX.
+func_echo_infix_1 ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ _G_infix=$1; shift
+ _G_indent=$_G_infix
+ _G_prefix="$progname: $_G_infix: "
+ _G_message=$*
+
+ # Strip color escape sequences before counting printable length
+ for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
+ do
+ test -n "$_G_tc" && {
+ _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
+ _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
+ }
+ done
+ _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes
+
+ func_echo_infix_1_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_infix_1_IFS
+ $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
+ _G_prefix=$_G_indent
+ done
+ IFS=$func_echo_infix_1_IFS
+}
+
+
+# func_error ARG...
+# -----------------
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2
+}
+
+
+# func_fatal_error ARG...
+# -----------------------
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ $debug_cmd
+
+ func_error "$*"
+ exit $EXIT_FAILURE
+}
+
+
+# func_grep EXPRESSION FILENAME
+# -----------------------------
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $debug_cmd
+
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_len STRING
+# ---------------
+# Set func_len_result to the length of STRING. STRING may not
+# start with a hyphen.
+ test -z "$_G_HAVE_XSI_OPS" \
+ && (eval 'x=a/b/c;
+ test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+ && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_len ()
+ {
+ $debug_cmd
+
+ func_len_result=${#1}
+ }'
+else
+ func_len ()
+ {
+ $debug_cmd
+
+ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+ }
+fi
+
+
+# func_mkdir_p DIRECTORY-PATH
+# ---------------------------
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ $debug_cmd
+
+ _G_directory_path=$1
+ _G_dir_list=
+
+ if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
+
+ # Protect directory names starting with '-'
+ case $_G_directory_path in
+ -*) _G_directory_path=./$_G_directory_path ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$_G_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ _G_dir_list=$_G_directory_path:$_G_dir_list
+
+ # If the last portion added has no slash in it, the list is done
+ case $_G_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+ done
+ _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+
+ func_mkdir_p_IFS=$IFS; IFS=:
+ for _G_dir in $_G_dir_list; do
+ IFS=$func_mkdir_p_IFS
+ # mkdir can fail with a 'File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$_G_dir" 2>/dev/null || :
+ done
+ IFS=$func_mkdir_p_IFS
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$_G_directory_path" || \
+ func_fatal_error "Failed to create '$1'"
+ fi
+}
+
+
+# func_mktempdir [BASENAME]
+# -------------------------
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, BASENAME is the basename for that directory.
+func_mktempdir ()
+{
+ $debug_cmd
+
+ _G_template=${TMPDIR-/tmp}/${1-$progname}
+
+ if test : = "$opt_dry_run"; then
+ # Return a directory name, but don't create it in dry-run mode
+ _G_tmpdir=$_G_template-$$
+ else
+
+ # If mktemp works, use that first and foremost
+ _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$_G_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ _G_tmpdir=$_G_template-${RANDOM-0}$$
+
+ func_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$_G_tmpdir"
+ umask $func_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$_G_tmpdir" || \
+ func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
+ fi
+
+ $ECHO "$_G_tmpdir"
+}
+
+
+# func_normal_abspath PATH
+# ------------------------
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+func_normal_abspath ()
+{
+ $debug_cmd
+
+ # These SED scripts presuppose an absolute path with a trailing slash.
+ _G_pathcar='s|^/\([^/]*\).*$|\1|'
+ _G_pathcdr='s|^/[^/]*||'
+ _G_removedotparts=':dotsl
+ s|/\./|/|g
+ t dotsl
+ s|/\.$|/|'
+ _G_collapseslashes='s|/\{1,\}|/|g'
+ _G_finalslash='s|/*$|/|'
+
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test / = "$func_normal_abspath_tpath"; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result"; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+
+# func_notquiet ARG...
+# --------------------
+# Echo program name prefixed message only when not in quiet mode.
+func_notquiet ()
+{
+ $debug_cmd
+
+ $opt_quiet || func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+
+# func_relative_path SRCDIR DSTDIR
+# --------------------------------
+# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
+func_relative_path ()
+{
+ $debug_cmd
+
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=$func_dirname_result
+ if test -z "$func_relative_path_tlibdir"; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
+
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test -n "$func_stripname_result"; then
+ func_append func_relative_path_result "/$func_stripname_result"
+ fi
+
+ # Normalisation. If bindir is libdir, return '.' else relative path.
+ if test -n "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ fi
+
+ test -n "$func_relative_path_result" || func_relative_path_result=.
+
+ :
+}
+
+
+# func_quote_for_eval ARG...
+# --------------------------
+# Aesthetically quote ARGs to be evaled later.
+# This function returns two values:
+# i) func_quote_for_eval_result
+# double-quoted, suitable for a subsequent eval
+# ii) func_quote_for_eval_unquoted_result
+# has all characters that are still active within double
+# quotes backslashified.
+func_quote_for_eval ()
+{
+ $debug_cmd
+
+ func_quote_for_eval_unquoted_result=
+ func_quote_for_eval_result=
+ while test 0 -lt $#; do
+ case $1 in
+ *[\\\`\"\$]*)
+ _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
+ *)
+ _G_unquoted_arg=$1 ;;
+ esac
+ if test -n "$func_quote_for_eval_unquoted_result"; then
+ func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
+ else
+ func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+ fi
+
+ case $_G_unquoted_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and variable expansion
+ # for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_quoted_arg=\"$_G_unquoted_arg\"
+ ;;
+ *)
+ _G_quoted_arg=$_G_unquoted_arg
+ ;;
+ esac
+
+ if test -n "$func_quote_for_eval_result"; then
+ func_append func_quote_for_eval_result " $_G_quoted_arg"
+ else
+ func_append func_quote_for_eval_result "$_G_quoted_arg"
+ fi
+ shift
+ done
+}
+
+
+# func_quote_for_expand ARG
+# -------------------------
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ $debug_cmd
+
+ case $1 in
+ *[\\\`\"]*)
+ _G_arg=`$ECHO "$1" | $SED \
+ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ _G_arg=$1 ;;
+ esac
+
+ case $_G_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_arg=\"$_G_arg\"
+ ;;
+ esac
+
+ func_quote_for_expand_result=$_G_arg
+}
+
+
+# func_stripname PREFIX SUFFIX NAME
+# ---------------------------------
+# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_stripname ()
+ {
+ $debug_cmd
+
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary variable first.
+ func_stripname_result=$3
+ func_stripname_result=${func_stripname_result#"$1"}
+ func_stripname_result=${func_stripname_result%"$2"}
+ }'
+else
+ func_stripname ()
+ {
+ $debug_cmd
+
+ case $2 in
+ .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
+ *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
+ esac
+ }
+fi
+
+
+# func_show_eval CMD [FAIL_EXP]
+# -----------------------------
+# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ $debug_cmd
+
+ _G_cmd=$1
+ _G_fail_exp=${2-':'}
+
+ func_quote_for_expand "$_G_cmd"
+ eval "func_notquiet $func_quote_for_expand_result"
+
+ $opt_dry_run || {
+ eval "$_G_cmd"
+ _G_status=$?
+ if test 0 -ne "$_G_status"; then
+ eval "(exit $_G_status); $_G_fail_exp"
+ fi
+ }
+}
+
+
+# func_show_eval_locale CMD [FAIL_EXP]
+# ------------------------------------
+# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ $debug_cmd
+
+ _G_cmd=$1
+ _G_fail_exp=${2-':'}
+
+ $opt_quiet || {
+ func_quote_for_expand "$_G_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ $opt_dry_run || {
+ eval "$_G_user_locale
+ $_G_cmd"
+ _G_status=$?
+ eval "$_G_safe_locale"
+ if test 0 -ne "$_G_status"; then
+ eval "(exit $_G_status); $_G_fail_exp"
+ fi
+ }
+}
+
+
+# func_tr_sh
+# ----------
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ $debug_cmd
+
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
+
+# func_verbose ARG...
+# -------------------
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $debug_cmd
+
+ $opt_verbose && func_echo "$*"
+
+ :
+}
+
+
+# func_warn_and_continue ARG...
+# -----------------------------
+# Echo program name prefixed warning message to standard error.
+func_warn_and_continue ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
+}
+
+
+# func_warning CATEGORY ARG...
+# ----------------------------
+# Echo program name prefixed warning message to standard error. Warning
+# messages can be filtered according to CATEGORY, where this function
+# elides messages where CATEGORY is not listed in the global variable
+# 'opt_warning_types'.
+func_warning ()
+{
+ $debug_cmd
+
+ # CATEGORY must be in the warning_categories list!
+ case " $warning_categories " in
+ *" $1 "*) ;;
+ *) func_internal_error "invalid warning category '$1'" ;;
+ esac
+
+ _G_category=$1
+ shift
+
+ case " $opt_warning_types " in
+ *" $_G_category "*) $warning_func ${1+"$@"} ;;
+ esac
+}
+
+
+# func_sort_ver VER1 VER2
+# -----------------------
+# 'sort -V' is not generally available.
+# Note this deviates from the version comparison in automake
+# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
+# but this should suffice as we won't be specifying old
+# version formats or redundant trailing .0 in bootstrap.conf.
+# If we did want full compatibility then we should probably
+# use m4_version_compare from autoconf.
+func_sort_ver ()
+{
+ $debug_cmd
+
+ printf '%s\n%s\n' "$1" "$2" \
+ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
+}
+
+# func_lt_ver PREV CURR
+# ---------------------
+# Return true if PREV and CURR are in the correct order according to
+# func_sort_ver, otherwise false. Use it like this:
+#
+# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
+func_lt_ver ()
+{
+ $debug_cmd
+
+ test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+#! /bin/sh
+
+# Set a version string for this script.
+scriptversion=2014-01-07.03; # UTC
+
+# A portable, pluggable option parser for Bourne shell.
+# Written by Gary V. Vaughan, 2010
+
+# Copyright (C) 2010-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# This file is a library for parsing options in your shell scripts along
+# with assorted other useful supporting features that you can make use
+# of too.
+#
+# For the simplest scripts you might need only:
+#
+# #!/bin/sh
+# . relative/path/to/funclib.sh
+# . relative/path/to/options-parser
+# scriptversion=1.0
+# func_options ${1+"$@"}
+# eval set dummy "$func_options_result"; shift
+# ...rest of your script...
+#
+# In order for the '--version' option to work, you will need to have a
+# suitably formatted comment like the one at the top of this file
+# starting with '# Written by ' and ending with '# warranty; '.
+#
+# For '-h' and '--help' to work, you will also need a one line
+# description of your script's purpose in a comment directly above the
+# '# Written by ' line, like the one at the top of this file.
+#
+# The default options also support '--debug', which will turn on shell
+# execution tracing (see the comment above debug_cmd below for another
+# use), and '--verbose' and the func_verbose function to allow your script
+# to display verbose messages only when your user has specified
+# '--verbose'.
+#
+# After sourcing this file, you can plug processing for additional
+# options by amending the variables from the 'Configuration' section
+# below, and following the instructions in the 'Option parsing'
+# section further down.
+
+## -------------- ##
+## Configuration. ##
+## -------------- ##
+
+# You should override these variables in your script after sourcing this
+# file so that they reflect the customisations you have added to the
+# option parser.
+
+# The usage line for option parsing errors and the start of '-h' and
+# '--help' output messages. You can embed shell variables for delayed
+# expansion at the time the message is displayed, but you will need to
+# quote other shell meta-characters carefully to prevent them being
+# expanded when the contents are evaled.
+usage='$progpath [OPTION]...'
+
+# Short help message in response to '-h' and '--help'. Add to this or
+# override it after sourcing this library to reflect the full set of
+# options your script accepts.
+usage_message="\
+ --debug enable verbose shell tracing
+ -W, --warnings=CATEGORY
+ report the warnings falling in CATEGORY [all]
+ -v, --verbose verbosely report processing
+ --version print version information and exit
+ -h, --help print short or long help message and exit
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+long_help_message="
+Warning categories include:
+ 'all' show all warnings
+ 'none' turn off all the warnings
+ 'error' warnings are treated as fatal errors"
+
+# Help message printed before fatal option parsing errors.
+fatal_help="Try '\$progname --help' for more information."
+
+
+
+## ------------------------- ##
+## Hook function management. ##
+## ------------------------- ##
+
+# This section contains functions for adding, removing, and running hooks
+# to the main code. A hook is just a named list of of function, that can
+# be run in order later on.
+
+# func_hookable FUNC_NAME
+# -----------------------
+# Declare that FUNC_NAME will run hooks added with
+# 'func_add_hook FUNC_NAME ...'.
+func_hookable ()
+{
+ $debug_cmd
+
+ func_append hookable_fns " $1"
+}
+
+
+# func_add_hook FUNC_NAME HOOK_FUNC
+# ---------------------------------
+# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must
+# first have been declared "hookable" by a call to 'func_hookable'.
+func_add_hook ()
+{
+ $debug_cmd
+
+ case " $hookable_fns " in
+ *" $1 "*) ;;
+ *) func_fatal_error "'$1' does not accept hook functions." ;;
+ esac
+
+ eval func_append ${1}_hooks '" $2"'
+}
+
+
+# func_remove_hook FUNC_NAME HOOK_FUNC
+# ------------------------------------
+# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
+func_remove_hook ()
+{
+ $debug_cmd
+
+ eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
+}
+
+
+# func_run_hooks FUNC_NAME [ARG]...
+# ---------------------------------
+# Run all hook functions registered to FUNC_NAME.
+# It is assumed that the list of hook functions contains nothing more
+# than a whitespace-delimited list of legal shell function names, and
+# no effort is wasted trying to catch shell meta-characters or preserve
+# whitespace.
+func_run_hooks ()
+{
+ $debug_cmd
+
+ case " $hookable_fns " in
+ *" $1 "*) ;;
+ *) func_fatal_error "'$1' does not support hook funcions.n" ;;
+ esac
+
+ eval _G_hook_fns=\$$1_hooks; shift
+
+ for _G_hook in $_G_hook_fns; do
+ eval $_G_hook '"$@"'
+
+ # store returned options list back into positional
+ # parameters for next 'cmd' execution.
+ eval _G_hook_result=\$${_G_hook}_result
+ eval set dummy "$_G_hook_result"; shift
+ done
+
+ func_quote_for_eval ${1+"$@"}
+ func_run_hooks_result=$func_quote_for_eval_result
+}
+
+
+
+## --------------- ##
+## Option parsing. ##
+## --------------- ##
+
+# In order to add your own option parsing hooks, you must accept the
+# full positional parameter list in your hook function, remove any
+# options that you action, and then pass back the remaining unprocessed
+# options in '<hooked_function_name>_result', escaped suitably for
+# 'eval'. Like this:
+#
+# my_options_prep ()
+# {
+# $debug_cmd
+#
+# # Extend the existing usage message.
+# usage_message=$usage_message'
+# -s, --silent don'\''t print informational messages
+# '
+#
+# func_quote_for_eval ${1+"$@"}
+# my_options_prep_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_options_prep my_options_prep
+#
+#
+# my_silent_option ()
+# {
+# $debug_cmd
+#
+# # Note that for efficiency, we parse as many options as we can
+# # recognise in a loop before passing the remainder back to the
+# # caller on the first unrecognised argument we encounter.
+# while test $# -gt 0; do
+# opt=$1; shift
+# case $opt in
+# --silent|-s) opt_silent=: ;;
+# # Separate non-argument short options:
+# -s*) func_split_short_opt "$_G_opt"
+# set dummy "$func_split_short_opt_name" \
+# "-$func_split_short_opt_arg" ${1+"$@"}
+# shift
+# ;;
+# *) set dummy "$_G_opt" "$*"; shift; break ;;
+# esac
+# done
+#
+# func_quote_for_eval ${1+"$@"}
+# my_silent_option_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_parse_options my_silent_option
+#
+#
+# my_option_validation ()
+# {
+# $debug_cmd
+#
+# $opt_silent && $opt_verbose && func_fatal_help "\
+# '--silent' and '--verbose' options are mutually exclusive."
+#
+# func_quote_for_eval ${1+"$@"}
+# my_option_validation_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_validate_options my_option_validation
+#
+# You'll alse need to manually amend $usage_message to reflect the extra
+# options you parse. It's preferable to append if you can, so that
+# multiple option parsing hooks can be added safely.
+
+
+# func_options [ARG]...
+# ---------------------
+# All the functions called inside func_options are hookable. See the
+# individual implementations for details.
+func_hookable func_options
+func_options ()
+{
+ $debug_cmd
+
+ func_options_prep ${1+"$@"}
+ eval func_parse_options \
+ ${func_options_prep_result+"$func_options_prep_result"}
+ eval func_validate_options \
+ ${func_parse_options_result+"$func_parse_options_result"}
+
+ eval func_run_hooks func_options \
+ ${func_validate_options_result+"$func_validate_options_result"}
+
+ # save modified positional parameters for caller
+ func_options_result=$func_run_hooks_result
+}
+
+
+# func_options_prep [ARG]...
+# --------------------------
+# All initialisations required before starting the option parse loop.
+# Note that when calling hook functions, we pass through the list of
+# positional parameters. If a hook function modifies that list, and
+# needs to propogate that back to rest of this script, then the complete
+# modified list must be put in 'func_run_hooks_result' before
+# returning.
+func_hookable func_options_prep
+func_options_prep ()
+{
+ $debug_cmd
+
+ # Option defaults:
+ opt_verbose=false
+ opt_warning_types=
+
+ func_run_hooks func_options_prep ${1+"$@"}
+
+ # save modified positional parameters for caller
+ func_options_prep_result=$func_run_hooks_result
+}
+
+
+# func_parse_options [ARG]...
+# ---------------------------
+# The main option parsing loop.
+func_hookable func_parse_options
+func_parse_options ()
+{
+ $debug_cmd
+
+ func_parse_options_result=
+
+ # this just eases exit handling
+ while test $# -gt 0; do
+ # Defer to hook functions for initial option parsing, so they
+ # get priority in the event of reusing an option name.
+ func_run_hooks func_parse_options ${1+"$@"}
+
+ # Adjust func_parse_options positional parameters to match
+ eval set dummy "$func_run_hooks_result"; shift
+
+ # Break out of the loop if we already parsed every option.
+ test $# -gt 0 || break
+
+ _G_opt=$1
+ shift
+ case $_G_opt in
+ --debug|-x) debug_cmd='set -x'
+ func_echo "enabling shell trace mode"
+ $debug_cmd
+ ;;
+
+ --no-warnings|--no-warning|--no-warn)
+ set dummy --warnings none ${1+"$@"}
+ shift
+ ;;
+
+ --warnings|--warning|-W)
+ test $# = 0 && func_missing_arg $_G_opt && break
+ case " $warning_categories $1" in
+ *" $1 "*)
+ # trailing space prevents matching last $1 above
+ func_append_uniq opt_warning_types " $1"
+ ;;
+ *all)
+ opt_warning_types=$warning_categories
+ ;;
+ *none)
+ opt_warning_types=none
+ warning_func=:
+ ;;
+ *error)
+ opt_warning_types=$warning_categories
+ warning_func=func_fatal_error
+ ;;
+ *)
+ func_fatal_error \
+ "unsupported warning category: '$1'"
+ ;;
+ esac
+ shift
+ ;;
+
+ --verbose|-v) opt_verbose=: ;;
+ --version) func_version ;;
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+
+ # Separate optargs to long options (plugins may need this):
+ --*=*) func_split_equals "$_G_opt"
+ set dummy "$func_split_equals_lhs" \
+ "$func_split_equals_rhs" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate optargs to short options:
+ -W*)
+ func_split_short_opt "$_G_opt"
+ set dummy "$func_split_short_opt_name" \
+ "$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-v*|-x*)
+ func_split_short_opt "$_G_opt"
+ set dummy "$func_split_short_opt_name" \
+ "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognised option: '$_G_opt'" ;;
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ func_parse_options_result=$func_quote_for_eval_result
+}
+
+
+# func_validate_options [ARG]...
+# ------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+func_hookable func_validate_options
+func_validate_options ()
+{
+ $debug_cmd
+
+ # Display all warnings if -W was not given.
+ test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
+
+ func_run_hooks func_validate_options ${1+"$@"}
+
+ # Bail if the options were screwed!
+ $exit_cmd $EXIT_FAILURE
+
+ # save modified positional parameters for caller
+ func_validate_options_result=$func_run_hooks_result
+}
+
+
+
+## ----------------- ##
+## Helper functions. ##
+## ----------------- ##
+
+# This section contains the helper functions used by the rest of the
+# hookable option parser framework in ascii-betical order.
+
+
+# func_fatal_help ARG...
+# ----------------------
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ $debug_cmd
+
+ eval \$ECHO \""Usage: $usage"\"
+ eval \$ECHO \""$fatal_help"\"
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+
+# func_help
+# ---------
+# Echo long help message to standard output and exit.
+func_help ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "$long_help_message"
+ exit 0
+}
+
+
+# func_missing_arg ARGNAME
+# ------------------------
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ $debug_cmd
+
+ func_error "Missing argument for '$1'."
+ exit_cmd=exit
+}
+
+
+# func_split_equals STRING
+# ------------------------
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
+# splitting STRING at the '=' sign.
+test -z "$_G_HAVE_XSI_OPS" \
+ && (eval 'x=a/b/c;
+ test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+ && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_split_equals ()
+ {
+ $debug_cmd
+
+ func_split_equals_lhs=${1%%=*}
+ func_split_equals_rhs=${1#*=}
+ test "x$func_split_equals_lhs" = "x$1" \
+ && func_split_equals_rhs=
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_split_equals ()
+ {
+ $debug_cmd
+
+ func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
+ func_split_equals_rhs=
+ test "x$func_split_equals_lhs" = "x$1" \
+ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
+ }
+fi #func_split_equals
+
+
+# func_split_short_opt SHORTOPT
+# -----------------------------
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_split_short_opt ()
+ {
+ $debug_cmd
+
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_split_short_opt ()
+ {
+ $debug_cmd
+
+ func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
+ func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
+ }
+fi #func_split_short_opt
+
+
+# func_usage
+# ----------
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
+ exit 0
+}
+
+
+# func_usage_message
+# ------------------
+# Echo short help message to standard output.
+func_usage_message ()
+{
+ $debug_cmd
+
+ eval \$ECHO \""Usage: $usage"\"
+ echo
+ $SED -n 's|^# ||
+ /^Written by/{
+ x;p;x
+ }
+ h
+ /^Written by/q' < "$progpath"
+ echo
+ eval \$ECHO \""$usage_message"\"
+}
+
+
+# func_version
+# ------------
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $debug_cmd
+
+ printf '%s\n' "$progname $scriptversion"
+ $SED -n '
+ /(C)/!b go
+ :more
+ /\./!{
+ N
+ s|\n# | |
+ b more
+ }
+ :go
+ /^# Written by /,/# warranty; / {
+ s|^# ||
+ s|^# *$||
+ s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+ p
+ }
+ /^# Written by / {
+ s|^# ||
+ p
+ }
+ /^warranty; /q' < "$progpath"
+
+ exit $?
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+
+# Set a version string.
+scriptversion='(GNU libtool) 2.4.6'
+
+
+# func_echo ARG...
+# ----------------
+# Libtool also displays the current mode in messages, so override
+# funclib.sh func_echo with this custom definition.
+func_echo ()
+{
+ $debug_cmd
+
+ _G_message=$*
+
+ func_echo_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_IFS
+ $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
+ done
+ IFS=$func_echo_IFS
+}
+
+
+# func_warning ARG...
+# -------------------
+# Libtool warnings are not categorized, so override funclib.sh
+# func_warning with this simpler definition.
+func_warning ()
+{
+ $debug_cmd
+
+ $warning_func ${1+"$@"}
+}
+
+
+## ---------------- ##
+## Options parsing. ##
+## ---------------- ##
+
+# Hook in the functions to make sure our own options are parsed during
+# the option parsing loop.
+
+usage='$progpath [OPTION]... [MODE-ARG]...'
+
+# Short help message in response to '-h'.
+usage_message="Options:
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+ -n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --mode=MODE use operation mode MODE
+ --no-warnings equivalent to '-Wnone'
+ --preserve-dup-deps don't remove duplicate dependency libraries
+ --quiet, --silent don't print informational messages
+ --tag=TAG use configuration variables from tag TAG
+ -v, --verbose print more informational messages than default
+ --version print version information
+ -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all]
+ -h, --help, --help-all print short, long, or detailed help message
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+func_help ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "$long_help_message
+
+MODE must be one of the following:
+
+ clean remove files from the build directory
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. When passed as first option,
+'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
+Try '$progname --help --mode=MODE' for a more detailed description of MODE.
+
+When reporting a bug, please describe a test case to reproduce it and
+include the following information:
+
+ host-triplet: $host
+ shell: $SHELL
+ compiler: $LTCC
+ compiler flags: $LTCFLAGS
+ linker: $LD (gnu? $with_gnu_ld)
+ version: $progname (GNU libtool) 2.4.6
+ automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
+ autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
+
+Report bugs to <bug-libtool@gnu.org>.
+GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
+ exit 0
+}
+
+
+# func_lo2o OBJECT-NAME
+# ---------------------
+# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
+# object suffix.
+
+lo2o=s/\\.lo\$/.$objext/
+o2lo=s/\\.$objext\$/.lo/
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_lo2o ()
+ {
+ case $1 in
+ *.lo) func_lo2o_result=${1%.lo}.$objext ;;
+ * ) func_lo2o_result=$1 ;;
+ esac
+ }'
+
+ # func_xform LIBOBJ-OR-SOURCE
+ # ---------------------------
+ # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
+ # suffix to a '.lo' libtool-object suffix.
+ eval 'func_xform ()
+ {
+ func_xform_result=${1%.*}.lo
+ }'
+else
+ # ...otherwise fall back to using sed.
+ func_lo2o ()
+ {
+ func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
+ }
+
+ func_xform ()
+ {
+ func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
+ }
+fi
+
+
+# func_fatal_configuration ARG...
+# -------------------------------
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func__fatal_error ${1+"$@"} \
+ "See the $PACKAGE documentation for more information." \
+ "Fatal configuration error."
+}
+
+
+# func_config
+# -----------
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+
+# func_features
+# -------------
+# Display the features supported by this script.
+func_features ()
+{
+ echo "host: $host"
+ if test yes = "$build_libtool_libs"; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test yes = "$build_old_libs"; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+
+ exit $?
+}
+
+
+# func_enable_tag TAGNAME
+# -----------------------
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname=$1
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf=/$re_begincf/,/$re_endcf/p
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+
+# func_check_version_match
+# ------------------------
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# libtool_options_prep [ARG]...
+# -----------------------------
+# Preparation for options parsed by libtool.
+libtool_options_prep ()
+{
+ $debug_mode
+
+ # Option defaults:
+ opt_config=false
+ opt_dlopen=
+ opt_dry_run=false
+ opt_help=false
+ opt_mode=
+ opt_preserve_dup_deps=false
+ opt_quiet=false
+
+ nonopt=
+ preserve_args=
+
+ # Shorthand for --mode=foo, only valid as the first argument
+ case $1 in
+ clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+ compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+ execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+ finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+ link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+ uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+ esac
+
+ # Pass back the list of options.
+ func_quote_for_eval ${1+"$@"}
+ libtool_options_prep_result=$func_quote_for_eval_result
+}
+func_add_hook func_options_prep libtool_options_prep
+
+
+# libtool_parse_options [ARG]...
+# ---------------------------------
+# Provide handling for libtool specific options.
+libtool_parse_options ()
+{
+ $debug_cmd
+
+ # Perform our own loop to consume as many options as possible in
+ # each iteration.
+ while test $# -gt 0; do
+ _G_opt=$1
+ shift
+ case $_G_opt in
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+
+ --config) func_config ;;
+
+ --dlopen|-dlopen)
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$1"
+ shift
+ ;;
+
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=: ;;
+
+ --features) func_features ;;
+
+ --finish) set dummy --mode finish ${1+"$@"}; shift ;;
+
+ --help) opt_help=: ;;
+
+ --help-all) opt_help=': help-all' ;;
+
+ --mode) test $# = 0 && func_missing_arg $_G_opt && break
+ opt_mode=$1
+ case $1 in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $_G_opt"
+ exit_cmd=exit
+ break
+ ;;
+ esac
+ shift
+ ;;
+
+ --no-silent|--no-quiet)
+ opt_quiet=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --no-warnings|--no-warning|--no-warn)
+ opt_warning=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --no-verbose)
+ opt_verbose=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --silent|--quiet)
+ opt_quiet=:
+ opt_verbose=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --tag) test $# = 0 && func_missing_arg $_G_opt && break
+ opt_tag=$1
+ func_append preserve_args " $_G_opt $1"
+ func_enable_tag "$1"
+ shift
+ ;;
+
+ --verbose|-v) opt_quiet=false
+ opt_verbose=:
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ # An option not handled by this hook function:
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ libtool_parse_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_parse_options libtool_parse_options
+
+
+
+# libtool_validate_options [ARG]...
+# ---------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+libtool_validate_options ()
+{
+ # save first non-option argument
+ if test 0 -lt $#; then
+ nonopt=$1
+ shift
+ fi
+
+ # preserve --debug
+ test : = "$debug_cmd" || func_append preserve_args " --debug"
+
+ case $host in
+ # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
+ # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
+ *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ test yes != "$build_libtool_libs" \
+ && test yes != "$build_old_libs" \
+ && func_fatal_configuration "not configured to build any kind of library"
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
+ func_error "unrecognized option '-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help=$help
+ help="Try '$progname --help --mode=$opt_mode' for more information."
+ }
+
+ # Pass back the unparsed argument list
+ func_quote_for_eval ${1+"$@"}
+ libtool_validate_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_validate_options libtool_validate_options
+
+
+# Process options as early as possible so that --help and --version
+# can return quickly.
+func_options ${1+"$@"}
+eval set dummy "$func_options_result"; shift
+
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+magic='%%%MAGIC variable%%%'
+magic_exe='%%%MAGIC EXE variable%%%'
+
+# Global variables.
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# func_generated_by_libtool
+# True iff stdin has been generated by Libtool. This function is only
+# a basic sanity check; it will hardly flush out determined imposters.
+func_generated_by_libtool_p ()
+{
+ $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if 'file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case $lalib_p_line in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test yes = "$lalib_p"
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ test -f "$1" &&
+ $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $debug_cmd
+
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$sp$nl
+ eval cmd=\"$cmd\"
+ IFS=$save_ifs
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# 'FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $debug_cmd
+
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case $lt_sysroot:$1 in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result='='$func_stripname_result
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $debug_cmd
+
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case "$@ " in
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with '--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=$1
+ if test yes = "$build_libtool_libs"; then
+ write_lobj=\'$2\'
+ else
+ write_lobj=none
+ fi
+
+ if test yes = "$build_old_libs"; then
+ write_oldobj=\'$3\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "$write_libobj"
+ }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $debug_cmd
+
+ func_convert_core_file_wine_to_w32_result=$1
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $debug_cmd
+
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result"; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $debug_cmd
+
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $debug_cmd
+
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $debug_cmd
+
+ if test -z "$2" && test -n "$1"; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result=$1
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $debug_cmd
+
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " '$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result=$3
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $debug_cmd
+
+ case $4 in
+ $1 ) func_to_host_path_result=$3$func_to_host_path_result
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via '$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $debug_cmd
+
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $debug_cmd
+
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result=$1
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result=$func_convert_core_msys_to_w32_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result=$func_cygpath_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result=$func_cygpath_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via '$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $debug_cmd
+
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd=func_convert_path_$func_stripname_result
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $debug_cmd
+
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result=$1
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result=$func_convert_core_msys_to_w32_result
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result=$func_cygpath_result
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result=$func_cygpath_result
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_dll_def_p FILE
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with _LT_DLL_DEF_P in libtool.m4
+func_dll_def_p ()
+{
+ $debug_cmd
+
+ func_dll_def_p_tmp=`$SED -n \
+ -e 's/^[ ]*//' \
+ -e '/^\(;.*\)*$/d' \
+ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \
+ -e q \
+ "$1"`
+ test DEF = "$func_dll_def_p_tmp"
+}
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $debug_cmd
+
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile=$nonopt # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg=$arg
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj=$arg
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify '-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ func_append pie_flag " $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ func_append later " $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs=$IFS; IFS=,
+ for arg in $args; do
+ IFS=$save_ifs
+ func_append_quoted lastarg "$arg"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ func_append base_compile " $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg=$srcfile
+ srcfile=$arg
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_append_quoted base_compile "$lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with '-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj=$func_basename_result
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from '$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test yes = "$build_libtool_libs" \
+ || func_fatal_configuration "cannot build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name '$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname=$func_basename_result
+ xdir=$func_dirname_result
+ lobj=$xdir$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test yes = "$build_old_libs"; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test no = "$compiler_c_o"; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
+ lockfile=$output_obj.lock
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test yes = "$need_locks"; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test warn = "$need_locks"; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ func_append removelist " $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ func_append removelist " $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test yes = "$build_libtool_libs"; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test no != "$pic_mode"; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ func_append command " -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test warn = "$need_locks" &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test yes = "$suppress_opt"; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test yes = "$build_old_libs"; then
+ if test yes != "$pic_mode"; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test yes = "$compiler_c_o"; then
+ func_append command " -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ func_append command "$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test warn = "$need_locks" &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test no != "$need_locks"; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+ test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $opt_mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
+ -shared do not build a '.o' file suitable for static linking
+ -static only build a '.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix '.c' with the
+library object suffix, '.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to '-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the '--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the 'install' or 'cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
+ -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE use a list of object files found in FILE to specify objects
+ -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes)
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with '-') are ignored.
+
+Every other argument is treated as a filename. Files ending in '.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in '.la', then a libtool library is created,
+only library objects ('.lo' files) may be specified, and '-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
+using 'ar' and 'ranlib', or on Windows using 'lib'.
+
+If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode '$opt_mode'"
+ ;;
+ esac
+
+ echo
+ $ECHO "Try '$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test : = "$opt_help"; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | $SED -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ $SED '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $debug_cmd
+
+ # The first argument is the command name.
+ cmd=$nonopt
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $opt_dlopen; do
+ test -f "$file" \
+ || func_fatal_help "'$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "'$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "'$file' was not linked with '-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+
+ if test -f "$dir/$objdir/$dlname"; then
+ func_append dir "/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+ ;;
+
+ *)
+ func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir=$absdir
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic=$magic
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -* | *.la | *.lo ) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file=$progdir/$program
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file=$progdir/$program
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_append_quoted args "$file"
+ done
+
+ if $opt_dry_run; then
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ else
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd=\$cmd$args
+ fi
+}
+
+test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $debug_cmd
+
+ libs=
+ libdirs=
+ admincmds=
+
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "'$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument '$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_quiet && exit $EXIT_SUCCESS
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the '$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the '$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the '$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+ fi
+ echo
+
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
+ exit $EXIT_SUCCESS
+}
+
+test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $debug_cmd
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+ # Allow the use of GNU shtool's install command.
+ case $nonopt in *shtool*) :;; *) false;; esac
+ then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=false
+ stripme=
+ no_mode=:
+ for arg
+ do
+ arg2=
+ if test -n "$dest"; then
+ func_append files " $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=: ;;
+ -f)
+ if $install_cp; then :; else
+ prev=$arg
+ fi
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ if test X-m = "X$prev" && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the '$prev' option requires an argument"
+
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=:
+ if $isdir; then
+ destdir=$dest
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir=$func_dirname_result
+ destname=$func_basename_result
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "'$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "'$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic=$magic
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ func_append staticlibs " $file"
+ ;;
+
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "'$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append current_libdirs " $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append future_libdirs " $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir=$func_dirname_result
+ func_append dir "$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking '$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname=$1
+ shift
+
+ srcname=$realname
+ test -n "$relink_command" && srcname=${realname}T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme=$stripme
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=
+ ;;
+ esac
+ ;;
+ os2*)
+ case $realname in
+ *_dll.a)
+ tstripme=
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try 'ln -sf' first, because the 'ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib=$destdir/$realname
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name=$func_basename_result
+ instname=$dir/${name}i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile=$destdir/$destname
+ else
+ func_basename "$file"
+ destfile=$func_basename_result
+ destfile=$destdir/$destfile
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest=$destfile
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to '$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test yes = "$build_old_libs"; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile=$destdir/$destname
+ else
+ func_basename "$file"
+ destfile=$func_basename_result
+ destfile=$destdir/$destfile
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=.exe
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script '$wrapper'"
+
+ finalize=:
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "'$lib' has not been installed in '$libdir'"
+ finalize=false
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test no = "$fast_install" && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if $finalize; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file=$func_basename_result
+ outputname=$tmpdir/$file
+ # Replace the output file specification.
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_quiet || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink '$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file=$outputname
+ else
+ func_warning "cannot relink '$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name=$func_basename_result
+
+ # Set up the ranlib parameters.
+ oldlib=$destdir/$name
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run '$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test install = "$opt_mode" && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $debug_cmd
+
+ my_outputname=$1
+ my_originator=$2
+ my_pic_p=${3-false}
+ my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms=${my_outputname}S.c
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist=$output_objdir/$my_outputname.nm
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test yes = "$dlself"; then
+ func_verbose "generating symbol list for '$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols=$output_objdir/$outputname.exp
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from '$dlprefile'"
+ func_basename "$dlprefile"
+ name=$func_basename_result
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname"; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename=$func_basename_result
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename"; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ func_show_eval '$RM "${nlist}I"'
+ if test -n "$global_symbol_to_import"; then
+ eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
+ fi
+
+ echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];\
+"
+
+ if test -s "$nlist"I; then
+ echo >> "$output_objdir/$my_dlsyms" "\
+static void lt_syminit(void)
+{
+ LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
+ for (; symbol->name; ++symbol)
+ {"
+ $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
+ echo >> "$output_objdir/$my_dlsyms" "\
+ }
+}"
+ fi
+ echo >> "$output_objdir/$my_dlsyms" "\
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{ {\"$my_originator\", (void *) 0},"
+
+ if test -s "$nlist"I; then
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {\"@INIT@\", (void *) <_syminit},"
+ fi
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) func_append symtab_cflags " $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj=$output_objdir/${my_outputname}S.$objext
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for '$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $debug_cmd
+
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $debug_cmd
+
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+ $debug_cmd
+
+ win32_libid_type=unknown
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ case $nm_interface in
+ "MS dumpbin")
+ if func_cygming_ms_implib_p "$1" ||
+ func_cygming_gnu_implib_p "$1"
+ then
+ win32_nmres=import
+ else
+ win32_nmres=
+ fi
+ ;;
+ *)
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s|.*|import|
+ p
+ q
+ }
+ }'`
+ ;;
+ esac
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $debug_cmd
+
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $debug_cmd
+
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive that possess that section. Heuristic: eliminate
+ # all those that have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $debug_cmd
+
+ if func_cygming_gnu_implib_p "$1"; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1"; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $debug_cmd
+
+ f_ex_an_ar_dir=$1; shift
+ f_ex_an_ar_oldlib=$1
+ if test yes = "$lock_old_archive_extraction"; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test yes = "$lock_old_archive_extraction"; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $debug_cmd
+
+ my_gentop=$1; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=
+ my_xlib=
+ my_xabs=
+ my_xdir=
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib=$func_basename_result
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir=$my_gentop/$my_xlib_u
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ func_basename "$darwin_archive"
+ darwin_base_archive=$func_basename_result
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches; do
+ func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
+ $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
+ cd "unfat-$$/$darwin_base_archive-$darwin_arch"
+ func_extract_an_archive "`pwd`" "$darwin_base_archive"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+ done
+
+ func_extract_archives_result=$my_oldobjs
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory where it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=${1-no}
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ that is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options that match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test yes = "$fast_install"; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ \$ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ # Export our shlibpath_var if we have one.
+ if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+ func_exec_program \${1+\"\$@\"}
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+*/
+EOF
+ cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* declarations of non-ANSI functions */
+#if defined __MINGW32__
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined __CYGWIN__
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined other_platform || defined ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined _MSC_VER
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+#elif defined __MINGW32__
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined __CYGWIN__
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined other platforms ... */
+#endif
+
+#if defined PATH_MAX
+# define LT_PATHMAX PATH_MAX
+#elif defined MAXPATHLEN
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
+ defined __OS2__
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free (stale); stale = 0; } \
+} while (0)
+
+#if defined LT_DEBUGWRAPPER
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+ cat <<EOF
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
+# define externally_visible volatile
+#else
+# define externally_visible __attribute__((externally_visible)) volatile
+#endif
+externally_visible const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test yes = "$fast_install"; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ int rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ newargz = XMALLOC (char *, (size_t) argc + 1);
+
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (STREQ (argv[i], dumpscript_opt))
+ {
+EOF
+ case $host in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ lt_dump_script (stdout);
+ return 0;
+ }
+ if (STREQ (argv[i], debug_opt))
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (STREQ (argv[i], ltwrapper_option_prefix))
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+EOF
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
+EOF
+ cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
+ {
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ newargz = prepare_spawn (newargz);
+ rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ size_t tmp_len;
+ char *concat_name;
+
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = (size_t) (q - p);
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (STREQ (str, pat))
+ *str = '\0';
+ }
+ return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+ va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ size_t len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ size_t orig_value_len = strlen (orig_value);
+ size_t add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ size_t len = strlen (new_value);
+ while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[--len] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $debug_cmd
+
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
+# func_suncc_cstd_abi
+# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
+# Several compiler flags select an ABI that is incompatible with the
+# Cstd library. Avoid specifying it if any are in CXXFLAGS.
+func_suncc_cstd_abi ()
+{
+ $debug_cmd
+
+ case " $compile_command " in
+ *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
+ suncc_use_cstd_abi=no
+ ;;
+ *)
+ suncc_use_cstd_abi=yes
+ ;;
+ esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $debug_cmd
+
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # what system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll that has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ bindir=
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ os2dllname=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=false
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module=$wl-single_module
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test yes != "$build_libtool_libs" \
+ && func_fatal_configuration "cannot build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg=$1
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ bindir)
+ bindir=$arg
+ prev=
+ continue
+ ;;
+ dlfiles|dlprefiles)
+ $preload || {
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=:
+ }
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test no = "$dlself"; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test dlprefiles = "$prev"; then
+ dlself=yes
+ elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test dlfiles = "$prev"; then
+ func_append dlfiles " $arg"
+ else
+ func_append dlprefiles " $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols=$arg
+ test -f "$arg" \
+ || func_fatal_error "symbol file '$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex=$arg
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir=$arg
+ prev=
+ continue
+ ;;
+ mllvm)
+ # Clang does not use LLVM to link, so we can simply discard any
+ # '-mllvm $arg' options when doing the link step.
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# func_append moreargs " $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test none = "$pic_object" &&
+ test none = "$non_pic_object"; then
+ func_fatal_error "cannot find name of object for '$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ if test none != "$pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ pic_object=$xdir$pic_object
+
+ if test dlfiles = "$prev"; then
+ if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test dlprefiles = "$prev"; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg=$pic_object
+ fi
+
+ # Non-PIC object.
+ if test none != "$non_pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object=$xdir$non_pic_object
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test none = "$pic_object"; then
+ arg=$non_pic_object
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object=$pic_object
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "'$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file '$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ os2dllname)
+ os2dllname=$arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex=$arg
+ prev=
+ continue
+ ;;
+ release)
+ release=-$arg
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test rpath = "$prev"; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) func_append rpath " $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) func_append xrpath " $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds=$arg
+ prev=
+ continue
+ ;;
+ weak)
+ func_append weak_libs " $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg=$arg
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "'-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test X-export-symbols = "X$arg"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between '-L' and '$1'"
+ else
+ func_fatal_error "need path for '-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of '$dir'"
+ dir=$absdir
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
+ *)
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ # Do not include libc due to us having libc/libc_r.
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ func_append deplibs " System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test X-lc = "X$arg" && continue
+ ;;
+ esac
+ elif test X-lc_r = "X$arg"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ func_append deplibs " $arg"
+ continue
+ ;;
+
+ -mllvm)
+ prev=mllvm
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module=$wl-multi_module
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "'-no-install' is ignored for $host"
+ func_warning "assuming '-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -os2dllname)
+ prev=os2dllname
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs=$IFS; IFS=,
+ for flag in $args; do
+ IFS=$save_ifs
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs=$IFS; IFS=,
+ for flag in $args; do
+ IFS=$save_ifs
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # -fstack-protector* stack protector flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ # -stdlib=* select c++ std lib with clang
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ func_append compiler_flags " $arg"
+ continue
+ ;;
+
+ -Z*)
+ if test os2 = "`expr $host : '.*\(os2\)'`"; then
+ # OS/2 uses -Zxxx to specify OS/2-specific options
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case $arg in
+ -Zlinker | -Zstack)
+ prev=xcompiler
+ ;;
+ esac
+ continue
+ else
+ # Otherwise treat like 'Some other compiler flag' below
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ fi
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+
+ *.$objext)
+ # A standard object.
+ func_append objs " $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test none = "$pic_object" &&
+ test none = "$non_pic_object"; then
+ func_fatal_error "cannot find name of object for '$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ test none = "$pic_object" || {
+ # Prepend the subdirectory the object is found in.
+ pic_object=$xdir$pic_object
+
+ if test dlfiles = "$prev"; then
+ if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test dlprefiles = "$prev"; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg=$pic_object
+ }
+
+ # Non-PIC object.
+ if test none != "$non_pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object=$xdir$non_pic_object
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test none = "$pic_object"; then
+ arg=$non_pic_object
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object=$pic_object
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "'$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ func_resolve_sysroot "$arg"
+ if test dlfiles = "$prev"; then
+ # This library was specified with -dlopen.
+ func_append dlfiles " $func_resolve_sysroot_result"
+ prev=
+ elif test dlprefiles = "$prev"; then
+ # The library was specified with -dlpreopen.
+ func_append dlprefiles " $func_resolve_sysroot_result"
+ prev=
+ else
+ func_append deplibs " $func_resolve_sysroot_result"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the '$prevarg' option requires an argument"
+
+ if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname=$func_basename_result
+ libobjs_save=$libobjs
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ # Definition is injected by LT_CONFIG during libtool generation.
+ func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"
+
+ func_dirname "$output" "/" ""
+ output_objdir=$func_dirname_result$objdir
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_preserve_dup_deps; then
+ case "$libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append libs " $deplib"
+ done
+
+ if test lib = "$linkmode"; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ esac
+ func_append pre_post_deps " $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=false
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test lib,link = "$linkmode,$pass"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs=$tmp_deplibs
+ fi
+
+ if test lib,link = "$linkmode,$pass" ||
+ test prog,scan = "$linkmode,$pass"; then
+ libs=$deplibs
+ deplibs=
+ fi
+ if test prog = "$linkmode"; then
+ case $pass in
+ dlopen) libs=$dlfiles ;;
+ dlpreopen) libs=$dlprefiles ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ esac
+ fi
+ if test lib,dlpreopen = "$linkmode,$pass"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ func_resolve_sysroot "$lib"
+ case $lib in
+ *.la) func_source "$func_resolve_sysroot_result" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) func_append deplibs " $deplib" ;;
+ esac
+ done
+ done
+ libs=$dlprefiles
+ fi
+ if test dlopen = "$pass"; then
+ # Collect dlpreopened libraries
+ save_deplibs=$deplibs
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=false
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append compiler_flags " $deplib"
+ if test lib = "$linkmode"; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test lib != "$linkmode" && test prog != "$linkmode"; then
+ func_warning "'-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test lib = "$linkmode"; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib=$searchdir/lib$name$search_ext
+ if test -f "$lib"; then
+ if test .la = "$search_ext"; then
+ found=:
+ else
+ found=false
+ fi
+ break 2
+ fi
+ done
+ done
+ if $found; then
+ # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll=$l
+ done
+ if test "X$ll" = "X$old_library"; then # only static version available
+ found=false
+ func_dirname "$lib" "" "."
+ ladir=$func_dirname_result
+ lib=$ladir/$old_library
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ else
+ # deplib doesn't seem to be a libtool library
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ ;; # -l
+ *.ltframework)
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test lib = "$linkmode"; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test conv = "$pass" && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ prog)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test scan = "$pass"; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ *)
+ func_warning "'-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test link = "$pass"; then
+ func_stripname '-R' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
+ *.$libext)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=false
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=:
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=:
+ ;;
+ esac
+ if $valid_a_lib; then
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ else
+ echo
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test link != "$pass"; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ elif test prog = "$linkmode"; then
+ if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ func_append newdlprefiles " $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append newdlfiles " $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=:
+ continue
+ ;;
+ esac # case $deplib
+
+ $found || test -f "$lib" \
+ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "'$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir=$func_dirname_result
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test lib,link = "$linkmode,$pass" ||
+ test prog,scan = "$linkmode,$pass" ||
+ { test prog != "$linkmode" && test lib != "$linkmode"; }; then
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ fi
+
+ if test conv = "$pass"; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for '$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ elif test prog != "$linkmode" && test lib != "$linkmode"; then
+ func_fatal_error "'$lib' is not a convenience library"
+ fi
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ if test -n "$old_library" &&
+ { test yes = "$prefer_static_libs" ||
+ test built,no = "$prefer_static_libs,$installed"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib=$l
+ done
+ fi
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for '$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test dlopen = "$pass"; then
+ test -z "$libdir" \
+ && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
+ if test -z "$dlname" ||
+ test yes != "$dlopen_support" ||
+ test no = "$build_libtool_libs"
+ then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ func_append dlprefiles " $lib $dependency_libs"
+ else
+ func_append newdlfiles " $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of '$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir=$ladir
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname=$func_basename_result
+
+ # Find the relevant object directory and library name.
+ if test yes = "$installed"; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library '$lib' was moved."
+ dir=$ladir
+ absdir=$abs_ladir
+ libdir=$abs_ladir
+ else
+ dir=$lt_sysroot$libdir
+ absdir=$lt_sysroot$libdir
+ fi
+ test yes = "$hardcode_automatic" && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir=$ladir
+ absdir=$abs_ladir
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ else
+ dir=$ladir/$objdir
+ absdir=$abs_ladir/$objdir
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test dlpreopen = "$pass"; then
+ if test -z "$libdir" && test prog = "$linkmode"; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
+ fi
+ case $host in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test lib = "$linkmode"; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test prog = "$linkmode" && test link != "$pass"; then
+ func_append newlib_search_path " $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=false
+ if test no != "$link_all_deplibs" || test -z "$library_names" ||
+ test no = "$build_libtool_libs"; then
+ linkalldeplibs=:
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if $linkalldeplibs; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test prog,link = "$linkmode,$pass"; then
+ if test -n "$library_names" &&
+ { { test no = "$prefer_static_libs" ||
+ test built,yes = "$prefer_static_libs,$installed"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
+ # Make sure the rpath contains only unique directories.
+ case $temp_rpath: in
+ *"$absdir:"*) ;;
+ *) func_append temp_rpath "$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if $alldeplibs &&
+ { test pass_all = "$deplibs_check_method" ||
+ { test yes = "$build_libtool_libs" &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test built = "$use_static_libs" && test yes = "$installed"; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test no = "$use_static_libs" || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc* | *os2*)
+ # No point in relinking DLLs because paths are not encoded
+ func_append notinst_deplibs " $lib"
+ need_relink=no
+ ;;
+ *)
+ if test no = "$installed"; then
+ func_append notinst_deplibs " $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule=$dlpremoduletest
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
+ echo
+ if test prog = "$linkmode"; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test lib = "$linkmode" &&
+ test yes = "$hardcode_into_libs"; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname=$1
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname=$dlname
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc* | *os2*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix=-$major
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname=$realname
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot=$soname
+ func_basename "$soroot"
+ soname=$func_basename_result
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from '$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for '$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test prog = "$linkmode" || test relink != "$opt_mode"; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test no = "$hardcode_direct"; then
+ add=$dir/$linklib
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
+ *-*-sysv4*uw2*) add_dir=-L$dir ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir=-L$dir ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we cannot
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library"; then
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
+ else
+ add=$dir/$old_library
+ fi
+ elif test -n "$old_library"; then
+ add=$dir/$old_library
+ fi
+ fi
+ esac
+ elif test no = "$hardcode_minus_L"; then
+ case $host in
+ *-*-sunos*) add_shlibpath=$dir ;;
+ esac
+ add_dir=-L$dir
+ add=-l$name
+ elif test no = "$hardcode_shlibpath_var"; then
+ add_shlibpath=$dir
+ add=-l$name
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test yes = "$hardcode_direct" &&
+ test no = "$hardcode_direct_absolute"; then
+ add=$dir/$linklib
+ elif test yes = "$hardcode_minus_L"; then
+ add_dir=-L$absdir
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add=-l$name
+ elif test yes = "$hardcode_shlibpath_var"; then
+ add_shlibpath=$dir
+ add=-l$name
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test yes != "$lib_linked"; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ esac
+ fi
+ if test prog = "$linkmode"; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test yes != "$hardcode_direct" &&
+ test yes != "$hardcode_minus_L" &&
+ test yes = "$hardcode_shlibpath_var"; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test prog = "$linkmode" || test relink = "$opt_mode"; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test yes = "$hardcode_direct" &&
+ test no = "$hardcode_direct_absolute"; then
+ add=$libdir/$linklib
+ elif test yes = "$hardcode_minus_L"; then
+ add_dir=-L$libdir
+ add=-l$name
+ elif test yes = "$hardcode_shlibpath_var"; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ add=-l$name
+ elif test yes = "$hardcode_automatic"; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib"; then
+ add=$inst_prefix_dir$libdir/$linklib
+ else
+ add=$libdir/$linklib
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir=-L$libdir
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add=-l$name
+ fi
+
+ if test prog = "$linkmode"; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test prog = "$linkmode"; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test unsupported != "$hardcode_direct"; then
+ test -n "$old_library" && linklib=$old_library
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test yes = "$build_libtool_libs"; then
+ # Not a shared library
+ if test pass_all != "$deplibs_check_method"; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ $ECHO "*** Warning: This system cannot link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test yes = "$module"; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test no = "$build_old_libs"; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test lib = "$linkmode"; then
+ if test -n "$dependency_libs" &&
+ { test yes != "$hardcode_into_libs" ||
+ test yes = "$build_old_libs" ||
+ test yes = "$link_static"; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) func_append xrpath " $temp_xrpath";;
+ esac;;
+ *) func_append temp_deplibs " $libdir";;
+ esac
+ done
+ dependency_libs=$temp_deplibs
+ fi
+
+ func_append newlib_search_path " $absdir"
+ # Link against this library
+ test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ esac
+ fi
+ func_append tmp_libs " $func_resolve_sysroot_result"
+ done
+
+ if test no != "$link_all_deplibs"; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path=$deplib ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
+ func_dirname "$deplib" "" "."
+ dir=$func_dirname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of '$dir'"
+ absdir=$dir
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names"; then
+ for tmp in $deplibrary_names; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl"; then
+ depdepl=$absdir/$objdir/$depdepl
+ darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
+ func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path=-L$absdir/$objdir
+ ;;
+ esac
+ else
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "'$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "'$deplib' seems to be moved"
+
+ path=-L$absdir
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test link = "$pass"; then
+ if test prog = "$linkmode"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs=$newdependency_libs
+ if test dlpreopen = "$pass"; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test dlopen != "$pass"; then
+ test conv = "$pass" || {
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) func_append lib_search_path " $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ }
+
+ if test prog,link = "$linkmode,$pass"; then
+ vars="compile_deplibs finalize_deplibs"
+ else
+ vars=deplibs
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+
+ # Add Sun CC postdeps if required:
+ test CXX = "$tagname" && {
+ case $host_os in
+ linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C++ 5.9
+ func_suncc_cstd_abi
+
+ if test no != "$suncc_use_cstd_abi"; then
+ func_append postdeps ' -library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ func_cc_basename "$CC"
+ case $func_cc_basename_result in
+ CC* | sunCC*)
+ func_suncc_cstd_abi
+
+ if test no != "$suncc_use_cstd_abi"; then
+ func_append postdeps ' -library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ }
+
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=
+ ;;
+ esac
+ if test -n "$i"; then
+ func_append tmp_libs " $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test prog = "$linkmode"; then
+ dlfiles=$newdlfiles
+ fi
+ if test prog = "$linkmode" || test lib = "$linkmode"; then
+ dlprefiles=$newdlprefiles
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ func_warning "'-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "'-l' and '-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "'-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "'-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "'-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs=$output
+ func_append objs "$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form 'libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test no = "$module" \
+ && func_fatal_help "libtool library '$output' must begin with 'lib'"
+
+ if test no != "$need_lib_prefix"; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test pass_all != "$deplibs_check_method"; then
+ func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ func_append libobjs " $objs"
+ fi
+ fi
+
+ test no = "$dlself" \
+ || func_warning "'-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test 1 -lt "$#" \
+ && func_warning "ignoring multiple '-rpath's for a libtool library"
+
+ install_libdir=$1
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test yes = "$build_libtool_libs"; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a '.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs=$IFS; IFS=:
+ set dummy $vinfo 0 0 0
+ shift
+ IFS=$save_ifs
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to '-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major=$1
+ number_minor=$2
+ number_revision=$3
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # that has an extra 1 added just for fun
+ #
+ case $version_type in
+ # correct linux to gnu/linux during the next big refactor
+ darwin|freebsd-elf|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age=$number_minor
+ revision=$number_revision
+ ;;
+ freebsd-aout|qnx|sunos)
+ current=$number_major
+ revision=$number_minor
+ age=0
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age=$number_minor
+ revision=$number_minor
+ lt_irix_increment=no
+ ;;
+ esac
+ ;;
+ no)
+ current=$1
+ revision=$2
+ age=$3
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT '$current' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION '$revision' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE '$age' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE '$age' is greater than the current interface number '$current'"
+ func_fatal_error "'$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ # On Darwin other compilers
+ case $CC in
+ nagfor*)
+ verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ ;;
+ *)
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+ esac
+ ;;
+
+ freebsd-aout)
+ major=.$current
+ versuffix=.$current.$revision
+ ;;
+
+ freebsd-elf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ ;;
+
+ irix | nonstopux)
+ if test no = "$lt_irix_increment"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring=$verstring_prefix$major.$revision
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test 0 -ne "$loop"; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring=$verstring_prefix$major.$iface:$verstring
+ done
+
+ # Before this point, $major must not contain '.'.
+ major=.$major
+ versuffix=$major.$revision
+ ;;
+
+ linux) # correct to gnu/linux during the next big refactor
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=.$current.$age.$revision
+ verstring=$current.$age.$revision
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test 0 -ne "$loop"; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring=$verstring:$iface.0
+ done
+
+ # Make executables depend on our current version.
+ func_append verstring ":$current.0"
+ ;;
+
+ qnx)
+ major=.$current
+ versuffix=.$current
+ ;;
+
+ sco)
+ major=.$current
+ versuffix=.$current
+ ;;
+
+ sunos)
+ major=.$current
+ versuffix=.$current.$revision
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 file systems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix=-$major
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type '$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring=0.0
+ ;;
+ esac
+ if test no = "$need_version"; then
+ versuffix=
+ else
+ versuffix=.0.0
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test yes,no = "$avoid_version,$need_version"; then
+ major=
+ versuffix=
+ verstring=
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test yes = "$allow_undefined"; then
+ if test unsupported = "$allow_undefined_flag"; then
+ if test yes = "$build_old_libs"; then
+ func_warning "undefined symbols not allowed in $host shared libraries; building static only"
+ build_libtool_libs=no
+ else
+ func_fatal_error "can't build $host shared library unless -no-undefined is specified"
+ fi
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag=$no_undefined_flag
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" :
+ func_append libobjs " $symfileobj"
+ test " " = "$libobjs" && libobjs=
+
+ if test relink != "$opt_mode"; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
+ if test -n "$precious_files_regex"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ func_append removelist " $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
+ func_append oldlibs " $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles=$dlfiles
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) func_append dlfiles " $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles=$dlprefiles
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) func_append dlprefiles " $lib" ;;
+ esac
+ done
+
+ if test yes = "$build_libtool_libs"; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ func_append deplibs " System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test yes = "$build_libtool_need_lc"; then
+ func_append deplibs " -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=
+ versuffix=
+ major=
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=
+ ;;
+ esac
+ fi
+ if test -n "$i"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=
+ ;;
+ esac
+ fi
+ if test -n "$i"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test yes = "$want_nocaseglob"; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib=$potent_lib
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
+ *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib"; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib"; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib=$potent_lib # see symlink-check above in file_magic test
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib"; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib"; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ for i in $predeps $postdeps; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
+ done
+ fi
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
+ if test none = "$deplibs_check_method"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ ;;
+ esac
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test yes = "$droppeddeps"; then
+ if test yes = "$module"; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test no = "$build_old_libs"; then
+ oldlibs=$output_objdir/$libname.$libext
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test no = "$allow_undefined"; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test no = "$build_old_libs"; then
+ oldlibs=$output_objdir/$libname.$libext
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ deplibs=$new_libs
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test yes = "$build_libtool_libs"; then
+ # Remove $wl instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
+ if test yes = "$hardcode_into_libs"; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath=$finalize_rpath
+ test relink = "$opt_mode" || rpath=$compile_rpath$rpath
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append dep_rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath=$finalize_shlibpath
+ test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname=$1
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname=$realname
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib=$output_objdir/$realname
+ linknames=
+ for link
+ do
+ func_append linknames " $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols=$output_objdir/$libname.uexp
+ func_append delfiles " $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ func_dll_def_p "$export_symbols" || {
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols=$export_symbols
+ export_symbols=
+ always_export_symbols=yes
+ }
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for '$libname.la'"
+ export_symbols=$output_objdir/$libname.exp
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs=$IFS; IFS='~'
+ for cmd1 in $cmds; do
+ IFS=$save_ifs
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test yes = "$try_normal_branch" \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=$output_objdir/$output_la.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
+ func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS=$save_ifs
+ if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols=$export_symbols
+ test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands, which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ func_append tmp_deplibs " $test_deplib"
+ ;;
+ esac
+ done
+ deplibs=$tmp_deplibs
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test yes = "$compiler_needs_object" &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ func_append linker_flags " $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test relink = "$opt_mode"; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test yes = "$module" && test -n "$module_cmds"; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test : != "$skipped_export" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ func_basename "$output"
+ output_la=$func_basename_result
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
+ output=$output_objdir/$output_la.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ echo 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
+ elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
+ output=$output_objdir/$output_la.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test yes = "$compiler_needs_object"; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-$k.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test -z "$objlist" ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test 1 -eq "$k"; then
+ # The first file doesn't have a previous command to add.
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-$k.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-$k.$objext
+ objlist=" $obj"
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds$reload_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ func_append delfiles " $output"
+
+ else
+ output=
+ fi
+
+ ${skipped_export-false} && {
+ func_verbose "generating symbol list for '$libname.la'"
+ export_symbols=$output_objdir/$libname.exp
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ }
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs=$IFS; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS=$save_ifs
+ $opt_quiet || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS=$save_ifs
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ ${skipped_export-false} && {
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols=$export_symbols
+ test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands, which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ }
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test yes = "$module" && test -n "$module_cmds"; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs=$IFS; IFS='~'
+ for cmd in $cmds; do
+ IFS=$sp$nl
+ eval cmd=\"$cmd\"
+ IFS=$save_ifs
+ $opt_quiet || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS=$save_ifs
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test yes = "$module" || test yes = "$export_dynamic"; then
+ # On all known operating systems, these are identical.
+ dlname=$soname
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ func_warning "'-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "'-l' and '-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "'-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "'-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object '$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj=$output
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # if reload_cmds runs $LD directly, get rid of -Wl from
+ # whole_archive_flag_spec and hope we can get by with turning comma
+ # into space.
+ case $reload_cmds in
+ *\$LD[\ \$]*) wl= ;;
+ esac
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
+ else
+ gentop=$output_objdir/${obj}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # If we're not building shared, we need to use non_pic_objs
+ test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
+
+ # Create the old-style object.
+ reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
+
+ output=$obj
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ test yes = "$build_libtool_libs" || {
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ }
+
+ if test -n "$pic_flag" || test default != "$pic_mode"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output=$libobj
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "'-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for programs"
+
+ $preload \
+ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
+ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test CXX = "$tagname"; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ func_append compile_command " $wl-bind_at_load"
+ func_append finalize_command " $wl-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ compile_deplibs=$new_libs
+
+
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath=$rpath
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath=$rpath
+
+ if test -n "$libobjs" && test yes = "$build_old_libs"; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" false
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=:
+ case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=false
+ ;;
+ *cygwin* | *mingw* )
+ test yes = "$build_libtool_libs" || wrappers_required=false
+ ;;
+ *)
+ if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
+ wrappers_required=false
+ fi
+ ;;
+ esac
+ $wrappers_required || {
+ # Replace the output file specification.
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ link_command=$compile_command$compile_rpath
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.$objext"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
+ fi
+
+ exit $exit_status
+ }
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test yes = "$no_install"; then
+ # We don't need to create a wrapper script.
+ link_command=$compile_var$compile_command$compile_rpath
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ case $hardcode_action,$fast_install in
+ relink,*)
+ # Fast installation is not supported
+ link_command=$compile_var$compile_command$compile_rpath
+ relink_command=$finalize_var$finalize_command$finalize_rpath
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "'$output' will be relinked during installation"
+ ;;
+ *,yes)
+ link_command=$finalize_var$compile_command$finalize_rpath
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ ;;
+ *,no)
+ link_command=$compile_var$compile_command$compile_rpath
+ relink_command=$finalize_var$finalize_command$finalize_rpath
+ ;;
+ *,needless)
+ link_command=$finalize_var$compile_command$finalize_rpath
+ relink_command=
+ ;;
+ esac
+
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource=$output_path/$objdir/lt-$output_name.c
+ cwrapper=$output_path/$output_name.exe
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host"; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ case $build_libtool_libs in
+ convenience)
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs=$convenience
+ build_libtool_libs=no
+ ;;
+ module)
+ oldobjs=$libobjs_save
+ addlibs=$old_convenience
+ build_libtool_libs=no
+ ;;
+ *)
+ oldobjs="$old_deplibs $non_pic_objects"
+ $preload && test -f "$symfileobj" \
+ && func_append oldobjs " $symfileobj"
+ addlibs=$old_convenience
+ ;;
+ esac
+
+ if test -n "$addlibs"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $addlibs
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ echo "copying selected object files to avoid basename conflicts..."
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase=$func_basename_result
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
+ ;;
+ *) func_append oldobjs " $obj" ;;
+ esac
+ done
+ fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj"; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test -z "$oldobjs"; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test yes = "$build_old_libs" && old_library=$libname.$libext
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ if test yes = "$hardcode_automatic"; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test yes = "$installed"; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output=$output_objdir/${outputname}i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name=$func_basename_result
+ func_resolve_sysroot "$deplib"
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ test -z "$libdir" && \
+ func_fatal_error "'$deplib' is not a valid libtool archive"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
+ ;;
+ *) func_append newdependency_libs " $deplib" ;;
+ esac
+ done
+ dependency_libs=$newdependency_libs
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name=$func_basename_result
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "'$lib' is not a valid libtool archive"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ *) func_append newdlfiles " $lib" ;;
+ esac
+ done
+ dlfiles=$newdlfiles
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name=$func_basename_result
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "'$lib' is not a valid libtool archive"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles=$newdlprefiles
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlfiles " $abs"
+ done
+ dlfiles=$newdlfiles
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlprefiles " $abs"
+ done
+ dlprefiles=$newdlprefiles
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test -n "$bindir"; then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result/$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that cannot go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test no,yes = "$installed,$need_relink"; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+if test link = "$opt_mode" || test relink = "$opt_mode"; then
+ func_mode_link ${1+"$@"}
+fi
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $debug_cmd
+
+ RM=$nonopt
+ files=
+ rmforce=false
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic=$magic
+
+ for arg
+ do
+ case $arg in
+ -f) func_append RM " $arg"; rmforce=: ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+ if test . = "$dir"; then
+ odir=$objdir
+ else
+ odir=$dir/$objdir
+ fi
+ func_basename "$file"
+ name=$func_basename_result
+ test uninstall = "$opt_mode" && odir=$dir
+
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test clean = "$opt_mode"; then
+ case " $rmdirs " in
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif $rmforce; then
+ continue
+ fi
+
+ rmfiles=$file
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ func_append rmfiles " $odir/$n"
+ done
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+ case $opt_mode in
+ clean)
+ case " $library_names " in
+ *" $dlname "*) ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ esac
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" && test none != "$pic_object"; then
+ func_append rmfiles " $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" && test none != "$non_pic_object"; then
+ func_append rmfiles " $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test clean = "$opt_mode"; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ func_append rmfiles " $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ func_append rmfiles " $odir/$name $odir/${name}S.$objext"
+ if test yes = "$fast_install" && test -n "$relink_command"; then
+ func_append rmfiles " $odir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name"; then
+ func_append rmfiles " $odir/lt-$noexename.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+
+ # Try to remove the $objdir's in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
+ func_mode_uninstall ${1+"$@"}
+fi
+
+test -z "$opt_mode" && {
+ help=$generic_help
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode '$opt_mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# where we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
--- /dev/null
+#! /bin/sh
+# Common wrapper for a few potentially missing GNU programs.
+
+scriptversion=2013-10-28.13; # UTC
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try '$0 --help' for more information"
+ exit 1
+fi
+
+case $1 in
+
+ --is-lightweight)
+ # Used by our autoconf macros to check whether the available missing
+ # script is modern enough.
+ exit 0
+ ;;
+
+ --run)
+ # Back-compat with the calling convention used by older automake.
+ shift
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal autoconf autoheader autom4te automake makeinfo
+ bison yacc flex lex help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: unknown '$1' option"
+ echo 1>&2 "Try '$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch. This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+ msg="probably too old"
+elif test $st -eq 127; then
+ # Program was missing.
+ msg="missing on your system"
+else
+ # Program was found and executed, but failed. Give up.
+ exit $st
+fi
+
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+ case $1 in
+ aclocal|automake)
+ echo "The '$1' program is part of the GNU Automake package:"
+ echo "<$gnu_software_URL/automake>"
+ echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/autoconf>"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ autoconf|autom4te|autoheader)
+ echo "The '$1' program is part of the GNU Autoconf package:"
+ echo "<$gnu_software_URL/autoconf/>"
+ echo "It also requires GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ esac
+}
+
+give_advice ()
+{
+ # Normalize program name to check for.
+ normalized_program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+ printf '%s\n' "'$1' is $msg."
+
+ configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+ case $normalized_program in
+ autoconf*)
+ echo "You should only need it if you modified 'configure.ac',"
+ echo "or m4 files included by it."
+ program_details 'autoconf'
+ ;;
+ autoheader*)
+ echo "You should only need it if you modified 'acconfig.h' or"
+ echo "$configure_deps."
+ program_details 'autoheader'
+ ;;
+ automake*)
+ echo "You should only need it if you modified 'Makefile.am' or"
+ echo "$configure_deps."
+ program_details 'automake'
+ ;;
+ aclocal*)
+ echo "You should only need it if you modified 'acinclude.m4' or"
+ echo "$configure_deps."
+ program_details 'aclocal'
+ ;;
+ autom4te*)
+ echo "You might have modified some maintainer files that require"
+ echo "the 'autom4te' program to be rebuilt."
+ program_details 'autom4te'
+ ;;
+ bison*|yacc*)
+ echo "You should only need it if you modified a '.y' file."
+ echo "You may want to install the GNU Bison package:"
+ echo "<$gnu_software_URL/bison/>"
+ ;;
+ lex*|flex*)
+ echo "You should only need it if you modified a '.l' file."
+ echo "You may want to install the Fast Lexical Analyzer package:"
+ echo "<$flex_URL>"
+ ;;
+ help2man*)
+ echo "You should only need it if you modified a dependency" \
+ "of a man page."
+ echo "You may want to install the GNU Help2man package:"
+ echo "<$gnu_software_URL/help2man/>"
+ ;;
+ makeinfo*)
+ echo "You should only need it if you modified a '.texi' file, or"
+ echo "any other file indirectly affecting the aspect of the manual."
+ echo "You might want to install the Texinfo package:"
+ echo "<$gnu_software_URL/texinfo/>"
+ echo "The spurious makeinfo call might also be the consequence of"
+ echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+ echo "want to install GNU make:"
+ echo "<$gnu_software_URL/make/>"
+ ;;
+ *)
+ echo "You might have modified some files without having the proper"
+ echo "tools for further handling them. Check the 'README' file, it"
+ echo "often tells you about the needed prerequisites for installing"
+ echo "this package. You may also peek at any GNU archive site, in"
+ echo "case some other package contains this missing '$1' program."
+ ;;
+ esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+ -e '2,$s/^/ /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2013-07-13.22; # UTC
+
+# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+# Make unconditional expansion of undefined variables an error. This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+ echo "$0: $*" >&2
+ print_usage >&2
+ exit 2
+}
+
+print_usage ()
+{
+ cat <<END
+Usage:
+ test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+ [--expect-failure={yes|no}] [--color-tests={yes|no}]
+ [--enable-hard-errors={yes|no}] [--]
+ TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+test_name= # Used for reporting.
+log_file= # Where to save the output of the test script.
+trs_file= # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+ case $1 in
+ --help) print_usage; exit $?;;
+ --version) echo "test-driver $scriptversion"; exit $?;;
+ --test-name) test_name=$2; shift;;
+ --log-file) log_file=$2; shift;;
+ --trs-file) trs_file=$2; shift;;
+ --color-tests) color_tests=$2; shift;;
+ --expect-failure) expect_failure=$2; shift;;
+ --enable-hard-errors) enable_hard_errors=$2; shift;;
+ --) shift; break;;
+ -*) usage_error "invalid option: '$1'";;
+ *) break;;
+ esac
+ shift
+done
+
+missing_opts=
+test x"$test_name" = x && missing_opts="$missing_opts --test-name"
+test x"$log_file" = x && missing_opts="$missing_opts --log-file"
+test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
+if test x"$missing_opts" != x; then
+ usage_error "the following mandatory options are missing:$missing_opts"
+fi
+
+if test $# -eq 0; then
+ usage_error "missing argument"
+fi
+
+if test $color_tests = yes; then
+ # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+ red='\e[0;31m' # Red.
+ grn='\e[0;32m' # Green.
+ lgn='\e[1;32m' # Light green.
+ blu='\e[1;34m' # Blue.
+ mgn='\e[0;35m' # Magenta.
+ std='\e[m' # No color.
+else
+ red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+ tweaked_estatus=1
+else
+ tweaked_estatus=$estatus
+fi
+
+case $tweaked_estatus:$expect_failure in
+ 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+ 0:*) col=$grn res=PASS recheck=no gcopy=no;;
+ 77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
+ 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
+ *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
+ *:*) col=$red res=FAIL recheck=yes gcopy=yes;;
+esac
+
+# Report the test outcome and exit status in the logs, so that one can
+# know whether the test passed or failed simply by looking at the '.log'
+# file, without the need of also peaking into the corresponding '.trs'
+# file (automake bug#11814).
+echo "$res $test_name (exit status: $estatus)" >>$log_file
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* always defined to indicate that i18n is enabled */
+#undef ENABLE_NLS
+
+/* Enable compile-time and run-time bounds-checking, and some warnings. */
+ #if !defined _FORTIFY_SOURCE && defined __OPTIMIZE__ && __OPTIMIZE__
+ # define _FORTIFY_SOURCE 2
+ #endif
+
+
+/* GETTEXT package name */
+#undef GETTEXT_PACKAGE
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define to 1 if you have the `bind_textdomain_codeset' function. */
+#undef HAVE_BIND_TEXTDOMAIN_CODESET
+
+/* Use the builtin mjpeg decoder? */
+#undef HAVE_BUILTIN_MJPEG
+
+/* Define to 1 if you have the `clearenv' function. */
+#undef HAVE_CLEARENV
+
+/* Define to 1 if you have the `dcgettext' function. */
+#undef HAVE_DCGETTEXT
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `gdk_event_get_scancode' function. */
+#undef HAVE_GDK_EVENT_GET_SCANCODE
+
+/* Define if the GNU gettext() function is already present or preinstalled. */
+#undef HAVE_GETTEXT
+
+/* Define if supporting GStreamer 1.0 */
+#undef HAVE_GSTAUDIO
+
+/* Define if supporting GStreamer 1.0 */
+#undef HAVE_GSTVIDEO
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if your <locale.h> file defines LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define if you have a polkit with polkit_authority_get_sync() */
+#undef HAVE_POLKIT_AUTHORITY_GET_SYNC
+
+/* Define if you have a polkit with
+ polkit_authorization_result_get_dismissed() */
+#undef HAVE_POLKIT_AUTHORIZATION_RESULT_GET_DISMISSED
+
+/* Have PulseAudio support? */
+#undef HAVE_PULSE
+
+/* whether Cyrus SASL is available for authentication */
+#undef HAVE_SASL
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strtok_r' function. */
+#undef HAVE_STRTOK_R
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <X11/XKBlib.h> header file. */
+#undef HAVE_X11_XKBLIB_H
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if supporting gdbus */
+#undef USE_GDBUS
+
+/* Define if supporting gudev */
+#undef USE_GUDEV
+
+/* Define if libusb has hotplug support */
+#undef USE_LIBUSB_HOTPLUG
+
+/* Define to build with lz4 support */
+#undef USE_LZ4
+
+/* Define if supporting phodav */
+#undef USE_PHODAV
+
+/* Define if supporting polkit */
+#undef USE_POLKIT
+
+/* Define if supporting smartcard proxying */
+#undef USE_SMARTCARD
+
+/* Define if supporting smartcard proxying without libcacard.h */
+#undef USE_SMARTCARD_012
+
+/* Define if supporting usbredir proxying */
+#undef USE_USBREDIR
+
+/* Version number of package */
+#undef VERSION
+
+/* Whether to use gthread coroutine impl */
+#undef WITH_GTHREAD
+
+/* Whether to use ucontext coroutine impl */
+#undef WITH_UCONTEXT
+
+/* Define if compiling with usb.ids support */
+#undef WITH_USBIDS
+
+/* Whether to use fiber coroutine impl */
+#undef WITH_WINFIBER
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
--- /dev/null
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for spice-gtk 0.33.
+#
+# Report bugs to <spice-devel@lists.freedesktop.org>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: spice-devel@lists.freedesktop.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+as_awk_strverscmp='
+ # Use only awk features that work with 7th edition Unix awk (1978).
+ # My, what an old awk you have, Mr. Solaris!
+ END {
+ while (length(v1) && length(v2)) {
+ # Set d1 to be the next thing to compare from v1, and likewise for d2.
+ # Normally this is a single character, but if v1 and v2 contain digits,
+ # compare them as integers and fractions as strverscmp does.
+ if (v1 ~ /^[0-9]/ && v2 ~ /^[0-9]/) {
+ # Split v1 and v2 into their leading digit string components d1 and d2,
+ # and advance v1 and v2 past the leading digit strings.
+ for (len1 = 1; substr(v1, len1 + 1) ~ /^[0-9]/; len1++) continue
+ for (len2 = 1; substr(v2, len2 + 1) ~ /^[0-9]/; len2++) continue
+ d1 = substr(v1, 1, len1); v1 = substr(v1, len1 + 1)
+ d2 = substr(v2, 1, len2); v2 = substr(v2, len2 + 1)
+ if (d1 ~ /^0/) {
+ if (d2 ~ /^0/) {
+ # Compare two fractions.
+ while (d1 ~ /^0/ && d2 ~ /^0/) {
+ d1 = substr(d1, 2); len1--
+ d2 = substr(d2, 2); len2--
+ }
+ if (len1 != len2 && ! (len1 && len2 && substr(d1, 1, 1) == substr(d2, 1, 1))) {
+ # The two components differ in length, and the common prefix
+ # contains only leading zeros. Consider the longer to be less.
+ d1 = -len1
+ d2 = -len2
+ } else {
+ # Otherwise, compare as strings.
+ d1 = "x" d1
+ d2 = "x" d2
+ }
+ } else {
+ # A fraction is less than an integer.
+ exit 1
+ }
+ } else {
+ if (d2 ~ /^0/) {
+ # An integer is greater than a fraction.
+ exit 2
+ } else {
+ # Compare two integers.
+ d1 += 0
+ d2 += 0
+ }
+ }
+ } else {
+ # The normal case, without worrying about digits.
+ d1 = substr(v1, 1, 1); v1 = substr(v1, 2)
+ d2 = substr(v2, 1, 1); v2 = substr(v2, 2)
+ }
+ if (d1 < d2) exit 1
+ if (d1 > d2) exit 2
+ }
+ # Beware Solaris /usr/xgp4/bin/awk (at least through Solaris 10),
+ # which mishandles some comparisons of empty strings to integers.
+ if (length(v2)) exit 1
+ if (length(v1)) exit 2
+ }
+'
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='spice-gtk'
+PACKAGE_TARNAME='spice-gtk'
+PACKAGE_VERSION='0.33'
+PACKAGE_STRING='spice-gtk 0.33'
+PACKAGE_BUGREPORT='spice-devel@lists.freedesktop.org'
+PACKAGE_URL=''
+
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+enable_option_checking=no
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+BUILD_TESTS_FALSE
+BUILD_TESTS_TRUE
+SPICE_GTK_REQUIRES
+SPICE_GLIB_REQUIRES
+SPICE_GTK_CFLAGS
+SPICE_GLIB_CFLAGS
+SPICE_CFLAGS
+WARN_PYFLAGS
+WARN_LDFLAGS
+WARN_CFLAGS
+HAVE_LZ4_FALSE
+HAVE_LZ4_TRUE
+LZ4_LIBS
+LZ4_CFLAGS
+VAPIDIR
+WITH_VALA_FALSE
+WITH_VALA_TRUE
+VAPIGEN
+VALAC
+WITH_CONTROLLER_FALSE
+WITH_CONTROLLER_TRUE
+G_IR_SCANNER_SYMBOL_PREFIX_FALSE
+G_IR_SCANNER_SYMBOL_PREFIX_TRUE
+INTROSPECTION_MAKEFILE
+INTROSPECTION_LIBS
+INTROSPECTION_CFLAGS
+INTROSPECTION_TYPELIBDIR
+INTROSPECTION_GIRDIR
+INTROSPECTION_GENERATE
+INTROSPECTION_COMPILER
+INTROSPECTION_SCANNER
+HAVE_INTROSPECTION_FALSE
+HAVE_INTROSPECTION_TRUE
+WITH_GTHREAD_FALSE
+WITH_GTHREAD_TRUE
+WITH_WINFIBER_FALSE
+WITH_WINFIBER_TRUE
+WITH_UCONTEXT_FALSE
+WITH_UCONTEXT_TRUE
+USB_IDS
+ACL_HELPER_DIR
+PIE_LDFLAGS
+PIE_CFLAGS
+POLICYDIR
+WITH_POLKIT_FALSE
+WITH_POLKIT_TRUE
+ACL_LIBS
+POLKIT_LIBS
+POLKIT_CFLAGS
+WITH_USBREDIR_FALSE
+WITH_USBREDIR_TRUE
+GUDEV_LIBS
+GUDEV_CFLAGS
+LIBUSB_HOTPLUG_LIBS
+LIBUSB_HOTPLUG_CFLAGS
+USBREDIR_LIBS
+USBREDIR_CFLAGS
+WITH_SMARTCARD_FALSE
+WITH_SMARTCARD_TRUE
+HAVE_SMARTCARD_FALSE
+HAVE_SMARTCARD_TRUE
+SMARTCARD_LIBS
+SMARTCARD_CFLAGS
+Z_LIBS
+JPEG_LIBS
+HAVE_BUILTIN_MJPEG_FALSE
+HAVE_BUILTIN_MJPEG_TRUE
+HAVE_GSTVIDEO_FALSE
+HAVE_GSTVIDEO_TRUE
+GSTVIDEO_LIBS
+GSTVIDEO_CFLAGS
+HAVE_GSTAUDIO_FALSE
+HAVE_GSTAUDIO_TRUE
+GST_INSPECT_1_0
+GSTAUDIO_LIBS
+GSTAUDIO_CFLAGS
+HAVE_PULSE_FALSE
+HAVE_PULSE_TRUE
+PULSE_LIBS
+PULSE_CFLAGS
+WITH_PHODAV_FALSE
+WITH_PHODAV_TRUE
+PHODAV_LIBS
+PHODAV_CFLAGS
+GTHREAD_LIBS
+GTHREAD_CFLAGS
+CAIRO_LIBS
+CAIRO_CFLAGS
+GIO_LIBS
+GIO_CFLAGS
+GOBJECT2_LIBS
+GOBJECT2_CFLAGS
+GLIB2_LIBS
+GLIB2_CFLAGS
+PNP_IDS
+USE_INTERNAL_PNP_IDS_FALSE
+USE_INTERNAL_PNP_IDS_TRUE
+X11_LIBS
+X11_CFLAGS
+GTK_LIBS
+GTK_CFLAGS
+WITH_GTK_FALSE
+WITH_GTK_TRUE
+GTK_REQUIRED
+SASL_LIBS
+SASL_CFLAGS
+SSL_LIBS
+SSL_CFLAGS
+PIXMAN_LIBS
+PIXMAN_CFLAGS
+SPICE_GTK_MICRO_VERSION
+SPICE_GTK_MINOR_VERSION
+SPICE_GTK_MAJOR_VERSION
+COMMON_CFLAGS
+SPICE_PROTOCOL_LIBS
+SPICE_PROTOCOL_CFLAGS
+subdirs
+LIBM
+OS_WIN32_FALSE
+OS_WIN32_TRUE
+HAVE_LD_VERSION_SCRIPT_FALSE
+HAVE_LD_VERSION_SCRIPT_TRUE
+PYTHON
+STOW
+GTK_DOC_USE_REBASE_FALSE
+GTK_DOC_USE_REBASE_TRUE
+GTK_DOC_USE_LIBTOOL_FALSE
+GTK_DOC_USE_LIBTOOL_TRUE
+GTK_DOC_BUILD_PDF_FALSE
+GTK_DOC_BUILD_PDF_TRUE
+GTK_DOC_BUILD_HTML_FALSE
+GTK_DOC_BUILD_HTML_TRUE
+ENABLE_GTK_DOC_FALSE
+ENABLE_GTK_DOC_TRUE
+HAVE_GTK_DOC_FALSE
+HAVE_GTK_DOC_TRUE
+GTKDOC_DEPS_LIBS
+GTKDOC_DEPS_CFLAGS
+HTML_DIR
+GTKDOC_MKPDF
+GTKDOC_REBASE
+GTKDOC_CHECK_PATH
+GTKDOC_CHECK
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
+SPICE_GTK_LOCALEDIR
+MKINSTALLDIRS
+POSUB
+POFILES
+PO_IN_DATADIR_FALSE
+PO_IN_DATADIR_TRUE
+INTLLIBS
+INSTOBJEXT
+GMOFILES
+DATADIRNAME
+CATOBJEXT
+CATALOGS
+MSGFMT_OPTS
+GETTEXT_PACKAGE
+ALL_LINGUAS
+INTLTOOL_PERL
+GMSGFMT
+MSGFMT
+MSGMERGE
+XGETTEXT
+INTLTOOL_POLICY_RULE
+INTLTOOL_SERVICE_RULE
+INTLTOOL_THEME_RULE
+INTLTOOL_SCHEMAS_RULE
+INTLTOOL_CAVES_RULE
+INTLTOOL_XML_NOMERGE_RULE
+INTLTOOL_XML_RULE
+INTLTOOL_KBD_RULE
+INTLTOOL_XAM_RULE
+INTLTOOL_UI_RULE
+INTLTOOL_SOUNDLIST_RULE
+INTLTOOL_SHEET_RULE
+INTLTOOL_SERVER_RULE
+INTLTOOL_PONG_RULE
+INTLTOOL_OAF_RULE
+INTLTOOL_PROP_RULE
+INTLTOOL_KEYS_RULE
+INTLTOOL_DIRECTORY_RULE
+INTLTOOL_DESKTOP_RULE
+intltool__v_merge_options_0
+intltool__v_merge_options_
+INTLTOOL_V_MERGE_OPTIONS
+INTLTOOL__v_MERGE_0
+INTLTOOL__v_MERGE_
+INTLTOOL_V_MERGE
+INTLTOOL_EXTRACT
+INTLTOOL_MERGE
+INTLTOOL_UPDATE
+USE_NLS
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+CPP
+LT_SYS_LIBRARY_PATH
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+OBJDUMP
+DLLTOOL
+AS
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+ac_ct_AR
+AR
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_silent_rules
+enable_dependency_tracking
+enable_static
+enable_shared
+with_pic
+enable_fast_install
+with_aix_soname
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+enable_maintainer_mode
+enable_nls
+with_html_dir
+enable_gtk_doc
+enable_gtk_doc_html
+enable_gtk_doc_pdf
+with_sasl
+with_gtk
+with_pnp_ids_path
+enable_webdav
+with_audio
+enable_pulse
+enable_gstaudio
+enable_gstvideo
+enable_builtin_mjpeg
+enable_smartcard
+enable_usbredir
+enable_polkit
+enable_pie
+with_usb_acl_helper_dir
+with_usb_ids_path
+with_coroutine
+enable_introspection
+enable_controller
+enable_vala
+enable_dbus
+enable_lz4
+enable_werror
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+LT_SYS_LIBRARY_PATH
+CPP
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR
+GTKDOC_DEPS_CFLAGS
+GTKDOC_DEPS_LIBS
+SPICE_PROTOCOL_CFLAGS
+SPICE_PROTOCOL_LIBS
+PIXMAN_CFLAGS
+PIXMAN_LIBS
+SSL_CFLAGS
+SSL_LIBS
+SASL_CFLAGS
+SASL_LIBS
+GTK_CFLAGS
+GTK_LIBS
+X11_CFLAGS
+X11_LIBS
+GLIB2_CFLAGS
+GLIB2_LIBS
+GOBJECT2_CFLAGS
+GOBJECT2_LIBS
+GIO_CFLAGS
+GIO_LIBS
+CAIRO_CFLAGS
+CAIRO_LIBS
+GTHREAD_CFLAGS
+GTHREAD_LIBS
+PHODAV_CFLAGS
+PHODAV_LIBS
+PULSE_CFLAGS
+PULSE_LIBS
+GSTAUDIO_CFLAGS
+GSTAUDIO_LIBS
+GSTVIDEO_CFLAGS
+GSTVIDEO_LIBS
+SMARTCARD_CFLAGS
+SMARTCARD_LIBS
+USBREDIR_CFLAGS
+USBREDIR_LIBS
+LIBUSB_HOTPLUG_CFLAGS
+LIBUSB_HOTPLUG_LIBS
+GUDEV_CFLAGS
+GUDEV_LIBS
+POLKIT_CFLAGS
+POLKIT_LIBS
+LZ4_CFLAGS
+LZ4_LIBS'
+ac_subdirs_all='spice-common'
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures spice-gtk 0.33 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/spice-gtk]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of spice-gtk 0.33:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-silent-rules less verbose build output (undo: "make V=1")
+ --disable-silent-rules verbose build output (undo: "make V=0")
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
+ --enable-static[=PKGS] build static libraries [default=no]
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --enable-maintainer-mode
+ enable make rules and dependencies not useful (and
+ sometimes confusing) to the casual installer
+ --disable-nls do not use Native Language Support
+ --enable-gtk-doc use gtk-doc to build documentation [[default=no]]
+ --enable-gtk-doc-html build documentation in html format [[default=yes]]
+ --enable-gtk-doc-pdf build documentation in pdf format [[default=no]]
+ --enable-webdav=[auto/yes/no]
+ Enable webdav support [default=auto]
+ --enable-pulse=[yes/auto/no]
+ Enable the PulseAudio backend [default=auto]
+ --enable-gstaudio=[yes/auto/no]
+ Enable the GStreamer 1.0 audio backend
+ [default=auto]
+ --enable-gstvideo=[auto/yes/no]
+ Enable GStreamer video support [default=auto]
+ --enable-builtin-mjpeg Enable the builtin mjpeg video decoder [default=yes]
+ --enable-smartcard=[yes/no/auto]
+ Enable smartcard support [default=auto]
+ --enable-usbredir=[auto/yes/no]
+ Enable usbredir support [default=auto]
+ --enable-polkit=[auto/yes/no]
+ Enable PolicyKit support (for the usb acl
+ helper)[default=auto]
+ --enable-pie=[auto/yes/no]
+ Enable position-independent-executable support (for
+ the usb acl helper)[default=auto]
+ --enable-introspection=[no/auto/yes]
+ Enable introspection for this build
+ --enable-controller Enable controller build [default=yes]
+ --enable-vala Check for vala requirements [default=no]
+ --enable-dbus=[auto/yes/no]
+ Enable dbus support for desktop integration
+ (disabling automount) [default=auto]
+ --enable-lz4=[yes/no/auto]
+ Enable LZ4 compression support [default=auto]
+ --enable-werror Use -Werror (if supported)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-aix-soname=aix|svr4|both
+ shared library versioning (aka "SONAME") variant to
+ provide on AIX, [default=aix].
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the
+ compiler's sysroot if not specified).
+ --with-html-dir=PATH path to installed docs
+ --with-sasl=[yes/no/auto]
+ use cyrus SASL for authentication [default=auto]
+ --with-gtk=[3.0/no] which gtk+ version to compile against [default=3.0]
+ --with-pnp-ids-path Specify the path to pnp.ids [default=(internal)]
+ --with-audio=[gstreamer/pulse/auto/no]
+ For legacy compatibility only
+ --with-usb-acl-helper-dir=DIR
+ Directory where the USB ACL helper binary should be
+ installed
+ --with-usb-ids-path Specify the path to usb.ids [default=auto]
+ --with-coroutine=[ucontext/gthread/winfiber/auto]
+ use ucontext or GThread for coroutines
+ [default=auto]
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ LT_SYS_LIBRARY_PATH
+ User-defined run-time library search path.
+ CPP C preprocessor
+ PKG_CONFIG path to pkg-config utility
+ PKG_CONFIG_PATH
+ directories to add to pkg-config's search path
+ PKG_CONFIG_LIBDIR
+ path overriding pkg-config's built-in search path
+ GTKDOC_DEPS_CFLAGS
+ C compiler flags for GTKDOC_DEPS, overriding pkg-config
+ GTKDOC_DEPS_LIBS
+ linker flags for GTKDOC_DEPS, overriding pkg-config
+ SPICE_PROTOCOL_CFLAGS
+ C compiler flags for SPICE_PROTOCOL, overriding pkg-config
+ SPICE_PROTOCOL_LIBS
+ linker flags for SPICE_PROTOCOL, overriding pkg-config
+ PIXMAN_CFLAGS
+ C compiler flags for PIXMAN, overriding pkg-config
+ PIXMAN_LIBS linker flags for PIXMAN, overriding pkg-config
+ SSL_CFLAGS C compiler flags for SSL, overriding pkg-config
+ SSL_LIBS linker flags for SSL, overriding pkg-config
+ SASL_CFLAGS C compiler flags for SASL, overriding pkg-config
+ SASL_LIBS linker flags for SASL, overriding pkg-config
+ GTK_CFLAGS C compiler flags for GTK, overriding pkg-config
+ GTK_LIBS linker flags for GTK, overriding pkg-config
+ X11_CFLAGS C compiler flags for X11, overriding pkg-config
+ X11_LIBS linker flags for X11, overriding pkg-config
+ GLIB2_CFLAGS
+ C compiler flags for GLIB2, overriding pkg-config
+ GLIB2_LIBS linker flags for GLIB2, overriding pkg-config
+ GOBJECT2_CFLAGS
+ C compiler flags for GOBJECT2, overriding pkg-config
+ GOBJECT2_LIBS
+ linker flags for GOBJECT2, overriding pkg-config
+ GIO_CFLAGS C compiler flags for GIO, overriding pkg-config
+ GIO_LIBS linker flags for GIO, overriding pkg-config
+ CAIRO_CFLAGS
+ C compiler flags for CAIRO, overriding pkg-config
+ CAIRO_LIBS linker flags for CAIRO, overriding pkg-config
+ GTHREAD_CFLAGS
+ C compiler flags for GTHREAD, overriding pkg-config
+ GTHREAD_LIBS
+ linker flags for GTHREAD, overriding pkg-config
+ PHODAV_CFLAGS
+ C compiler flags for PHODAV, overriding pkg-config
+ PHODAV_LIBS linker flags for PHODAV, overriding pkg-config
+ PULSE_CFLAGS
+ C compiler flags for PULSE, overriding pkg-config
+ PULSE_LIBS linker flags for PULSE, overriding pkg-config
+ GSTAUDIO_CFLAGS
+ C compiler flags for GSTAUDIO, overriding pkg-config
+ GSTAUDIO_LIBS
+ linker flags for GSTAUDIO, overriding pkg-config
+ GSTVIDEO_CFLAGS
+ C compiler flags for GSTVIDEO, overriding pkg-config
+ GSTVIDEO_LIBS
+ linker flags for GSTVIDEO, overriding pkg-config
+ SMARTCARD_CFLAGS
+ C compiler flags for SMARTCARD, overriding pkg-config
+ SMARTCARD_LIBS
+ linker flags for SMARTCARD, overriding pkg-config
+ USBREDIR_CFLAGS
+ C compiler flags for USBREDIR, overriding pkg-config
+ USBREDIR_LIBS
+ linker flags for USBREDIR, overriding pkg-config
+ LIBUSB_HOTPLUG_CFLAGS
+ C compiler flags for LIBUSB_HOTPLUG, overriding pkg-config
+ LIBUSB_HOTPLUG_LIBS
+ linker flags for LIBUSB_HOTPLUG, overriding pkg-config
+ GUDEV_CFLAGS
+ C compiler flags for GUDEV, overriding pkg-config
+ GUDEV_LIBS linker flags for GUDEV, overriding pkg-config
+ POLKIT_CFLAGS
+ C compiler flags for POLKIT, overriding pkg-config
+ POLKIT_LIBS linker flags for POLKIT, overriding pkg-config
+ LZ4_CFLAGS C compiler flags for LZ4, overriding pkg-config
+ LZ4_LIBS linker flags for LZ4, overriding pkg-config
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <spice-devel@lists.freedesktop.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+spice-gtk configure 0.33
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------------------------ ##
+## Report this to spice-devel@lists.freedesktop.org ##
+## ------------------------------------------------ ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by spice-gtk $as_me 0.33, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args=$ac_configure_args" '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+# For autoconf < 2.63
+
+
+
+
+# SPICE_WARNING(warning)
+# SPICE_PRINT_MESSAGES
+# ----------------------
+# Collect warnings and print them at the end so they are clearly visible.
+# ---------------------
+
+
+
+
+# SPICE_CHECK_SYSDEPS()
+# ---------------------
+# Checks for header files and library functions needed by spice-common.
+# ---------------------
+
+
+
+# SPICE_CHECK_SMARTCARD
+# ---------------------
+# Adds a --enable-smartcard switch in order to enable/disable smartcard
+# support, and checks if the needed libraries are available. If found, it will
+# return the flags to use in the SMARTCARD_CFLAGS and SMARTCARD_LIBS variables, and
+# it will define a USE_SMARTCARD preprocessor symbol as well as a HAVE_SMARTCARD
+# Makefile conditional.
+#----------------------
+
+
+
+# SPICE_CHECK_CELT051
+# -------------------
+# Adds a --disable-celt051 switch in order to enable/disable CELT 0.5.1
+# support, and checks if the needed libraries are available. If found, it will
+# return the flags to use in the CELT051_CFLAGS and CELT051_LIBS variables, and
+# it will define a HAVE_CELT051 preprocessor symbol as well as a HAVE_CELT051
+# Makefile conditional.
+#--------------------
+
+
+
+# SPICE_CHECK_OPUS
+# ----------------
+# Check for the availability of Opus. If found, it will return the flags to use
+# in the OPUS_CFLAGS and OPUS_LIBS variables, and it will define a
+# HAVE_OPUS preprocessor symbol as well as a HAVE_OPUS Makefile conditional.
+# ----------------
+
+
+
+# SPICE_CHECK_PIXMAN
+# ------------------
+# Check for the availability of pixman. If found, it will return the flags to
+# use in the PIXMAN_CFLAGS and PIXMAN_LIBS variables.
+#-------------------
+
+
+
+# SPICE_CHECK_GLIB2
+# -----------------
+# Check for the availability of glib2. If found, it will return the flags to
+# use in the GLIB2_CFLAGS and GLIB2_LIBS variables.
+#------------------
+
+
+# SPICE_CHECK_PYTHON_MODULES()
+# --------------------------
+# Adds a --enable-python-checks configure flags as well as checks for the
+# availability of the python modules needed by the python scripts generating
+# C code from spice.proto. These checks are not needed when building from
+# tarballs so they are disabled by default.
+#---------------------------
+
+
+
+# SPICE_CHECK_LZ4
+# ---------------
+# Adds a --enable-lz4 switch in order to enable/disable LZ4 compression
+# support, and checks if the needed libraries are available. If found, it will
+# return the flags to use in the LZ4_CFLAGS and LZ4_LIBS variables, and
+# it will define a USE_LZ4 preprocessor symbol.
+# conditional.
+# ---------------
+
+
+
+# SPICE_CHECK_GSTREAMER(VAR, version, packages-to-check-for, [action-if-found, [action-if-not-found]])
+# ---------------------
+# Checks whether the specified GStreamer modules are present and sets the
+# corresponding autoconf variables and preprocessor definitions.
+# ---------------------
+
+
+# SPICE_CHECK_GSTREAMER_ELEMENTS(gst-inspect, package, elements-to-check-for)
+# ---------------------
+# Checks that the specified GStreamer elements are installed. If not it
+# issues a warning and sets missing_gstreamer_elements.
+# ---------------------
+
+
+# SPICE_CHECK_SASL
+# ----------------
+# Adds a --with-sasl switch to allow using SASL for authentication.
+# Checks whether the required library is available. If it is present,
+# it will return the flags to use in SASL_CFLAGS and SASL_LIBS variables,
+# and it will define a have_sasl configure variable and a HAVE_SASL preprocessor
+# symbol.
+# ----------------
+
+
+# SPICE_CHECK_OPENSSL
+# -----------------
+# Check for the availability of openssl. If found, it will return the flags to
+# use in the OPENSSL_CFLAGS and OPENSSL_LIBS variables.
+#------------------
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+ac_aux_dir=
+for ac_dir in build-aux "$srcdir"/build-aux; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+am__api_version='1.15'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='spice-gtk'
+ VERSION='0.33'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+ fi
+fi
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar lib "link -lib"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar lib "link -lib"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ am_cv_ar_interface=ar
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+ (eval $am_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=ar
+ else
+ am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+ (eval $am_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=lib
+ else
+ am_cv_ar_interface=unknown
+ fi
+ fi
+ rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+ ;;
+lib)
+ # Microsoft lib, so override with the ar-lib wrapper script.
+ # FIXME: It is wrong to rewrite AR.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__AR in this case,
+ # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+ # similar.
+ AR="$am_aux_dir/ar-lib $AR"
+ ;;
+unknown)
+ as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+ ;;
+esac
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.6'
+macro_revision='2.4.6'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case $ECHO in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi
+fi
+
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+os2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
+$as_echo "$with_sysroot" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
+$as_echo_n "checking for a working dd... " >&6; }
+if ${ac_cv_path_lt_DD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+if test -z "$lt_DD"; then
+ ac_path_lt_DD_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in dd; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_lt_DD" || continue
+if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi
+ $ac_path_lt_DD_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_lt_DD"; then
+ :
+ fi
+else
+ ac_cv_path_lt_DD=$lt_DD
+fi
+
+rm -f conftest.i conftest2.i conftest.out
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
+$as_echo "$ac_cv_path_lt_DD" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
+$as_echo_n "checking how to truncate binary pipes... " >&6; }
+if ${lt_cv_truncate_bin+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
+$as_echo "$lt_cv_truncate_bin" >&6; }
+
+
+
+
+
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[012][,.]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+# Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_static=no
+fi
+
+
+
+
+
+
+
+enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AS=$ac_cv_prog_AS
+if test -n "$AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
+$as_echo "$AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AS"; then
+ ac_ct_AS=$AS
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AS"; then
+ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AS="as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AS=$ac_cv_prog_ac_ct_AS
+if test -n "$ac_ct_AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5
+$as_echo "$ac_ct_AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AS" = x; then
+ AS="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AS=$ac_ct_AS
+ fi
+else
+ AS="$ac_cv_prog_AS"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+ ;;
+esac
+
+test -z "$AS" && AS=as
+
+
+
+
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+ enable_dlopen=no
+
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ pic_mode=default
+fi
+
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+ shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[5-9]*,yes)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
+$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
+
+# Check whether --with-aix-soname was given.
+if test "${with_aix_soname+set}" = set; then :
+ withval=$with_aix_soname; case $withval in
+ aix|svr4|both)
+ ;;
+ *)
+ as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5
+ ;;
+ esac
+ lt_cv_with_aix_soname=$with_aix_soname
+else
+ if ${lt_cv_with_aix_soname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_with_aix_soname=aix
+fi
+
+ with_aix_soname=$lt_cv_with_aix_soname
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
+$as_echo "$with_aix_soname" >&6; }
+ if test aix != "$with_aix_soname"; then
+ # For the AIX way of multilib, we name the shared archive member
+ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+ # the AIX toolchain works better with OBJECT_MODE set (default 32).
+ if test 64 = "${OBJECT_MODE-32}"; then
+ shared_archive_member_spec=shr_64
+ else
+ shared_archive_member_spec=shr
+ fi
+ fi
+ ;;
+*)
+ with_aix_soname=aix
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+func_cc_basename $compiler
+cc_basename=$func_cc_basename_result
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/${ac_tool_prefix}file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC=$CC
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test yes = "$GCC"; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static='$wl-static'
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static='$wl-static'
+ ;;
+ esac
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_pic_works"; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_static_works"; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links=nottested
+if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test no = "$hard_links"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ export_dynamic_flag_spec='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='$wl--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ shrext_cmds=.dll
+ archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ tcc*)
+ export_dynamic_flag_spec='-rdynamic'
+ ;;
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test no = "$ld_shlibs"; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # traditional, no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ ;;
+ esac
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ export_dynamic_flag_spec='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' $wl-bernotok'
+ allow_undefined_flag=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test yes = "$lt_cv_prog_compiler__b"; then
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ linux*)
+ case $cc_basename in
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ ld_shlibs=yes
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ else
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ shrext_cmds=.dll
+ archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='$wl-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='$wl-z,text'
+ allow_undefined_flag='$wl-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test no = "$ld_shlibs" && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a(lib.so.V)'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Add ABI-specific directories to the system library path.
+ sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test yes = "$hardcode_automatic"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$hardcode_direct" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
+ test no != "$hardcode_minus_L"; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test relink = "$hardcode_action" ||
+ test yes = "$inherit_rpath"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report what library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC=$lt_save_CC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5
+$as_echo_n "checking whether NLS is requested... " >&6; }
+ # Check whether --enable-nls was given.
+if test "${enable_nls+set}" = set; then :
+ enableval=$enable_nls; USE_NLS=$enableval
+else
+ USE_NLS=yes
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5
+$as_echo "$USE_NLS" >&6; }
+
+
+
+
+case "$am__api_version" in
+ 1.01234)
+ as_fn_error $? "Automake 1.5 or newer is required to use intltool" "$LINENO" 5
+ ;;
+ *)
+ ;;
+esac
+
+INTLTOOL_REQUIRED_VERSION_AS_INT=`echo 0.40.0 | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'`
+INTLTOOL_APPLIED_VERSION=`intltool-update --version | head -1 | cut -d" " -f3`
+INTLTOOL_APPLIED_VERSION_AS_INT=`echo $INTLTOOL_APPLIED_VERSION | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'`
+if test -n "0.40.0"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intltool >= 0.40.0" >&5
+$as_echo_n "checking for intltool >= 0.40.0... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_APPLIED_VERSION found" >&5
+$as_echo "$INTLTOOL_APPLIED_VERSION found" >&6; }
+ test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT" ||
+ as_fn_error $? "Your intltool is too old. You need intltool 0.40.0 or later." "$LINENO" 5
+fi
+
+# Extract the first word of "intltool-update", so it can be a program name with args.
+set dummy intltool-update; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_INTLTOOL_UPDATE+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $INTLTOOL_UPDATE in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_INTLTOOL_UPDATE="$INTLTOOL_UPDATE" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_INTLTOOL_UPDATE="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+INTLTOOL_UPDATE=$ac_cv_path_INTLTOOL_UPDATE
+if test -n "$INTLTOOL_UPDATE"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_UPDATE" >&5
+$as_echo "$INTLTOOL_UPDATE" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "intltool-merge", so it can be a program name with args.
+set dummy intltool-merge; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_INTLTOOL_MERGE+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $INTLTOOL_MERGE in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_INTLTOOL_MERGE="$INTLTOOL_MERGE" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_INTLTOOL_MERGE="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+INTLTOOL_MERGE=$ac_cv_path_INTLTOOL_MERGE
+if test -n "$INTLTOOL_MERGE"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_MERGE" >&5
+$as_echo "$INTLTOOL_MERGE" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "intltool-extract", so it can be a program name with args.
+set dummy intltool-extract; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_INTLTOOL_EXTRACT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $INTLTOOL_EXTRACT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_INTLTOOL_EXTRACT="$INTLTOOL_EXTRACT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_INTLTOOL_EXTRACT="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+INTLTOOL_EXTRACT=$ac_cv_path_INTLTOOL_EXTRACT
+if test -n "$INTLTOOL_EXTRACT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_EXTRACT" >&5
+$as_echo "$INTLTOOL_EXTRACT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test -z "$INTLTOOL_UPDATE" -o -z "$INTLTOOL_MERGE" -o -z "$INTLTOOL_EXTRACT"; then
+ as_fn_error $? "The intltool scripts were not found. Please install intltool." "$LINENO" 5
+fi
+
+if test -z "$AM_DEFAULT_VERBOSITY"; then
+ AM_DEFAULT_VERBOSITY=1
+fi
+
+
+INTLTOOL_V_MERGE='$(INTLTOOL__v_MERGE_$(V))'
+INTLTOOL__v_MERGE_='$(INTLTOOL__v_MERGE_$(AM_DEFAULT_VERBOSITY))'
+INTLTOOL__v_MERGE_0='@echo " ITMRG " $@;'
+
+
+
+
+INTLTOOL_V_MERGE_OPTIONS='$(intltool__v_merge_options_$(V))'
+intltool__v_merge_options_='$(intltool__v_merge_options_$(AM_DEFAULT_VERBOSITY))'
+intltool__v_merge_options_0='-q'
+
+
+
+
+ INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -o -p $(top_srcdir)/po $< $@'
+ INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+if test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge 5000; then
+ INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u --no-translations $< $@'
+else
+ INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; $(INTLTOOL_V_MERGE)_it_tmp_dir=tmp.intltool.$$RANDOM && mkdir $$_it_tmp_dir && LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u $$_it_tmp_dir $< $@ && rmdir $$_it_tmp_dir'
+fi
+ INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_SERVICE_RULE='%.service: %.service.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+ INTLTOOL_POLICY_RULE='%.policy: %.policy.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check the gettext tools to make sure they are GNU
+# Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_XGETTEXT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $XGETTEXT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_XGETTEXT="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+XGETTEXT=$ac_cv_path_XGETTEXT
+if test -n "$XGETTEXT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5
+$as_echo "$XGETTEXT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "msgmerge", so it can be a program name with args.
+set dummy msgmerge; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MSGMERGE+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MSGMERGE in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MSGMERGE="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MSGMERGE=$ac_cv_path_MSGMERGE
+if test -n "$MSGMERGE"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5
+$as_echo "$MSGMERGE" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MSGFMT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MSGFMT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MSGFMT="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MSGFMT=$ac_cv_path_MSGFMT
+if test -n "$MSGFMT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5
+$as_echo "$MSGFMT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GMSGFMT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GMSGFMT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT=$ac_cv_path_GMSGFMT
+if test -n "$GMSGFMT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5
+$as_echo "$GMSGFMT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test -z "$XGETTEXT" -o -z "$MSGMERGE" -o -z "$MSGFMT"; then
+ as_fn_error $? "GNU gettext tools not found; required for intltool" "$LINENO" 5
+fi
+xgversion="`$XGETTEXT --version|grep '(GNU ' 2> /dev/null`"
+mmversion="`$MSGMERGE --version|grep '(GNU ' 2> /dev/null`"
+mfversion="`$MSGFMT --version|grep '(GNU ' 2> /dev/null`"
+if test -z "$xgversion" -o -z "$mmversion" -o -z "$mfversion"; then
+ as_fn_error $? "GNU gettext tools not found; required for intltool" "$LINENO" 5
+fi
+
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_INTLTOOL_PERL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $INTLTOOL_PERL in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_INTLTOOL_PERL="$INTLTOOL_PERL" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_INTLTOOL_PERL="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+INTLTOOL_PERL=$ac_cv_path_INTLTOOL_PERL
+if test -n "$INTLTOOL_PERL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INTLTOOL_PERL" >&5
+$as_echo "$INTLTOOL_PERL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test -z "$INTLTOOL_PERL"; then
+ as_fn_error $? "perl not found" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl >= 5.8.1" >&5
+$as_echo_n "checking for perl >= 5.8.1... " >&6; }
+$INTLTOOL_PERL -e "use 5.8.1;" > /dev/null 2>&1
+if test $? -ne 0; then
+ as_fn_error $? "perl 5.8.1 is required for intltool" "$LINENO" 5
+else
+ IT_PERL_VERSION=`$INTLTOOL_PERL -e "printf '%vd', $^V"`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $IT_PERL_VERSION" >&5
+$as_echo "$IT_PERL_VERSION" >&6; }
+fi
+if test "x" != "xno-xml"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML::Parser" >&5
+$as_echo_n "checking for XML::Parser... " >&6; }
+ if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+ else
+ as_fn_error $? "XML::Parser perl module is required for intltool" "$LINENO" 5
+ fi
+fi
+
+# Substitute ALL_LINGUAS so we can use it in po/Makefile
+
+
+
+
+
+GETTEXT_PACKAGE=spice-gtk
+
+
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE "$GETTEXT_PACKAGE"
+_ACEOF
+
+
+ for ac_header in locale.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default"
+if test "x$ac_cv_header_locale_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LOCALE_H 1
+_ACEOF
+
+fi
+
+done
+
+ if test $ac_cv_header_locale_h = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LC_MESSAGES" >&5
+$as_echo_n "checking for LC_MESSAGES... " >&6; }
+if ${am_cv_val_LC_MESSAGES+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <locale.h>
+int
+main ()
+{
+return LC_MESSAGES
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ am_cv_val_LC_MESSAGES=yes
+else
+ am_cv_val_LC_MESSAGES=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_val_LC_MESSAGES" >&5
+$as_echo "$am_cv_val_LC_MESSAGES" >&6; }
+ if test $am_cv_val_LC_MESSAGES = yes; then
+
+$as_echo "#define HAVE_LC_MESSAGES 1" >>confdefs.h
+
+ fi
+ fi
+ USE_NLS=yes
+
+
+ gt_cv_have_gettext=no
+
+ CATOBJEXT=NONE
+ XGETTEXT=:
+ INTLLIBS=
+
+ ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default"
+if test "x$ac_cv_header_libintl_h" = xyes; then :
+ gt_cv_func_dgettext_libintl="no"
+ libintl_extra_libs=""
+
+ #
+ # First check in libc
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ngettext in libc" >&5
+$as_echo_n "checking for ngettext in libc... " >&6; }
+if ${gt_cv_func_ngettext_libc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <libintl.h>
+
+int
+main ()
+{
+return !ngettext ("","", 1)
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gt_cv_func_ngettext_libc=yes
+else
+ gt_cv_func_ngettext_libc=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_ngettext_libc" >&5
+$as_echo "$gt_cv_func_ngettext_libc" >&6; }
+
+ if test "$gt_cv_func_ngettext_libc" = "yes" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dgettext in libc" >&5
+$as_echo_n "checking for dgettext in libc... " >&6; }
+if ${gt_cv_func_dgettext_libc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <libintl.h>
+
+int
+main ()
+{
+return !dgettext ("","")
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gt_cv_func_dgettext_libc=yes
+else
+ gt_cv_func_dgettext_libc=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_dgettext_libc" >&5
+$as_echo "$gt_cv_func_dgettext_libc" >&6; }
+ fi
+
+ if test "$gt_cv_func_ngettext_libc" = "yes" ; then
+ for ac_func in bind_textdomain_codeset
+do :
+ ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset"
+if test "x$ac_cv_func_bind_textdomain_codeset" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_BIND_TEXTDOMAIN_CODESET 1
+_ACEOF
+
+fi
+done
+
+ fi
+
+ #
+ # If we don't have everything we want, check in libintl
+ #
+ if test "$gt_cv_func_dgettext_libc" != "yes" \
+ || test "$gt_cv_func_ngettext_libc" != "yes" \
+ || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bindtextdomain in -lintl" >&5
+$as_echo_n "checking for bindtextdomain in -lintl... " >&6; }
+if ${ac_cv_lib_intl_bindtextdomain+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char bindtextdomain ();
+int
+main ()
+{
+return bindtextdomain ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_intl_bindtextdomain=yes
+else
+ ac_cv_lib_intl_bindtextdomain=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_bindtextdomain" >&5
+$as_echo "$ac_cv_lib_intl_bindtextdomain" >&6; }
+if test "x$ac_cv_lib_intl_bindtextdomain" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ngettext in -lintl" >&5
+$as_echo_n "checking for ngettext in -lintl... " >&6; }
+if ${ac_cv_lib_intl_ngettext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ngettext ();
+int
+main ()
+{
+return ngettext ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_intl_ngettext=yes
+else
+ ac_cv_lib_intl_ngettext=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_ngettext" >&5
+$as_echo "$ac_cv_lib_intl_ngettext" >&6; }
+if test "x$ac_cv_lib_intl_ngettext" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dgettext in -lintl" >&5
+$as_echo_n "checking for dgettext in -lintl... " >&6; }
+if ${ac_cv_lib_intl_dgettext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dgettext ();
+int
+main ()
+{
+return dgettext ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_intl_dgettext=yes
+else
+ ac_cv_lib_intl_dgettext=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_dgettext" >&5
+$as_echo "$ac_cv_lib_intl_dgettext" >&6; }
+if test "x$ac_cv_lib_intl_dgettext" = xyes; then :
+ gt_cv_func_dgettext_libintl=yes
+fi
+
+fi
+
+fi
+
+
+ if test "$gt_cv_func_dgettext_libintl" != "yes" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -liconv is needed to use gettext" >&5
+$as_echo_n "checking if -liconv is needed to use gettext... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ngettext in -lintl" >&5
+$as_echo_n "checking for ngettext in -lintl... " >&6; }
+if ${ac_cv_lib_intl_ngettext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl -liconv $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ngettext ();
+int
+main ()
+{
+return ngettext ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_intl_ngettext=yes
+else
+ ac_cv_lib_intl_ngettext=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_ngettext" >&5
+$as_echo "$ac_cv_lib_intl_ngettext" >&6; }
+if test "x$ac_cv_lib_intl_ngettext" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dcgettext in -lintl" >&5
+$as_echo_n "checking for dcgettext in -lintl... " >&6; }
+if ${ac_cv_lib_intl_dcgettext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl -liconv $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dcgettext ();
+int
+main ()
+{
+return dcgettext ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_intl_dcgettext=yes
+else
+ ac_cv_lib_intl_dcgettext=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_dcgettext" >&5
+$as_echo "$ac_cv_lib_intl_dcgettext" >&6; }
+if test "x$ac_cv_lib_intl_dcgettext" = xyes; then :
+ gt_cv_func_dgettext_libintl=yes
+ libintl_extra_libs=-liconv
+else
+ :
+fi
+
+else
+ :
+fi
+
+ fi
+
+ #
+ # If we found libintl, then check in it for bind_textdomain_codeset();
+ # we'll prefer libc if neither have bind_textdomain_codeset(),
+ # and both have dgettext and ngettext
+ #
+ if test "$gt_cv_func_dgettext_libintl" = "yes" ; then
+ glib_save_LIBS="$LIBS"
+ LIBS="$LIBS -lintl $libintl_extra_libs"
+ unset ac_cv_func_bind_textdomain_codeset
+ for ac_func in bind_textdomain_codeset
+do :
+ ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset"
+if test "x$ac_cv_func_bind_textdomain_codeset" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_BIND_TEXTDOMAIN_CODESET 1
+_ACEOF
+
+fi
+done
+
+ LIBS="$glib_save_LIBS"
+
+ if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then
+ gt_cv_func_dgettext_libc=no
+ else
+ if test "$gt_cv_func_dgettext_libc" = "yes" \
+ && test "$gt_cv_func_ngettext_libc" = "yes"; then
+ gt_cv_func_dgettext_libintl=no
+ fi
+ fi
+ fi
+ fi
+
+ if test "$gt_cv_func_dgettext_libc" = "yes" \
+ || test "$gt_cv_func_dgettext_libintl" = "yes"; then
+ gt_cv_have_gettext=yes
+ fi
+
+ if test "$gt_cv_func_dgettext_libintl" = "yes"; then
+ INTLLIBS="-lintl $libintl_extra_libs"
+ fi
+
+ if test "$gt_cv_have_gettext" = "yes"; then
+
+$as_echo "#define HAVE_GETTEXT 1" >>confdefs.h
+
+ # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MSGFMT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case "$MSGFMT" in
+ /*)
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+ ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test "$MSGFMT" != "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5
+$as_echo "$MSGFMT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+ if test "$MSGFMT" != "no"; then
+ glib_save_LIBS="$LIBS"
+ LIBS="$LIBS $INTLLIBS"
+ for ac_func in dcgettext
+do :
+ ac_fn_c_check_func "$LINENO" "dcgettext" "ac_cv_func_dcgettext"
+if test "x$ac_cv_func_dcgettext" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DCGETTEXT 1
+_ACEOF
+
+fi
+done
+
+ MSGFMT_OPTS=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if msgfmt accepts -c" >&5
+$as_echo_n "checking if msgfmt accepts -c... " >&6; }
+ cat >conftest.foo <<_ACEOF
+
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: test 1.0\n"
+"PO-Revision-Date: 2007-02-15 12:01+0100\n"
+"Last-Translator: test <foo@bar.xx>\n"
+"Language-Team: C <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+_ACEOF
+if { { $as_echo "$as_me:${as_lineno-$LINENO}: \$MSGFMT -c -o /dev/null conftest.foo"; } >&5
+ ($MSGFMT -c -o /dev/null conftest.foo) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ MSGFMT_OPTS=-c; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+echo "$as_me: failed input was:" >&5
+sed 's/^/| /' conftest.foo >&5
+fi
+
+ # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GMSGFMT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GMSGFMT in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+ ;;
+esac
+fi
+GMSGFMT=$ac_cv_path_GMSGFMT
+if test -n "$GMSGFMT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5
+$as_echo "$GMSGFMT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_XGETTEXT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case "$XGETTEXT" in
+ /*)
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+ ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test "$XGETTEXT" != ":"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5
+$as_echo "$XGETTEXT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ case $host in
+ *-*-solaris*)
+ ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset"
+if test "x$ac_cv_func_bind_textdomain_codeset" = xyes; then :
+ CATOBJEXT=.gmo
+ DATADIRNAME=share
+else
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+fi
+
+ ;;
+ *-*-openbsd*)
+ CATOBJEXT=.mo
+ DATADIRNAME=share
+ ;;
+ *)
+ CATOBJEXT=.mo
+ DATADIRNAME=lib
+ ;;
+ esac
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$glib_save_LIBS"
+ INSTOBJEXT=.mo
+ else
+ gt_cv_have_gettext=no
+ fi
+ fi
+
+fi
+
+
+
+ if test "$gt_cv_have_gettext" = "yes" ; then
+
+$as_echo "#define ENABLE_NLS 1" >>confdefs.h
+
+ fi
+
+ if test "$XGETTEXT" != ":"; then
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found xgettext program is not GNU xgettext; ignore it" >&5
+$as_echo "found xgettext program is not GNU xgettext; ignore it" >&6; }
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+
+ ac_config_commands="$ac_config_commands default-1"
+
+
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+
+
+
+
+
+
+
+
+
+
+
+
+ if test "$gt_cv_have_gettext" = "yes"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for catalogs to be installed" >&5
+$as_echo_n "checking for catalogs to be installed... " >&6; }
+ NEW_LINGUAS=
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ NEW_LINGUAS="$NEW_LINGUAS $presentlang"
+ fi
+ done
+ LINGUAS=$NEW_LINGUAS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINGUAS" >&5
+$as_echo "$LINGUAS" >&6; }
+ fi
+
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ MKINSTALLDIRS=
+ if test -n "$ac_aux_dir"; then
+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
+ fi
+ if test -z "$MKINSTALLDIRS"; then
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+ fi
+
+
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+
+
+
+SPICE_GTK_LOCALEDIR=${datadir}/locale
+
+
+
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+ ac_pt_PKG_CONFIG=$PKG_CONFIG
+ # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_PKG_CONFIG" = x; then
+ PKG_CONFIG=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ PKG_CONFIG=$ac_pt_PKG_CONFIG
+ fi
+else
+ PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=0.9.0
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ PKG_CONFIG=""
+ fi
+fi
+
+
+
+ gtk_doc_requires="gtk-doc >= 1.14"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtk-doc" >&5
+$as_echo_n "checking for gtk-doc... " >&6; }
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$gtk_doc_requires\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "$gtk_doc_requires") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ have_gtk_doc=yes
+else
+ have_gtk_doc=no
+fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gtk_doc" >&5
+$as_echo "$have_gtk_doc" >&6; }
+
+ if test "$have_gtk_doc" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+ You will not be able to create source packages with 'make dist'
+ because $gtk_doc_requires is not found." >&5
+$as_echo "$as_me: WARNING:
+ You will not be able to create source packages with 'make dist'
+ because $gtk_doc_requires is not found." >&2;}
+ fi
+
+ # Extract the first word of "gtkdoc-check", so it can be a program name with args.
+set dummy gtkdoc-check; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_GTKDOC_CHECK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$GTKDOC_CHECK"; then
+ ac_cv_prog_GTKDOC_CHECK="$GTKDOC_CHECK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_GTKDOC_CHECK="gtkdoc-check.test"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+GTKDOC_CHECK=$ac_cv_prog_GTKDOC_CHECK
+if test -n "$GTKDOC_CHECK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTKDOC_CHECK" >&5
+$as_echo "$GTKDOC_CHECK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ # Extract the first word of "gtkdoc-check", so it can be a program name with args.
+set dummy gtkdoc-check; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GTKDOC_CHECK_PATH+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GTKDOC_CHECK_PATH in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GTKDOC_CHECK_PATH="$GTKDOC_CHECK_PATH" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GTKDOC_CHECK_PATH="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+GTKDOC_CHECK_PATH=$ac_cv_path_GTKDOC_CHECK_PATH
+if test -n "$GTKDOC_CHECK_PATH"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTKDOC_CHECK_PATH" >&5
+$as_echo "$GTKDOC_CHECK_PATH" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ for ac_prog in gtkdoc-rebase
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GTKDOC_REBASE+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GTKDOC_REBASE in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GTKDOC_REBASE="$GTKDOC_REBASE" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GTKDOC_REBASE="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+GTKDOC_REBASE=$ac_cv_path_GTKDOC_REBASE
+if test -n "$GTKDOC_REBASE"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTKDOC_REBASE" >&5
+$as_echo "$GTKDOC_REBASE" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$GTKDOC_REBASE" && break
+done
+test -n "$GTKDOC_REBASE" || GTKDOC_REBASE="true"
+
+ # Extract the first word of "gtkdoc-mkpdf", so it can be a program name with args.
+set dummy gtkdoc-mkpdf; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GTKDOC_MKPDF+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GTKDOC_MKPDF in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GTKDOC_MKPDF="$GTKDOC_MKPDF" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GTKDOC_MKPDF="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+GTKDOC_MKPDF=$ac_cv_path_GTKDOC_MKPDF
+if test -n "$GTKDOC_MKPDF"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTKDOC_MKPDF" >&5
+$as_echo "$GTKDOC_MKPDF" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+# Check whether --with-html-dir was given.
+if test "${with_html_dir+set}" = set; then :
+ withval=$with_html_dir;
+else
+ with_html_dir='${datadir}/gtk-doc/html'
+fi
+
+ HTML_DIR="$with_html_dir"
+
+
+ # Check whether --enable-gtk-doc was given.
+if test "${enable_gtk_doc+set}" = set; then :
+ enableval=$enable_gtk_doc;
+else
+ enable_gtk_doc=no
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build gtk-doc documentation" >&5
+$as_echo_n "checking whether to build gtk-doc documentation... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_gtk_doc" >&5
+$as_echo "$enable_gtk_doc" >&6; }
+
+ if test "x$enable_gtk_doc" = "xyes" && test "$have_gtk_doc" = "no"; then
+ as_fn_error $? "
+ You must have $gtk_doc_requires installed to build documentation for
+ $PACKAGE_NAME. Please install gtk-doc or disable building the
+ documentation by adding '--disable-gtk-doc' to '$0'." "$LINENO" 5
+ fi
+
+ if test "x$PACKAGE_NAME" != "xglib"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTKDOC_DEPS" >&5
+$as_echo_n "checking for GTKDOC_DEPS... " >&6; }
+
+if test -n "$GTKDOC_DEPS_CFLAGS"; then
+ pkg_cv_GTKDOC_DEPS_CFLAGS="$GTKDOC_DEPS_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GTKDOC_DEPS_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GTKDOC_DEPS_LIBS"; then
+ pkg_cv_GTKDOC_DEPS_LIBS="$GTKDOC_DEPS_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GTKDOC_DEPS_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GTKDOC_DEPS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0" 2>&1`
+ else
+ GTKDOC_DEPS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GTKDOC_DEPS_PKG_ERRORS" >&5
+
+ :
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ :
+else
+ GTKDOC_DEPS_CFLAGS=$pkg_cv_GTKDOC_DEPS_CFLAGS
+ GTKDOC_DEPS_LIBS=$pkg_cv_GTKDOC_DEPS_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+ fi
+
+ # Check whether --enable-gtk-doc-html was given.
+if test "${enable_gtk_doc_html+set}" = set; then :
+ enableval=$enable_gtk_doc_html;
+else
+ enable_gtk_doc_html=yes
+fi
+
+ # Check whether --enable-gtk-doc-pdf was given.
+if test "${enable_gtk_doc_pdf+set}" = set; then :
+ enableval=$enable_gtk_doc_pdf;
+else
+ enable_gtk_doc_pdf=no
+fi
+
+
+ if test -z "$GTKDOC_MKPDF"; then
+ enable_gtk_doc_pdf=no
+ fi
+
+ if test -z "$AM_DEFAULT_VERBOSITY"; then
+ AM_DEFAULT_VERBOSITY=1
+ fi
+
+
+ if test x$have_gtk_doc = xyes; then
+ HAVE_GTK_DOC_TRUE=
+ HAVE_GTK_DOC_FALSE='#'
+else
+ HAVE_GTK_DOC_TRUE='#'
+ HAVE_GTK_DOC_FALSE=
+fi
+
+ if test x$enable_gtk_doc = xyes; then
+ ENABLE_GTK_DOC_TRUE=
+ ENABLE_GTK_DOC_FALSE='#'
+else
+ ENABLE_GTK_DOC_TRUE='#'
+ ENABLE_GTK_DOC_FALSE=
+fi
+
+ if test x$enable_gtk_doc_html = xyes; then
+ GTK_DOC_BUILD_HTML_TRUE=
+ GTK_DOC_BUILD_HTML_FALSE='#'
+else
+ GTK_DOC_BUILD_HTML_TRUE='#'
+ GTK_DOC_BUILD_HTML_FALSE=
+fi
+
+ if test x$enable_gtk_doc_pdf = xyes; then
+ GTK_DOC_BUILD_PDF_TRUE=
+ GTK_DOC_BUILD_PDF_FALSE='#'
+else
+ GTK_DOC_BUILD_PDF_TRUE='#'
+ GTK_DOC_BUILD_PDF_FALSE=
+fi
+
+ if test -n "$LIBTOOL"; then
+ GTK_DOC_USE_LIBTOOL_TRUE=
+ GTK_DOC_USE_LIBTOOL_FALSE='#'
+else
+ GTK_DOC_USE_LIBTOOL_TRUE='#'
+ GTK_DOC_USE_LIBTOOL_FALSE=
+fi
+
+ if test -n "$GTKDOC_REBASE"; then
+ GTK_DOC_USE_REBASE_TRUE=
+ GTK_DOC_USE_REBASE_FALSE='#'
+else
+ GTK_DOC_USE_REBASE_TRUE='#'
+ GTK_DOC_USE_REBASE_FALSE=
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
+$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
+if ${ac_cv_prog_cc_c99+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros. These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+ int x = 1234;
+ int y = 5678;
+ debug ("Flag");
+ debug ("X = %d\n", x);
+ showlist (The first, second, and third items.);
+ report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+ your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+ your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+ int datasize;
+ double data[];
+};
+
+struct named_init {
+ int number;
+ const wchar_t *name;
+ double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+ // See if C++-style comments work.
+ // Iterate through items via the restricted pointer.
+ // Also check for declarations in for loops.
+ for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+ continue;
+ return 0;
+}
+
+// Check varargs and va_copy.
+static void
+test_varargs (const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ va_list args_copy;
+ va_copy (args_copy, args);
+
+ const char *str;
+ int number;
+ float fnumber;
+
+ while (*format)
+ {
+ switch (*format++)
+ {
+ case 's': // string
+ str = va_arg (args_copy, const char *);
+ break;
+ case 'd': // int
+ number = va_arg (args_copy, int);
+ break;
+ case 'f': // float
+ fnumber = va_arg (args_copy, double);
+ break;
+ default:
+ break;
+ }
+ }
+ va_end (args_copy);
+ va_end (args);
+}
+
+int
+main ()
+{
+
+ // Check bool.
+ _Bool success = false;
+
+ // Check restrict.
+ if (test_restrict ("String literal") == 0)
+ success = true;
+ char *restrict newvar = "Another string";
+
+ // Check varargs.
+ test_varargs ("s, d' f .", "string", 65, 34.234);
+ test_varargs_macros ();
+
+ // Check flexible array members.
+ struct incomplete_array *ia =
+ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+ ia->datasize = 10;
+ for (int i = 0; i < ia->datasize; ++i)
+ ia->data[i] = i * 1.234;
+
+ // Check named initializers.
+ struct named_init ni = {
+ .number = 34,
+ .name = L"Test wide string",
+ .average = 543.34343,
+ };
+
+ ni.number = 58;
+
+ int dynamic_array[ni.number];
+ dynamic_array[ni.number - 1] = 543;
+
+ // work around unused variable warnings
+ return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+ || dynamic_array[ni.number - 1] != 543);
+
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c99" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c99"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c99" != xno; then :
+
+fi
+
+
+if test "x$ac_cv_prog_cc_c99" = xno; then
+ as_fn_error $? "C99 compiler is required." "$LINENO" 5
+fi
+
+
+# Extract the first word of "stow", so it can be a program name with args.
+set dummy stow; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STOW+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STOW"; then
+ ac_cv_prog_STOW="$STOW" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STOW="yes"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_STOW" && ac_cv_prog_STOW="no"
+fi
+fi
+STOW=$ac_cv_prog_STOW
+if test -n "$STOW"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STOW" >&5
+$as_echo "$STOW" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "x$STOW" = "xyes" && test -d /usr/local/stow; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: *** Found /usr/local/stow: default install prefix set to /usr/local/stow/${PACKAGE_NAME} ***" >&5
+$as_echo "$as_me: *** Found /usr/local/stow: default install prefix set to /usr/local/stow/${PACKAGE_NAME} ***" >&6;}
+ ac_default_prefix="/usr/local/stow/${PACKAGE_NAME}"
+
+fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+for ac_prog in python2 python
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PYTHON+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PYTHON in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+PYTHON=$ac_cv_path_PYTHON
+if test -n "$PYTHON"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+$as_echo "$PYTHON" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$PYTHON" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if -Wl,--version-script works" >&5
+$as_echo_n "checking if -Wl,--version-script works... " >&6; }
+if ${rra_cv_ld_version_script+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map"
+ cat > conftest.map <<EOF
+VERSION_1 {
+ global:
+ sym;
+
+ local:
+ *;
+};
+EOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ rra_cv_ld_version_script=yes
+else
+ rra_cv_ld_version_script=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ rm -f conftest.map
+ LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rra_cv_ld_version_script" >&5
+$as_echo "$rra_cv_ld_version_script" >&6; }
+ if test x"$rra_cv_ld_version_script" = xyes; then
+ HAVE_LD_VERSION_SCRIPT_TRUE=
+ HAVE_LD_VERSION_SCRIPT_FALSE='#'
+else
+ HAVE_LD_VERSION_SCRIPT_TRUE='#'
+ HAVE_LD_VERSION_SCRIPT_FALSE=
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for native Win32" >&5
+$as_echo_n "checking for native Win32... " >&6; }
+case "$host_os" in
+ *mingw*|*cygwin*)
+ os_win32=yes
+ gio_os=gio-windows-2.0
+ red_target=Windows
+ ;;
+ *)
+ os_win32=no
+ gio_os=gio-unix-2.0
+ red_target=Unix
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $os_win32" >&5
+$as_echo "$os_win32" >&6; }
+ if test "$os_win32" = "yes"; then
+ OS_WIN32_TRUE=
+ OS_WIN32_FALSE='#'
+else
+ OS_WIN32_TRUE='#'
+ OS_WIN32_FALSE=
+fi
+
+
+for ac_header in sys/socket.h netinet/in.h arpa/inet.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+for ac_header in termios.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "termios.h" "ac_cv_header_termios_h" "$ac_includes_default"
+if test "x$ac_cv_header_termios_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_TERMIOS_H 1
+_ACEOF
+
+fi
+
+done
+
+
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _mwvalidcheckl in -lmw" >&5
+$as_echo_n "checking for _mwvalidcheckl in -lmw... " >&6; }
+if ${ac_cv_lib_mw__mwvalidcheckl+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmw $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char _mwvalidcheckl ();
+int
+main ()
+{
+return _mwvalidcheckl ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_mw__mwvalidcheckl=yes
+else
+ ac_cv_lib_mw__mwvalidcheckl=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mw__mwvalidcheckl" >&5
+$as_echo "$ac_cv_lib_mw__mwvalidcheckl" >&6; }
+if test "x$ac_cv_lib_mw__mwvalidcheckl" = xyes; then :
+ LIBM=-lmw
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5
+$as_echo_n "checking for cos in -lm... " >&6; }
+if ${ac_cv_lib_m_cos+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cos ();
+int
+main ()
+{
+return cos ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_cos=yes
+else
+ ac_cv_lib_m_cos=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5
+$as_echo "$ac_cv_lib_m_cos" >&6; }
+if test "x$ac_cv_lib_m_cos" = xyes; then :
+ LIBM="$LIBM -lm"
+fi
+
+ ;;
+*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5
+$as_echo_n "checking for cos in -lm... " >&6; }
+if ${ac_cv_lib_m_cos+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cos ();
+int
+main ()
+{
+return cos ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_m_cos=yes
+else
+ ac_cv_lib_m_cos=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5
+$as_echo "$ac_cv_lib_m_cos" >&6; }
+if test "x$ac_cv_lib_m_cos" = xyes; then :
+ LIBM=-lm
+fi
+
+ ;;
+esac
+
+
+
+
+
+
+subdirs="$subdirs spice-common"
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SPICE_PROTOCOL" >&5
+$as_echo_n "checking for SPICE_PROTOCOL... " >&6; }
+
+if test -n "$SPICE_PROTOCOL_CFLAGS"; then
+ pkg_cv_SPICE_PROTOCOL_CFLAGS="$SPICE_PROTOCOL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"spice-protocol >= 0.12.12\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "spice-protocol >= 0.12.12") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SPICE_PROTOCOL_CFLAGS=`$PKG_CONFIG --cflags "spice-protocol >= 0.12.12" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$SPICE_PROTOCOL_LIBS"; then
+ pkg_cv_SPICE_PROTOCOL_LIBS="$SPICE_PROTOCOL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"spice-protocol >= 0.12.12\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "spice-protocol >= 0.12.12") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SPICE_PROTOCOL_LIBS=`$PKG_CONFIG --libs "spice-protocol >= 0.12.12" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ SPICE_PROTOCOL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "spice-protocol >= 0.12.12" 2>&1`
+ else
+ SPICE_PROTOCOL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "spice-protocol >= 0.12.12" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$SPICE_PROTOCOL_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (spice-protocol >= 0.12.12) were not met:
+
+$SPICE_PROTOCOL_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables SPICE_PROTOCOL_CFLAGS
+and SPICE_PROTOCOL_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables SPICE_PROTOCOL_CFLAGS
+and SPICE_PROTOCOL_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ SPICE_PROTOCOL_CFLAGS=$pkg_cv_SPICE_PROTOCOL_CFLAGS
+ SPICE_PROTOCOL_LIBS=$pkg_cv_SPICE_PROTOCOL_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+COMMON_CFLAGS='-I${top_builddir}/spice-common/ -I${top_srcdir}/spice-common/ ${SPICE_PROTOCOL_CFLAGS}'
+
+
+SPICE_GTK_MAJOR_VERSION=`echo $PACKAGE_VERSION | cut -d. -f1`
+SPICE_GTK_MINOR_VERSION=`echo $PACKAGE_VERSION | cut -d. -f2`
+SPICE_GTK_MICRO_VERSION=`echo $PACKAGE_VERSION | cut -d. -f3 | cut -d- -f1`
+if test "x$SPICE_GTK_MICRO_VERSION" = "x"; then :
+ SPICE_GTK_MICRO_VERSION=0
+fi
+
+
+
+
+
+
+srcdir="$(dirname $0)"
+if test ! -e "$srcdir/src/vncdisplaykeymap_osx2xtkbd.c"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Text::CSV Perl module" >&5
+$as_echo_n "checking for Text::CSV Perl module... " >&6; }
+ perl -MText::CSV -e "" >/dev/null 2>&1
+ if test $? -ne 0 ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+ as_fn_error $? "Text::CSV Perl module is required to compile this package" "$LINENO" 5
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
+$as_echo "found" >&6; }
+fi
+
+SPICE_GLIB_REQUIRES=""
+SPICE_GTK_REQUIRES=""
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PIXMAN" >&5
+$as_echo_n "checking for PIXMAN... " >&6; }
+
+if test -n "$PIXMAN_CFLAGS"; then
+ pkg_cv_PIXMAN_CFLAGS="$PIXMAN_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"pixman-1 >= 0.17.7\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "pixman-1 >= 0.17.7") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PIXMAN_CFLAGS=`$PKG_CONFIG --cflags "pixman-1 >= 0.17.7" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$PIXMAN_LIBS"; then
+ pkg_cv_PIXMAN_LIBS="$PIXMAN_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"pixman-1 >= 0.17.7\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "pixman-1 >= 0.17.7") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PIXMAN_LIBS=`$PKG_CONFIG --libs "pixman-1 >= 0.17.7" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ PIXMAN_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "pixman-1 >= 0.17.7" 2>&1`
+ else
+ PIXMAN_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "pixman-1 >= 0.17.7" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$PIXMAN_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (pixman-1 >= 0.17.7) were not met:
+
+$PIXMAN_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables PIXMAN_CFLAGS
+and PIXMAN_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables PIXMAN_CFLAGS
+and PIXMAN_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ PIXMAN_CFLAGS=$pkg_cv_PIXMAN_CFLAGS
+ PIXMAN_LIBS=$pkg_cv_PIXMAN_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+SPICE_GLIB_REQUIRES="${SPICE_GLIB_REQUIRES} pixman-1 >= 0.17.7"
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL" >&5
+$as_echo_n "checking for SSL... " >&6; }
+
+if test -n "$SSL_CFLAGS"; then
+ pkg_cv_SSL_CFLAGS="$SSL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "openssl") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SSL_CFLAGS=`$PKG_CONFIG --cflags "openssl" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$SSL_LIBS"; then
+ pkg_cv_SSL_LIBS="$SSL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "openssl") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SSL_LIBS=`$PKG_CONFIG --libs "openssl" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ SSL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "openssl" 2>&1`
+ else
+ SSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "openssl" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$SSL_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (openssl) were not met:
+
+$SSL_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables SSL_CFLAGS
+and SSL_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables SSL_CFLAGS
+and SSL_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ SSL_CFLAGS=$pkg_cv_SSL_CFLAGS
+ SSL_LIBS=$pkg_cv_SSL_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+SPICE_GLIB_REQUIRES="${SPICE_GLIB_REQUIRES} openssl"
+
+
+
+# Check whether --with-sasl was given.
+if test "${with_sasl+set}" = set; then :
+ withval=$with_sasl;
+else
+ with_sasl="auto"
+fi
+
+
+ have_sasl=no
+ if test "x$with_sasl" != "xno"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SASL" >&5
+$as_echo_n "checking for SASL... " >&6; }
+
+if test -n "$SASL_CFLAGS"; then
+ pkg_cv_SASL_CFLAGS="$SASL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsasl2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libsasl2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SASL_CFLAGS=`$PKG_CONFIG --cflags "libsasl2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$SASL_LIBS"; then
+ pkg_cv_SASL_LIBS="$SASL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsasl2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libsasl2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SASL_LIBS=`$PKG_CONFIG --libs "libsasl2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ SASL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsasl2" 2>&1`
+ else
+ SASL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsasl2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$SASL_PKG_ERRORS" >&5
+
+ have_sasl=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_sasl=no
+else
+ SASL_CFLAGS=$pkg_cv_SASL_CFLAGS
+ SASL_LIBS=$pkg_cv_SASL_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_sasl=yes
+fi
+ if test "x$have_sasl" = "xno" && test "x$with_sasl" = "xyes"; then
+ as_fn_error $? "Cyrus SASL support requested but libsasl2 could not be found" "$LINENO" 5
+ fi
+ if test "x$have_sasl" = "xyes"; then
+
+$as_echo "#define HAVE_SASL 1" >>confdefs.h
+
+ fi
+ fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which gtk+ version to compile against" >&5
+$as_echo_n "checking which gtk+ version to compile against... " >&6; }
+
+# Check whether --with-gtk was given.
+if test "${with_gtk+set}" = set; then :
+ withval=$with_gtk; case "$with_gtk" in
+ 3.0) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_gtk" >&5
+$as_echo "$with_gtk" >&6; } ;;
+ no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; } ;;
+ *) as_fn_error $? "invalid gtk version specified" "$LINENO" 5 ;;
+ esac
+else
+ with_gtk=3.0
+fi
+
+
+case "$with_gtk" in
+ 3.0) GTK_REQUIRED=3.12
+ GTK_ENCODED_VERSION="GDK_VERSION_3_12"
+ ;;
+ no)
+ if test x$enable_gtk_doc = xyes; then :
+ as_fn_error $? "Without GTK+, gtk-doc must be disabled" "$LINENO" 5
+fi
+esac
+
+
+ if test "$with_gtk" != "no"; then
+ WITH_GTK_TRUE=
+ WITH_GTK_FALSE='#'
+else
+ WITH_GTK_TRUE='#'
+ WITH_GTK_FALSE=
+fi
+
+
+if test "x$with_gtk" != "xno"; then :
+ if test "x$os_win32" = "xyes"; then :
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK" >&5
+$as_echo_n "checking for GTK... " >&6; }
+
+if test -n "$GTK_CFLAGS"; then
+ pkg_cv_GTK_CFLAGS="$GTK_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-3.0 >= \$GTK_REQUIRED\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gtk+-3.0 >= $GTK_REQUIRED") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GTK_CFLAGS=`$PKG_CONFIG --cflags "gtk+-3.0 >= $GTK_REQUIRED" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GTK_LIBS"; then
+ pkg_cv_GTK_LIBS="$GTK_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-3.0 >= \$GTK_REQUIRED\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gtk+-3.0 >= $GTK_REQUIRED") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GTK_LIBS=`$PKG_CONFIG --libs "gtk+-3.0 >= $GTK_REQUIRED" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-3.0 >= $GTK_REQUIRED" 2>&1`
+ else
+ GTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-3.0 >= $GTK_REQUIRED" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GTK_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (gtk+-3.0 >= $GTK_REQUIRED) were not met:
+
+$GTK_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables GTK_CFLAGS
+and GTK_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables GTK_CFLAGS
+and GTK_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ GTK_CFLAGS=$pkg_cv_GTK_CFLAGS
+ GTK_LIBS=$pkg_cv_GTK_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+else
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK" >&5
+$as_echo_n "checking for GTK... " >&6; }
+
+if test -n "$GTK_CFLAGS"; then
+ pkg_cv_GTK_CFLAGS="$GTK_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-3.0 >= \$GTK_REQUIRED epoxy\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gtk+-3.0 >= $GTK_REQUIRED epoxy") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GTK_CFLAGS=`$PKG_CONFIG --cflags "gtk+-3.0 >= $GTK_REQUIRED epoxy" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GTK_LIBS"; then
+ pkg_cv_GTK_LIBS="$GTK_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-3.0 >= \$GTK_REQUIRED epoxy\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gtk+-3.0 >= $GTK_REQUIRED epoxy") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GTK_LIBS=`$PKG_CONFIG --libs "gtk+-3.0 >= $GTK_REQUIRED epoxy" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gtk+-3.0 >= $GTK_REQUIRED epoxy" 2>&1`
+ else
+ GTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gtk+-3.0 >= $GTK_REQUIRED epoxy" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GTK_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (gtk+-3.0 >= $GTK_REQUIRED epoxy) were not met:
+
+$GTK_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables GTK_CFLAGS
+and GTK_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables GTK_CFLAGS
+and GTK_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ GTK_CFLAGS=$pkg_cv_GTK_CFLAGS
+ GTK_LIBS=$pkg_cv_GTK_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+fi
+ GTK_CFLAGS="$GTK_CFLAGS -DGDK_VERSION_MIN_REQUIRED=$GTK_ENCODED_VERSION \
+ -DGDK_VERSION_MAX_ALLOWED=$GTK_ENCODED_VERSION"
+fi
+SPICE_GTK_REQUIRES="${SPICE_GTK_REQUIRES} gtk+-3.0 >= $GTK_REQUIRED"
+
+# Check for gdk_event_get_scancode function
+# This was added in Gdk 3.22
+# The check allows the usage of the function in case the function is
+# backported or in case of compilation from Gdk master branch
+old_LIBS="$LIBS"
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $GTK_CFLAGS"
+LIBS="$LIBS $GTK_LIBS"
+for ac_func in gdk_event_get_scancode
+do :
+ ac_fn_c_check_func "$LINENO" "gdk_event_get_scancode" "ac_cv_func_gdk_event_get_scancode"
+if test "x$ac_cv_func_gdk_event_get_scancode" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_GDK_EVENT_GET_SCANCODE 1
+_ACEOF
+
+fi
+done
+
+LIBS="$old_LIBS"
+CFLAGS="$old_CFLAGS"
+
+if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-x11-\$with_gtk\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gtk+-x11-$with_gtk") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11" >&5
+$as_echo_n "checking for X11... " >&6; }
+
+if test -n "$X11_CFLAGS"; then
+ pkg_cv_X11_CFLAGS="$X11_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "x11") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_X11_CFLAGS=`$PKG_CONFIG --cflags "x11" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$X11_LIBS"; then
+ pkg_cv_X11_LIBS="$X11_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "x11") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_X11_LIBS=`$PKG_CONFIG --libs "x11" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ X11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "x11" 2>&1`
+ else
+ X11_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "x11" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$X11_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (x11) were not met:
+
+$X11_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables X11_CFLAGS
+and X11_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables X11_CFLAGS
+and X11_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ X11_CFLAGS=$pkg_cv_X11_CFLAGS
+ X11_LIBS=$pkg_cv_X11_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+fi
+for ac_header in X11/XKBlib.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "X11/XKBlib.h" "ac_cv_header_X11_XKBlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_X11_XKBlib_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_X11_XKBLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+# Check whether --with-pnp-ids-path was given.
+if test "${with_pnp_ids_path+set}" = set; then :
+ withval=$with_pnp_ids_path;
+else
+ with_pnp_ids_path="\${pnpdatadir}/pnp.ids"
+fi
+
+
+ if test "x$with_pnp_ids_path" = "x\${pnpdatadir}/pnp.ids"; then
+ USE_INTERNAL_PNP_IDS_TRUE=
+ USE_INTERNAL_PNP_IDS_FALSE='#'
+else
+ USE_INTERNAL_PNP_IDS_TRUE='#'
+ USE_INTERNAL_PNP_IDS_FALSE=
+fi
+
+PNP_IDS=$with_pnp_ids_path
+
+if test "x$with_pnp_ids_path" = "x\${pnpdatadir}/pnp.ids"; then
+ EXTERNAL_PNP_IDS="no (internal)"
+else
+ EXTERNAL_PNP_IDS="$with_pnp_ids_path"
+fi
+
+for ac_func in clearenv strtok_r
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# Keep these two definitions in agreement.
+GLIB2_REQUIRED="2.36"
+GLIB2_ENCODED_VERSION="GLIB_VERSION_2_36"
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLIB2" >&5
+$as_echo_n "checking for GLIB2... " >&6; }
+
+if test -n "$GLIB2_CFLAGS"; then
+ pkg_cv_GLIB2_CFLAGS="$GLIB2_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= \$GLIB2_REQUIRED\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "glib-2.0 >= $GLIB2_REQUIRED") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GLIB2_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= $GLIB2_REQUIRED" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GLIB2_LIBS"; then
+ pkg_cv_GLIB2_LIBS="$GLIB2_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= \$GLIB2_REQUIRED\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "glib-2.0 >= $GLIB2_REQUIRED") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GLIB2_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= $GLIB2_REQUIRED" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GLIB2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "glib-2.0 >= $GLIB2_REQUIRED" 2>&1`
+ else
+ GLIB2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "glib-2.0 >= $GLIB2_REQUIRED" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GLIB2_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (glib-2.0 >= $GLIB2_REQUIRED) were not met:
+
+$GLIB2_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables GLIB2_CFLAGS
+and GLIB2_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables GLIB2_CFLAGS
+and GLIB2_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ GLIB2_CFLAGS=$pkg_cv_GLIB2_CFLAGS
+ GLIB2_LIBS=$pkg_cv_GLIB2_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+GLIB2_CFLAGS="$GLIB2_CFLAGS -DGLIB_VERSION_MIN_REQUIRED=$GLIB2_ENCODED_VERSION \
+ -DGLIB_VERSION_MAX_ALLOWED=$GLIB2_ENCODED_VERSION"
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GOBJECT2" >&5
+$as_echo_n "checking for GOBJECT2... " >&6; }
+
+if test -n "$GOBJECT2_CFLAGS"; then
+ pkg_cv_GOBJECT2_CFLAGS="$GOBJECT2_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gobject-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gobject-2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GOBJECT2_CFLAGS=`$PKG_CONFIG --cflags "gobject-2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GOBJECT2_LIBS"; then
+ pkg_cv_GOBJECT2_LIBS="$GOBJECT2_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gobject-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gobject-2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GOBJECT2_LIBS=`$PKG_CONFIG --libs "gobject-2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GOBJECT2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gobject-2.0" 2>&1`
+ else
+ GOBJECT2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gobject-2.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GOBJECT2_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (gobject-2.0) were not met:
+
+$GOBJECT2_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables GOBJECT2_CFLAGS
+and GOBJECT2_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables GOBJECT2_CFLAGS
+and GOBJECT2_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ GOBJECT2_CFLAGS=$pkg_cv_GOBJECT2_CFLAGS
+ GOBJECT2_LIBS=$pkg_cv_GOBJECT2_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GIO" >&5
+$as_echo_n "checking for GIO... " >&6; }
+
+if test -n "$GIO_CFLAGS"; then
+ pkg_cv_GIO_CFLAGS="$GIO_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gio-2.0 >= 2.36 \$gio_os\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gio-2.0 >= 2.36 $gio_os") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GIO_CFLAGS=`$PKG_CONFIG --cflags "gio-2.0 >= 2.36 $gio_os" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GIO_LIBS"; then
+ pkg_cv_GIO_LIBS="$GIO_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gio-2.0 >= 2.36 \$gio_os\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gio-2.0 >= 2.36 $gio_os") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GIO_LIBS=`$PKG_CONFIG --libs "gio-2.0 >= 2.36 $gio_os" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gio-2.0 >= 2.36 $gio_os" 2>&1`
+ else
+ GIO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gio-2.0 >= 2.36 $gio_os" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GIO_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (gio-2.0 >= 2.36 $gio_os) were not met:
+
+$GIO_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables GIO_CFLAGS
+and GIO_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables GIO_CFLAGS
+and GIO_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ GIO_CFLAGS=$pkg_cv_GIO_CFLAGS
+ GIO_LIBS=$pkg_cv_GIO_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CAIRO" >&5
+$as_echo_n "checking for CAIRO... " >&6; }
+
+if test -n "$CAIRO_CFLAGS"; then
+ pkg_cv_CAIRO_CFLAGS="$CAIRO_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cairo >= 1.2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "cairo >= 1.2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_CAIRO_CFLAGS=`$PKG_CONFIG --cflags "cairo >= 1.2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$CAIRO_LIBS"; then
+ pkg_cv_CAIRO_LIBS="$CAIRO_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cairo >= 1.2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "cairo >= 1.2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_CAIRO_LIBS=`$PKG_CONFIG --libs "cairo >= 1.2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ CAIRO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "cairo >= 1.2.0" 2>&1`
+ else
+ CAIRO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "cairo >= 1.2.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$CAIRO_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (cairo >= 1.2.0) were not met:
+
+$CAIRO_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables CAIRO_CFLAGS
+and CAIRO_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables CAIRO_CFLAGS
+and CAIRO_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ CAIRO_CFLAGS=$pkg_cv_CAIRO_CFLAGS
+ CAIRO_LIBS=$pkg_cv_CAIRO_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTHREAD" >&5
+$as_echo_n "checking for GTHREAD... " >&6; }
+
+if test -n "$GTHREAD_CFLAGS"; then
+ pkg_cv_GTHREAD_CFLAGS="$GTHREAD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gthread-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gthread-2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GTHREAD_CFLAGS=`$PKG_CONFIG --cflags "gthread-2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GTHREAD_LIBS"; then
+ pkg_cv_GTHREAD_LIBS="$GTHREAD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gthread-2.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gthread-2.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GTHREAD_LIBS=`$PKG_CONFIG --libs "gthread-2.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GTHREAD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gthread-2.0" 2>&1`
+ else
+ GTHREAD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gthread-2.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GTHREAD_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (gthread-2.0) were not met:
+
+$GTHREAD_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables GTHREAD_CFLAGS
+and GTHREAD_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables GTHREAD_CFLAGS
+and GTHREAD_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ GTHREAD_CFLAGS=$pkg_cv_GTHREAD_CFLAGS
+ GTHREAD_LIBS=$pkg_cv_GTHREAD_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+# Check whether --enable-webdav was given.
+if test "${enable_webdav+set}" = set; then :
+ enableval=$enable_webdav;
+else
+ enable_webdav="auto"
+fi
+
+
+if test "x$enable_webdav" = "xno"; then
+ have_phodav="no"
+else
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PHODAV" >&5
+$as_echo_n "checking for PHODAV... " >&6; }
+
+if test -n "$PHODAV_CFLAGS"; then
+ pkg_cv_PHODAV_CFLAGS="$PHODAV_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libphodav-2.0 glib-2.0 >= 2.43.90 libsoup-2.4 >= 2.49.91\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libphodav-2.0 glib-2.0 >= 2.43.90 libsoup-2.4 >= 2.49.91") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PHODAV_CFLAGS=`$PKG_CONFIG --cflags "libphodav-2.0 glib-2.0 >= 2.43.90 libsoup-2.4 >= 2.49.91" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$PHODAV_LIBS"; then
+ pkg_cv_PHODAV_LIBS="$PHODAV_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libphodav-2.0 glib-2.0 >= 2.43.90 libsoup-2.4 >= 2.49.91\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libphodav-2.0 glib-2.0 >= 2.43.90 libsoup-2.4 >= 2.49.91") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PHODAV_LIBS=`$PKG_CONFIG --libs "libphodav-2.0 glib-2.0 >= 2.43.90 libsoup-2.4 >= 2.49.91" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ PHODAV_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libphodav-2.0 glib-2.0 >= 2.43.90 libsoup-2.4 >= 2.49.91" 2>&1`
+ else
+ PHODAV_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libphodav-2.0 glib-2.0 >= 2.43.90 libsoup-2.4 >= 2.49.91" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$PHODAV_PKG_ERRORS" >&5
+
+ have_phodav=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_phodav=no
+else
+ PHODAV_CFLAGS=$pkg_cv_PHODAV_CFLAGS
+ PHODAV_LIBS=$pkg_cv_PHODAV_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_phodav=yes
+fi
+
+ if test "x$have_phodav" = "xno" && test "x$enable_webdav" = "xyes"; then
+ as_fn_error $? "webdav support explicitly requested, but some required packages are not available" "$LINENO" 5
+ fi
+fi
+if test "x$have_phodav" = "xyes"; then :
+
+$as_echo "#define USE_PHODAV 1" >>confdefs.h
+
+fi
+
+ if test "x$have_phodav" = "xyes"; then
+ WITH_PHODAV_TRUE=
+ WITH_PHODAV_FALSE='#'
+else
+ WITH_PHODAV_TRUE='#'
+ WITH_PHODAV_FALSE=
+fi
+
+
+
+# Check whether --with-audio was given.
+if test "${with_audio+set}" = set; then :
+ withval=$with_audio; spice_warnings=$spice_warnings"|--with-audio is deprecated. Use --enable-pulse and/or --enable-gstaudio instead"
+ case "$with_audio" in
+ pulse) enable_pulse="yes"; enable_gstaudio="no" ;;
+ gstreamer) enable_pulse="no"; enable_gstaudio="yes" ;;
+ no) enable_pulse="no"; enable_gstaudio="no" ;;
+ esac
+
+fi
+
+
+# Check whether --enable-pulse was given.
+if test "${enable_pulse+set}" = set; then :
+ enableval=$enable_pulse;
+else
+ enable_pulse="auto"
+fi
+
+if test "x$enable_pulse" != "xno"; then :
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PULSE" >&5
+$as_echo_n "checking for PULSE... " >&6; }
+
+if test -n "$PULSE_CFLAGS"; then
+ pkg_cv_PULSE_CFLAGS="$PULSE_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpulse libpulse-mainloop-glib\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libpulse libpulse-mainloop-glib") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PULSE_CFLAGS=`$PKG_CONFIG --cflags "libpulse libpulse-mainloop-glib" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$PULSE_LIBS"; then
+ pkg_cv_PULSE_LIBS="$PULSE_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpulse libpulse-mainloop-glib\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libpulse libpulse-mainloop-glib") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PULSE_LIBS=`$PKG_CONFIG --libs "libpulse libpulse-mainloop-glib" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ PULSE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libpulse libpulse-mainloop-glib" 2>&1`
+ else
+ PULSE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libpulse libpulse-mainloop-glib" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$PULSE_PKG_ERRORS" >&5
+
+ if test "x$enable_pulse" = "xyes"; then :
+ as_fn_error $? "PulseAudio requested but not found" "$LINENO" 5
+fi
+ enable_pulse="no"
+
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ if test "x$enable_pulse" = "xyes"; then :
+ as_fn_error $? "PulseAudio requested but not found" "$LINENO" 5
+fi
+ enable_pulse="no"
+
+else
+ PULSE_CFLAGS=$pkg_cv_PULSE_CFLAGS
+ PULSE_LIBS=$pkg_cv_PULSE_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_PULSE 1" >>confdefs.h
+
+ enable_pulse="yes"
+fi
+
+fi
+ if test "x$enable_pulse" = "xyes"; then
+ HAVE_PULSE_TRUE=
+ HAVE_PULSE_FALSE='#'
+else
+ HAVE_PULSE_TRUE='#'
+ HAVE_PULSE_FALSE=
+fi
+
+
+# Check whether --enable-gstaudio was given.
+if test "${enable_gstaudio+set}" = set; then :
+ enableval=$enable_gstaudio;
+else
+ enable_gstaudio="auto"
+fi
+
+if test "x$enable_gstaudio" != "xno"; then :
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GSTAUDIO" >&5
+$as_echo_n "checking for GSTAUDIO... " >&6; }
+
+if test -n "$GSTAUDIO_CFLAGS"; then
+ pkg_cv_GSTAUDIO_CFLAGS="$GSTAUDIO_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-audio-1.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-audio-1.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GSTAUDIO_CFLAGS=`$PKG_CONFIG --cflags "gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-audio-1.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GSTAUDIO_LIBS"; then
+ pkg_cv_GSTAUDIO_LIBS="$GSTAUDIO_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-audio-1.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-audio-1.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GSTAUDIO_LIBS=`$PKG_CONFIG --libs "gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-audio-1.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GSTAUDIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-audio-1.0" 2>&1`
+ else
+ GSTAUDIO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-audio-1.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GSTAUDIO_PKG_ERRORS" >&5
+
+ have_gstaudio="no"
+ if test "x$enable_gstaudio" = "xyes"; then :
+ as_fn_error $? "GStreamer 1.0 audio requested but not found" "$LINENO" 5
+fi
+
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_gstaudio="no"
+ if test "x$enable_gstaudio" = "xyes"; then :
+ as_fn_error $? "GStreamer 1.0 audio requested but not found" "$LINENO" 5
+fi
+
+else
+ GSTAUDIO_CFLAGS=$pkg_cv_GSTAUDIO_CFLAGS
+ GSTAUDIO_LIBS=$pkg_cv_GSTAUDIO_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_gstaudio="yes"
+
+
+ SPICE_REQUIRES=$SPICE_REQUIRES" gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-audio-1.0"
+
+$as_echo "#define HAVE_GSTAUDIO 1" >>confdefs.h
+
+ # Extract the first word of "gst-inspect-1.0", so it can be a program name with args.
+set dummy gst-inspect-1.0; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GST_INSPECT_1_0+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GST_INSPECT_1_0 in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GST_INSPECT_1_0="$GST_INSPECT_1_0" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GST_INSPECT_1_0="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+GST_INSPECT_1_0=$ac_cv_path_GST_INSPECT_1_0
+if test -n "$GST_INSPECT_1_0"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GST_INSPECT_1_0" >&5
+$as_echo "$GST_INSPECT_1_0" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$GST_INSPECT_1_0" = x; then :
+ spice_warnings=$spice_warnings"|Cannot verify that the required runtime GStreamer 1.0 elements are present because gst-inspect-1.0 is missing"
+fi
+
+if test "x$GST_INSPECT_1_0" != x; then :
+ missing=""
+ for element in audioconvert audioresample appsink
+ do
+ as_cache_var=`$as_echo "spice_cv_prog_${1}_${element}" | $as_tr_sh`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the $element GStreamer element" >&5
+$as_echo_n "checking for the $element GStreamer element... " >&6; }
+if eval \${$as_cache_var+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ found=no
+ "$GST_INSPECT_1_0" $element >/dev/null 2>/dev/null && found=yes
+ eval "$as_cache_var=$found"
+fi
+eval ac_res=\$$as_cache_var
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval res=\$$as_cache_var
+ if test "x$res" = "xno"; then :
+ missing="$missing $element"
+fi
+ done
+ if test "x$missing" != x; then :
+ spice_warnings=$spice_warnings"|The$missing GStreamer element(s) are missing. You should be able to find them in the gst-plugins-base 1.0 package."
+ missing_gstreamer_elements="yes"
+elif test "x$missing_gstreamer_elements" = x; then :
+ missing_gstreamer_elements="no"
+fi
+
+fi
+
+
+if test "x$GST_INSPECT_1_0" != x; then :
+ missing=""
+ for element in autoaudiosrc
+ do
+ as_cache_var=`$as_echo "spice_cv_prog_${1}_${element}" | $as_tr_sh`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the $element GStreamer element" >&5
+$as_echo_n "checking for the $element GStreamer element... " >&6; }
+if eval \${$as_cache_var+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ found=no
+ "$GST_INSPECT_1_0" $element >/dev/null 2>/dev/null && found=yes
+ eval "$as_cache_var=$found"
+fi
+eval ac_res=\$$as_cache_var
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval res=\$$as_cache_var
+ if test "x$res" = "xno"; then :
+ missing="$missing $element"
+fi
+ done
+ if test "x$missing" != x; then :
+ spice_warnings=$spice_warnings"|The$missing GStreamer element(s) are missing. You should be able to find them in the gst-plugins-good 1.0 package."
+ missing_gstreamer_elements="yes"
+elif test "x$missing_gstreamer_elements" = x; then :
+ missing_gstreamer_elements="no"
+fi
+
+fi
+
+ if test x"$missing_gstreamer_elements" = "xyes"; then :
+ spice_warnings=$spice_warnings"|The GStreamer 1.0 audio backend can be built but may not work."
+fi
+
+fi
+
+
+else
+ have_gstaudio="no"
+
+fi
+ if test "x$have_gstaudio" = "xyes"; then
+ HAVE_GSTAUDIO_TRUE=
+ HAVE_GSTAUDIO_FALSE='#'
+else
+ HAVE_GSTAUDIO_TRUE='#'
+ HAVE_GSTAUDIO_FALSE=
+fi
+
+
+if test "x$enable_pulse$have_gstaudio" = "xnono"; then :
+ spice_warnings=$spice_warnings"|No PulseAudio or GStreamer 1.0 audio decoder, audio will not be streamed"
+
+fi
+
+# Check whether --enable-gstvideo was given.
+if test "${enable_gstvideo+set}" = set; then :
+ enableval=$enable_gstvideo;
+else
+ enable_gstvideo="auto"
+fi
+
+if test "x$enable_gstvideo" != "xno"; then :
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GSTVIDEO" >&5
+$as_echo_n "checking for GSTVIDEO... " >&6; }
+
+if test -n "$GSTVIDEO_CFLAGS"; then
+ pkg_cv_GSTVIDEO_CFLAGS="$GSTVIDEO_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GSTVIDEO_CFLAGS=`$PKG_CONFIG --cflags "gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GSTVIDEO_LIBS"; then
+ pkg_cv_GSTVIDEO_LIBS="$GSTVIDEO_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GSTVIDEO_LIBS=`$PKG_CONFIG --libs "gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GSTVIDEO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0" 2>&1`
+ else
+ GSTVIDEO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GSTVIDEO_PKG_ERRORS" >&5
+
+ have_gstvideo="no"
+ if test "x$enable_gstvideo" = "xyes"; then :
+ as_fn_error $? "GStreamer 1.0 video requested but not found" "$LINENO" 5
+fi
+
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_gstvideo="no"
+ if test "x$enable_gstvideo" = "xyes"; then :
+ as_fn_error $? "GStreamer 1.0 video requested but not found" "$LINENO" 5
+fi
+
+else
+ GSTVIDEO_CFLAGS=$pkg_cv_GSTVIDEO_CFLAGS
+ GSTVIDEO_LIBS=$pkg_cv_GSTVIDEO_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_gstvideo="yes"
+
+
+ SPICE_REQUIRES=$SPICE_REQUIRES" gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0"
+
+$as_echo "#define HAVE_GSTVIDEO 1" >>confdefs.h
+
+ # Extract the first word of "gst-inspect-1.0", so it can be a program name with args.
+set dummy gst-inspect-1.0; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_GST_INSPECT_1_0+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GST_INSPECT_1_0 in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GST_INSPECT_1_0="$GST_INSPECT_1_0" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_GST_INSPECT_1_0="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+GST_INSPECT_1_0=$ac_cv_path_GST_INSPECT_1_0
+if test -n "$GST_INSPECT_1_0"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GST_INSPECT_1_0" >&5
+$as_echo "$GST_INSPECT_1_0" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$GST_INSPECT_1_0" = x; then :
+ spice_warnings=$spice_warnings"|Cannot verify that the required runtime GStreamer 1.0 elements are present because gst-inspect-1.0 is missing"
+fi
+ missing_gstreamer_elements=""
+
+if test "x$GST_INSPECT_1_0" != x; then :
+ missing=""
+ for element in appsrc videoconvert appsink
+ do
+ as_cache_var=`$as_echo "spice_cv_prog_${1}_${element}" | $as_tr_sh`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the $element GStreamer element" >&5
+$as_echo_n "checking for the $element GStreamer element... " >&6; }
+if eval \${$as_cache_var+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ found=no
+ "$GST_INSPECT_1_0" $element >/dev/null 2>/dev/null && found=yes
+ eval "$as_cache_var=$found"
+fi
+eval ac_res=\$$as_cache_var
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval res=\$$as_cache_var
+ if test "x$res" = "xno"; then :
+ missing="$missing $element"
+fi
+ done
+ if test "x$missing" != x; then :
+ spice_warnings=$spice_warnings"|The$missing GStreamer element(s) are missing. You should be able to find them in the gst-plugins-base 1.0 package."
+ missing_gstreamer_elements="yes"
+elif test "x$missing_gstreamer_elements" = x; then :
+ missing_gstreamer_elements="no"
+fi
+
+fi
+
+
+if test "x$GST_INSPECT_1_0" != x; then :
+ missing=""
+ for element in jpegdec vp8dec
+ do
+ as_cache_var=`$as_echo "spice_cv_prog_${1}_${element}" | $as_tr_sh`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the $element GStreamer element" >&5
+$as_echo_n "checking for the $element GStreamer element... " >&6; }
+if eval \${$as_cache_var+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ found=no
+ "$GST_INSPECT_1_0" $element >/dev/null 2>/dev/null && found=yes
+ eval "$as_cache_var=$found"
+fi
+eval ac_res=\$$as_cache_var
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval res=\$$as_cache_var
+ if test "x$res" = "xno"; then :
+ missing="$missing $element"
+fi
+ done
+ if test "x$missing" != x; then :
+ spice_warnings=$spice_warnings"|The$missing GStreamer element(s) are missing. You should be able to find them in the gst-plugins-good 1.0 package."
+ missing_gstreamer_elements="yes"
+elif test "x$missing_gstreamer_elements" = x; then :
+ missing_gstreamer_elements="no"
+fi
+
+fi
+
+
+if test "x$GST_INSPECT_1_0" != x; then :
+ missing=""
+ for element in h264parse
+ do
+ as_cache_var=`$as_echo "spice_cv_prog_${1}_${element}" | $as_tr_sh`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the $element GStreamer element" >&5
+$as_echo_n "checking for the $element GStreamer element... " >&6; }
+if eval \${$as_cache_var+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ found=no
+ "$GST_INSPECT_1_0" $element >/dev/null 2>/dev/null && found=yes
+ eval "$as_cache_var=$found"
+fi
+eval ac_res=\$$as_cache_var
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval res=\$$as_cache_var
+ if test "x$res" = "xno"; then :
+ missing="$missing $element"
+fi
+ done
+ if test "x$missing" != x; then :
+ spice_warnings=$spice_warnings"|The$missing GStreamer element(s) are missing. You should be able to find them in the gst-plugins-bad 1.0 package."
+ missing_gstreamer_elements="yes"
+elif test "x$missing_gstreamer_elements" = x; then :
+ missing_gstreamer_elements="no"
+fi
+
+fi
+
+
+if test "x$GST_INSPECT_1_0" != x; then :
+ missing=""
+ for element in avdec_h264
+ do
+ as_cache_var=`$as_echo "spice_cv_prog_${1}_${element}" | $as_tr_sh`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the $element GStreamer element" >&5
+$as_echo_n "checking for the $element GStreamer element... " >&6; }
+if eval \${$as_cache_var+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ found=no
+ "$GST_INSPECT_1_0" $element >/dev/null 2>/dev/null && found=yes
+ eval "$as_cache_var=$found"
+fi
+eval ac_res=\$$as_cache_var
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval res=\$$as_cache_var
+ if test "x$res" = "xno"; then :
+ missing="$missing $element"
+fi
+ done
+ if test "x$missing" != x; then :
+ spice_warnings=$spice_warnings"|The$missing GStreamer element(s) are missing. You should be able to find them in the gstreamer-libav 1.0 package."
+ missing_gstreamer_elements="yes"
+elif test "x$missing_gstreamer_elements" = x; then :
+ missing_gstreamer_elements="no"
+fi
+
+fi
+
+ if test x"$missing_gstreamer_elements" = "xyes"; then :
+ spice_warnings=$spice_warnings"|The GStreamer video decoder can be built but may not work."
+fi
+
+fi
+
+
+else
+ have_gstvideo="no"
+
+fi
+ if test "x$have_gstvideo" = "xyes"; then
+ HAVE_GSTVIDEO_TRUE=
+ HAVE_GSTVIDEO_FALSE='#'
+else
+ HAVE_GSTVIDEO_TRUE='#'
+ HAVE_GSTVIDEO_FALSE=
+fi
+
+
+# Check whether --enable-builtin-mjpeg was given.
+if test "${enable_builtin_mjpeg+set}" = set; then :
+ enableval=$enable_builtin_mjpeg;
+else
+ enable_builtin_mjpeg="yes"
+fi
+
+if test "x$enable_builtin_mjpeg" = "xyes"; then :
+
+$as_echo "#define HAVE_BUILTIN_MJPEG 1" >>confdefs.h
+
+fi
+ if test "x$enable_builtin_mjpeg" != "xno"; then
+ HAVE_BUILTIN_MJPEG_TRUE=
+ HAVE_BUILTIN_MJPEG_FALSE='#'
+else
+ HAVE_BUILTIN_MJPEG_TRUE='#'
+ HAVE_BUILTIN_MJPEG_FALSE=
+fi
+
+
+if test "x$enable_builtin_mjpeg$enable_gstvideo" = "xnono"; then :
+ spice_warnings=$spice_warnings"|No builtin MJPEG or GStreamer decoder, video will not be streamed"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for jpeg_destroy_decompress in -ljpeg" >&5
+$as_echo_n "checking for jpeg_destroy_decompress in -ljpeg... " >&6; }
+if ${ac_cv_lib_jpeg_jpeg_destroy_decompress+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljpeg $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char jpeg_destroy_decompress ();
+int
+main ()
+{
+return jpeg_destroy_decompress ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_jpeg_jpeg_destroy_decompress=yes
+else
+ ac_cv_lib_jpeg_jpeg_destroy_decompress=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_jpeg_destroy_decompress" >&5
+$as_echo "$ac_cv_lib_jpeg_jpeg_destroy_decompress" >&6; }
+if test "x$ac_cv_lib_jpeg_jpeg_destroy_decompress" = xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jpeglib.h" >&5
+$as_echo_n "checking for jpeglib.h... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+#undef PACKAGE
+#undef VERSION
+#undef HAVE_STDLIB_H
+#include <jpeglib.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ JPEG_LIBS='-ljpeg'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $jpeg_ok" >&5
+$as_echo "$jpeg_ok" >&6; }
+else
+ as_fn_error $? "jpeglib.h not found" "$LINENO" 5
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+else
+ as_fn_error $? "libjpeg not found" "$LINENO" 5
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflate in -lz" >&5
+$as_echo_n "checking for deflate in -lz... " >&6; }
+if ${ac_cv_lib_z_deflate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char deflate ();
+int
+main ()
+{
+return deflate ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_z_deflate=yes
+else
+ ac_cv_lib_z_deflate=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflate" >&5
+$as_echo "$ac_cv_lib_z_deflate" >&6; }
+if test "x$ac_cv_lib_z_deflate" = xyes; then :
+ Z_LIBS='-lz'
+else
+ as_fn_error $? "zlib not found" "$LINENO" 5
+fi
+
+
+
+
+ # Check whether --enable-smartcard was given.
+if test "${enable_smartcard+set}" = set; then :
+ enableval=$enable_smartcard;
+else
+ enable_smartcard="auto"
+fi
+
+
+ have_smartcard=no
+ if test "x$enable_smartcard" != "xno"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SMARTCARD" >&5
+$as_echo_n "checking for SMARTCARD... " >&6; }
+
+if test -n "$SMARTCARD_CFLAGS"; then
+ pkg_cv_SMARTCARD_CFLAGS="$SMARTCARD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcacard >= 2.5.1\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libcacard >= 2.5.1") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SMARTCARD_CFLAGS=`$PKG_CONFIG --cflags "libcacard >= 2.5.1" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$SMARTCARD_LIBS"; then
+ pkg_cv_SMARTCARD_LIBS="$SMARTCARD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcacard >= 2.5.1\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libcacard >= 2.5.1") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SMARTCARD_LIBS=`$PKG_CONFIG --libs "libcacard >= 2.5.1" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ SMARTCARD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcacard >= 2.5.1" 2>&1`
+ else
+ SMARTCARD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcacard >= 2.5.1" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$SMARTCARD_PKG_ERRORS" >&5
+
+ have_smartcard=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_smartcard=no
+else
+ SMARTCARD_CFLAGS=$pkg_cv_SMARTCARD_CFLAGS
+ SMARTCARD_LIBS=$pkg_cv_SMARTCARD_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_smartcard=yes
+fi
+ if test "x$have_smartcard" = "xno"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SMARTCARD" >&5
+$as_echo_n "checking for SMARTCARD... " >&6; }
+
+if test -n "$SMARTCARD_CFLAGS"; then
+ pkg_cv_SMARTCARD_CFLAGS="$SMARTCARD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcacard >= 0.1.2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libcacard >= 0.1.2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SMARTCARD_CFLAGS=`$PKG_CONFIG --cflags "libcacard >= 0.1.2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$SMARTCARD_LIBS"; then
+ pkg_cv_SMARTCARD_LIBS="$SMARTCARD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcacard >= 0.1.2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libcacard >= 0.1.2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SMARTCARD_LIBS=`$PKG_CONFIG --libs "libcacard >= 0.1.2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ SMARTCARD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcacard >= 0.1.2" 2>&1`
+ else
+ SMARTCARD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcacard >= 0.1.2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$SMARTCARD_PKG_ERRORS" >&5
+
+ have_smartcard=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_smartcard=no
+else
+ SMARTCARD_CFLAGS=$pkg_cv_SMARTCARD_CFLAGS
+ SMARTCARD_LIBS=$pkg_cv_SMARTCARD_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_smartcard=yes have_smartcard_012=yes
+fi
+ fi
+ if test "x$enable_smartcard" != "xauto" && test "x$have_smartcard" = "xno"; then
+ as_fn_error $? "\"Smartcard support requested but libcacard could not be found\"" "$LINENO" 5
+ fi
+ if test "x$have_smartcard_012" = "xyes"; then
+
+$as_echo "#define USE_SMARTCARD_012 1" >>confdefs.h
+
+ fi
+ if test "x$have_smartcard" = "xyes"; then
+
+$as_echo "#define USE_SMARTCARD 1" >>confdefs.h
+
+ fi
+ fi
+ if test "x$have_smartcard" = "xyes"; then
+ HAVE_SMARTCARD_TRUE=
+ HAVE_SMARTCARD_FALSE='#'
+else
+ HAVE_SMARTCARD_TRUE='#'
+ HAVE_SMARTCARD_FALSE=
+fi
+
+
+ if test "x$have_smartcard" = "xyes"; then
+ WITH_SMARTCARD_TRUE=
+ WITH_SMARTCARD_FALSE='#'
+else
+ WITH_SMARTCARD_TRUE='#'
+ WITH_SMARTCARD_FALSE=
+fi
+
+
+# Check whether --enable-usbredir was given.
+if test "${enable_usbredir+set}" = set; then :
+ enableval=$enable_usbredir;
+else
+ enable_usbredir="auto"
+fi
+
+
+if test "x$enable_usbredir" = "xno"; then
+ have_usbredir="no"
+else
+ if ${PKG_CONFIG} libusbredirparser-0.5; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for USBREDIR" >&5
+$as_echo_n "checking for USBREDIR... " >&6; }
+
+if test -n "$USBREDIR_CFLAGS"; then
+ pkg_cv_USBREDIR_CFLAGS="$USBREDIR_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0 >= 1.0.9 libusbredirhost libusbredirparser-0.5\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libusb-1.0 >= 1.0.9 libusbredirhost libusbredirparser-0.5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_USBREDIR_CFLAGS=`$PKG_CONFIG --cflags "libusb-1.0 >= 1.0.9 libusbredirhost libusbredirparser-0.5" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$USBREDIR_LIBS"; then
+ pkg_cv_USBREDIR_LIBS="$USBREDIR_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0 >= 1.0.9 libusbredirhost libusbredirparser-0.5\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libusb-1.0 >= 1.0.9 libusbredirhost libusbredirparser-0.5") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_USBREDIR_LIBS=`$PKG_CONFIG --libs "libusb-1.0 >= 1.0.9 libusbredirhost libusbredirparser-0.5" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ USBREDIR_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libusb-1.0 >= 1.0.9 libusbredirhost libusbredirparser-0.5" 2>&1`
+ else
+ USBREDIR_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libusb-1.0 >= 1.0.9 libusbredirhost libusbredirparser-0.5" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$USBREDIR_PKG_ERRORS" >&5
+
+ have_usbredir=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_usbredir=no
+else
+ USBREDIR_CFLAGS=$pkg_cv_USBREDIR_CFLAGS
+ USBREDIR_LIBS=$pkg_cv_USBREDIR_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_usbredir=yes
+fi
+ else
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for USBREDIR" >&5
+$as_echo_n "checking for USBREDIR... " >&6; }
+
+if test -n "$USBREDIR_CFLAGS"; then
+ pkg_cv_USBREDIR_CFLAGS="$USBREDIR_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0 >= 1.0.9 libusbredirhost >= 0.4.2 libusbredirparser >= 0.4\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libusb-1.0 >= 1.0.9 libusbredirhost >= 0.4.2 libusbredirparser >= 0.4") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_USBREDIR_CFLAGS=`$PKG_CONFIG --cflags "libusb-1.0 >= 1.0.9 libusbredirhost >= 0.4.2 libusbredirparser >= 0.4" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$USBREDIR_LIBS"; then
+ pkg_cv_USBREDIR_LIBS="$USBREDIR_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0 >= 1.0.9 libusbredirhost >= 0.4.2 libusbredirparser >= 0.4\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libusb-1.0 >= 1.0.9 libusbredirhost >= 0.4.2 libusbredirparser >= 0.4") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_USBREDIR_LIBS=`$PKG_CONFIG --libs "libusb-1.0 >= 1.0.9 libusbredirhost >= 0.4.2 libusbredirparser >= 0.4" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ USBREDIR_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libusb-1.0 >= 1.0.9 libusbredirhost >= 0.4.2 libusbredirparser >= 0.4" 2>&1`
+ else
+ USBREDIR_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libusb-1.0 >= 1.0.9 libusbredirhost >= 0.4.2 libusbredirparser >= 0.4" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$USBREDIR_PKG_ERRORS" >&5
+
+ have_usbredir=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_usbredir=no
+else
+ USBREDIR_CFLAGS=$pkg_cv_USBREDIR_CFLAGS
+ USBREDIR_LIBS=$pkg_cv_USBREDIR_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_usbredir=yes
+fi
+ fi
+ if test "x$have_usbredir" = "xno" && test "x$enable_usbredir" = "xyes"; then
+ as_fn_error $? "usbredir support explicitly requested, but some required packages are not available" "$LINENO" 5
+ fi
+
+ # On non windows we need either libusb hotplug support or gudev
+ if test "x$have_usbredir" = "xyes" && test "x$os_win32" = "xno"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBUSB_HOTPLUG" >&5
+$as_echo_n "checking for LIBUSB_HOTPLUG... " >&6; }
+
+if test -n "$LIBUSB_HOTPLUG_CFLAGS"; then
+ pkg_cv_LIBUSB_HOTPLUG_CFLAGS="$LIBUSB_HOTPLUG_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0 >= 1.0.16\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libusb-1.0 >= 1.0.16") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LIBUSB_HOTPLUG_CFLAGS=`$PKG_CONFIG --cflags "libusb-1.0 >= 1.0.16" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$LIBUSB_HOTPLUG_LIBS"; then
+ pkg_cv_LIBUSB_HOTPLUG_LIBS="$LIBUSB_HOTPLUG_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0 >= 1.0.16\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libusb-1.0 >= 1.0.16") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LIBUSB_HOTPLUG_LIBS=`$PKG_CONFIG --libs "libusb-1.0 >= 1.0.16" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ LIBUSB_HOTPLUG_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libusb-1.0 >= 1.0.16" 2>&1`
+ else
+ LIBUSB_HOTPLUG_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libusb-1.0 >= 1.0.16" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$LIBUSB_HOTPLUG_PKG_ERRORS" >&5
+
+ have_libusb_hotplug=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_libusb_hotplug=no
+else
+ LIBUSB_HOTPLUG_CFLAGS=$pkg_cv_LIBUSB_HOTPLUG_CFLAGS
+ LIBUSB_HOTPLUG_LIBS=$pkg_cv_LIBUSB_HOTPLUG_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_libusb_hotplug=yes
+fi
+ if test "x$have_libusb_hotplug" = "xyes"; then
+
+$as_echo "#define USE_LIBUSB_HOTPLUG 1" >>confdefs.h
+
+ with_usbredir_hotplug="with libusb hotplug"
+ else
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GUDEV" >&5
+$as_echo_n "checking for GUDEV... " >&6; }
+
+if test -n "$GUDEV_CFLAGS"; then
+ pkg_cv_GUDEV_CFLAGS="$GUDEV_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gudev-1.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gudev-1.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GUDEV_CFLAGS=`$PKG_CONFIG --cflags "gudev-1.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GUDEV_LIBS"; then
+ pkg_cv_GUDEV_LIBS="$GUDEV_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gudev-1.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gudev-1.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GUDEV_LIBS=`$PKG_CONFIG --libs "gudev-1.0" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GUDEV_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gudev-1.0" 2>&1`
+ else
+ GUDEV_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gudev-1.0" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GUDEV_PKG_ERRORS" >&5
+
+ have_gudev=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_gudev=no
+else
+ GUDEV_CFLAGS=$pkg_cv_GUDEV_CFLAGS
+ GUDEV_LIBS=$pkg_cv_GUDEV_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_gudev=yes
+fi
+
+ if test "x$have_gudev" = "xno" && test "x$enable_usbredir" = "xyes"; then
+ as_fn_error $? "usbredir requested but required gudev is not available" "$LINENO" 5
+ fi
+ if test "x$have_gudev" = "xyes"; then
+
+$as_echo "#define USE_GUDEV 1" >>confdefs.h
+
+ with_usbredir_hotplug="with gudev hotplug"
+ else
+ have_usbredir=no
+ fi
+ fi
+ fi
+
+ if test "x$have_usbredir" = "xyes"; then
+
+$as_echo "#define USE_USBREDIR 1" >>confdefs.h
+
+ fi
+fi
+ if test "x$have_usbredir" = "xyes"; then
+ WITH_USBREDIR_TRUE=
+ WITH_USBREDIR_FALSE='#'
+else
+ WITH_USBREDIR_TRUE='#'
+ WITH_USBREDIR_FALSE=
+fi
+
+
+# Check whether --enable-polkit was given.
+if test "${enable_polkit+set}" = set; then :
+ enableval=$enable_polkit;
+else
+ enable_polkit="auto"
+fi
+
+
+if test "x$have_usbredir" = "xyes" && test "x$enable_polkit" != "xno"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for POLKIT" >&5
+$as_echo_n "checking for POLKIT... " >&6; }
+
+if test -n "$POLKIT_CFLAGS"; then
+ pkg_cv_POLKIT_CFLAGS="$POLKIT_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"polkit-gobject-1 >= 0.96\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "polkit-gobject-1 >= 0.96") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_POLKIT_CFLAGS=`$PKG_CONFIG --cflags "polkit-gobject-1 >= 0.96" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$POLKIT_LIBS"; then
+ pkg_cv_POLKIT_LIBS="$POLKIT_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"polkit-gobject-1 >= 0.96\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "polkit-gobject-1 >= 0.96") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_POLKIT_LIBS=`$PKG_CONFIG --libs "polkit-gobject-1 >= 0.96" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ POLKIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "polkit-gobject-1 >= 0.96" 2>&1`
+ else
+ POLKIT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "polkit-gobject-1 >= 0.96" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$POLKIT_PKG_ERRORS" >&5
+
+ have_polkit=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_polkit=no
+else
+ POLKIT_CFLAGS=$pkg_cv_POLKIT_CFLAGS
+ POLKIT_LIBS=$pkg_cv_POLKIT_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_polkit=yes
+fi
+ ac_fn_c_check_header_mongrel "$LINENO" "acl/libacl.h" "ac_cv_header_acl_libacl_h" "$ac_includes_default"
+if test "x$ac_cv_header_acl_libacl_h" = xyes; then :
+
+else
+ have_polkit=no
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acl_get_file in -lacl" >&5
+$as_echo_n "checking for acl_get_file in -lacl... " >&6; }
+if ${ac_cv_lib_acl_acl_get_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lacl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char acl_get_file ();
+int
+main ()
+{
+return acl_get_file ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_acl_acl_get_file=yes
+else
+ ac_cv_lib_acl_acl_get_file=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_acl_acl_get_file" >&5
+$as_echo "$ac_cv_lib_acl_acl_get_file" >&6; }
+if test "x$ac_cv_lib_acl_acl_get_file" = xyes; then :
+ ACL_LIBS=-lacl
+else
+ have_polkit=no
+fi
+
+ if test "x$enable_polkit" = "xyes" && test "x$have_polkit" = "xno"; then
+ as_fn_error $? "PolicyKit support explicitly requested, but some required packages are not available" "$LINENO" 5
+ fi
+
+ if test "x$have_polkit" = "xyes"; then
+
+
+$as_echo "#define USE_POLKIT 1" >>confdefs.h
+
+ fi
+ if test "x$have_polkit" = "xyes"; then
+ WITH_POLKIT_TRUE=
+ WITH_POLKIT_FALSE='#'
+else
+ WITH_POLKIT_TRUE='#'
+ WITH_POLKIT_FALSE=
+fi
+
+ POLICYDIR=`${PKG_CONFIG} polkit-gobject-1 --variable=policydir`
+
+ # Check for polkit_authority_get_sync()
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for polkit_authority_get_sync in -lpolkit-gobject-1" >&5
+$as_echo_n "checking for polkit_authority_get_sync in -lpolkit-gobject-1... " >&6; }
+if ${ac_cv_lib_polkit_gobject_1_polkit_authority_get_sync+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpolkit-gobject-1 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char polkit_authority_get_sync ();
+int
+main ()
+{
+return polkit_authority_get_sync ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_polkit_gobject_1_polkit_authority_get_sync=yes
+else
+ ac_cv_lib_polkit_gobject_1_polkit_authority_get_sync=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_polkit_gobject_1_polkit_authority_get_sync" >&5
+$as_echo "$ac_cv_lib_polkit_gobject_1_polkit_authority_get_sync" >&6; }
+if test "x$ac_cv_lib_polkit_gobject_1_polkit_authority_get_sync" = xyes; then :
+ ac_have_pk_auth_get_sync="1"
+else
+ ac_have_pk_auth_get_sync="0"
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_POLKIT_AUTHORITY_GET_SYNC $ac_have_pk_auth_get_sync
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for polkit_authorization_result_get_dismissed in -lpolkit-gobject-1" >&5
+$as_echo_n "checking for polkit_authorization_result_get_dismissed in -lpolkit-gobject-1... " >&6; }
+if ${ac_cv_lib_polkit_gobject_1_polkit_authorization_result_get_dismissed+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpolkit-gobject-1 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char polkit_authorization_result_get_dismissed ();
+int
+main ()
+{
+return polkit_authorization_result_get_dismissed ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_polkit_gobject_1_polkit_authorization_result_get_dismissed=yes
+else
+ ac_cv_lib_polkit_gobject_1_polkit_authorization_result_get_dismissed=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_polkit_gobject_1_polkit_authorization_result_get_dismissed" >&5
+$as_echo "$ac_cv_lib_polkit_gobject_1_polkit_authorization_result_get_dismissed" >&6; }
+if test "x$ac_cv_lib_polkit_gobject_1_polkit_authorization_result_get_dismissed" = xyes; then :
+ ac_have_pk_authorization_result_get_dismissed="1"
+else
+ ac_have_pk_authorization_result_get_dismissed="0"
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_POLKIT_AUTHORIZATION_RESULT_GET_DISMISSED $ac_have_pk_authorization_result_get_dismissed
+_ACEOF
+
+else
+ if false; then
+ WITH_POLKIT_TRUE=
+ WITH_POLKIT_FALSE='#'
+else
+ WITH_POLKIT_TRUE='#'
+ WITH_POLKIT_FALSE=
+fi
+
+fi
+
+if test "x$have_usbredir" = "xyes" && test "x$have_polkit" != "xyes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Building with usbredir support, but *not* building the usb acl helper" >&5
+$as_echo "$as_me: WARNING: Building with usbredir support, but *not* building the usb acl helper" >&2;}
+fi
+
+# Check whether --enable-pie was given.
+if test "${enable_pie+set}" = set; then :
+ enableval=$enable_pie;
+else
+ enable_pie="auto"
+fi
+
+
+if test "x$have_polkit" = "xyes" && test "x$enable_pie" != "xno"; then
+ save_CFLAGS="$CFLAGS"
+ save_LDFLAGS="$LDFLAGS"
+ CFLAGS="$CFLAGS -fPIE"
+ LDFLAGS="$LDFLAGS -pie -Wl,-z,relro -Wl,-z,now"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PIE support" >&5
+$as_echo_n "checking for PIE support... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void main () {}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ have_pie=yes
+else
+ have_pie=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_pie" >&5
+$as_echo "$have_pie" >&6; }
+ if test "x$have_pie" = "xno" && test "x$enable_pie" = "xyes"; then
+ as_fn_error $? "pie support explicitly requested, but your toolchain does not support it" "$LINENO" 5
+ fi
+ if test "x$have_pie" = "xyes"; then
+ PIE_CFLAGS="-fPIE"
+ PIE_LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now"
+
+
+ fi
+ CFLAGS="$save_CFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+fi
+
+
+# Check whether --with-usb-acl-helper-dir was given.
+if test "${with_usb_acl_helper_dir+set}" = set; then :
+ withval=$with_usb_acl_helper_dir; ACL_HELPER_DIR="$with_usb_acl_helper_dir"
+else
+ ACL_HELPER_DIR="${bindir}/"
+fi
+
+
+
+
+# Check whether --with-usb-ids-path was given.
+if test "${with_usb_ids_path+set}" = set; then :
+ withval=$with_usb_ids_path; USB_IDS="$with_usb_ids_path"
+else
+ USB_IDS="auto"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for usb.ids" >&5
+$as_echo_n "checking for usb.ids... " >&6; }
+if test "x$USB_IDS" = "xauto"; then
+ if test -n "$PKG_CONFIG"; then
+ USB_IDS=$($PKG_CONFIG --variable=usbids usbutils)
+ else
+ USB_IDS=
+ fi
+fi
+if test -n "$USB_IDS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USB_IDS" >&5
+$as_echo "$USB_IDS" >&6; }
+
+
+$as_echo "#define WITH_USBIDS 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+$as_echo "not found" >&6; }
+fi
+
+
+# Check whether --with-coroutine was given.
+if test "${with_coroutine+set}" = set; then :
+ withval=$with_coroutine;
+else
+ with_coroutine=auto
+fi
+
+
+case $with_coroutine in
+ ucontext|gthread|winfiber|auto) ;;
+ *) as_fn_error $? "Unsupported coroutine type" "$LINENO" 5
+esac
+
+if test "$with_coroutine" = "auto"; then
+ if test "$os_win32" = "yes"; then
+ with_coroutine=winfiber
+ else
+ with_coroutine=ucontext
+ fi
+fi
+
+if test "$with_coroutine" = "ucontext"; then
+ ac_fn_c_check_func "$LINENO" "makecontext" "ac_cv_func_makecontext"
+if test "x$ac_cv_func_makecontext" = xyes; then :
+
+else
+ with_coroutine=gthread
+fi
+
+ ac_fn_c_check_func "$LINENO" "swapcontext" "ac_cv_func_swapcontext"
+if test "x$ac_cv_func_swapcontext" = xyes; then :
+
+else
+ with_coroutine=gthread
+fi
+
+ ac_fn_c_check_func "$LINENO" "getcontext" "ac_cv_func_getcontext"
+if test "x$ac_cv_func_getcontext" = xyes; then :
+
+else
+ with_coroutine=gthread
+fi
+
+fi
+
+WITH_UCONTEXT=0
+WITH_GTHREAD=0
+WITH_WINFIBER=0
+
+case $with_coroutine in
+ ucontext) WITH_UCONTEXT=1 ;;
+ gthread) WITH_GTHREAD=1 ;;
+ winfiber) WITH_WINFIBER=1 ;;
+ *) as_fn_error $? "Unsupported coroutine type" "$LINENO" 5
+esac
+
+
+cat >>confdefs.h <<_ACEOF
+#define WITH_UCONTEXT $WITH_UCONTEXT
+_ACEOF
+
+ if test "x$WITH_UCONTEXT" = "x1"; then
+ WITH_UCONTEXT_TRUE=
+ WITH_UCONTEXT_FALSE='#'
+else
+ WITH_UCONTEXT_TRUE='#'
+ WITH_UCONTEXT_FALSE=
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define WITH_WINFIBER $WITH_WINFIBER
+_ACEOF
+
+ if test "x$WITH_WINFIBER" = "x1"; then
+ WITH_WINFIBER_TRUE=
+ WITH_WINFIBER_FALSE='#'
+else
+ WITH_WINFIBER_TRUE='#'
+ WITH_WINFIBER_FALSE=
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define WITH_GTHREAD $WITH_GTHREAD
+_ACEOF
+
+ if test "x$WITH_GTHREAD" = "x1"; then
+ WITH_GTHREAD_TRUE=
+ WITH_GTHREAD_FALSE='#'
+else
+ WITH_GTHREAD_TRUE='#'
+ WITH_GTHREAD_FALSE=
+fi
+
+
+ if test "0" = "1"; then
+ HAVE_INTROSPECTION_TRUE=
+ HAVE_INTROSPECTION_FALSE='#'
+else
+ HAVE_INTROSPECTION_TRUE='#'
+ HAVE_INTROSPECTION_FALSE=
+fi
+
+
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"GOBJECT_INTROSPECTION\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "GOBJECT_INTROSPECTION") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ gobject-introspection-1.0 >= 0.9.4
+else
+ has_symbol_prefix=yes
+fi
+
+
+
+ # Check whether --enable-introspection was given.
+if test "${enable_introspection+set}" = set; then :
+ enableval=$enable_introspection;
+else
+ enable_introspection=auto
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gobject-introspection" >&5
+$as_echo_n "checking for gobject-introspection... " >&6; }
+
+ case $enable_introspection in #(
+ no) :
+ found_introspection="no (disabled, use --enable-introspection to enable)"
+ ;; #(
+ yes) :
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gobject-introspection-1.0\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gobject-introspection-1.0") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ :
+else
+ as_fn_error $? "gobject-introspection-1.0 is not installed" "$LINENO" 5
+fi
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gobject-introspection-1.0 >= 0.6.7\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gobject-introspection-1.0 >= 0.6.7") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ found_introspection=yes
+else
+ as_fn_error $? "You need to have gobject-introspection >= 0.6.7 installed to build spice-gtk" "$LINENO" 5
+fi
+ ;; #(
+ auto) :
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gobject-introspection-1.0 >= 0.6.7\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "gobject-introspection-1.0 >= 0.6.7") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ found_introspection=yes
+else
+ found_introspection=no
+fi
+ enable_introspection=$found_introspection
+ ;; #(
+ *) :
+ as_fn_error $? "invalid argument passed to --enable-introspection, should be one of [no/auto/yes]" "$LINENO" 5
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $found_introspection" >&5
+$as_echo "$found_introspection" >&6; }
+
+ INTROSPECTION_SCANNER=
+ INTROSPECTION_COMPILER=
+ INTROSPECTION_GENERATE=
+ INTROSPECTION_GIRDIR=
+ INTROSPECTION_TYPELIBDIR=
+ if test "x$found_introspection" = "xyes"; then
+ INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0`
+ INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0`
+ INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0`
+ INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0`
+ INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)"
+ INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0`
+ INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0`
+ INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection
+ fi
+
+
+
+
+
+
+
+
+
+ if test "x$found_introspection" = "xyes"; then
+ HAVE_INTROSPECTION_TRUE=
+ HAVE_INTROSPECTION_FALSE='#'
+else
+ HAVE_INTROSPECTION_TRUE='#'
+ HAVE_INTROSPECTION_FALSE=
+fi
+
+
+
+
+ if test "x$has_symbol_prefix" = "xyes"; then
+ G_IR_SCANNER_SYMBOL_PREFIX_TRUE=
+ G_IR_SCANNER_SYMBOL_PREFIX_FALSE='#'
+else
+ G_IR_SCANNER_SYMBOL_PREFIX_TRUE='#'
+ G_IR_SCANNER_SYMBOL_PREFIX_FALSE=
+fi
+
+
+# Check whether --enable-controller was given.
+if test "${enable_controller+set}" = set; then :
+ enableval=$enable_controller;
+else
+ enable_controller="yes"
+fi
+
+
+ if test "x$enable_controller" != "xno"; then
+ WITH_CONTROLLER_TRUE=
+ WITH_CONTROLLER_FALSE='#'
+else
+ WITH_CONTROLLER_TRUE='#'
+ WITH_CONTROLLER_FALSE=
+fi
+
+
+# Check whether --enable-vala was given.
+if test "${enable_vala+set}" = set; then :
+ enableval=$enable_vala;
+else
+ enable_vala="no"
+fi
+
+
+VALA_REQUIRED=0.14
+if test x$enable_vala = xyes ; then
+ # check for vala
+ # Extract the first word of "valac", so it can be a program name with args.
+set dummy valac; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_VALAC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $VALAC in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_VALAC="$VALAC" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_VALAC="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_VALAC" && ac_cv_path_VALAC="valac"
+ ;;
+esac
+fi
+VALAC=$ac_cv_path_VALAC
+if test -n "$VALAC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $VALAC" >&5
+$as_echo "$VALAC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "$VALAC" != valac && test -n "$VALA_REQUIRED"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $VALAC is at least version $VALA_REQUIRED" >&5
+$as_echo_n "checking whether $VALAC is at least version $VALA_REQUIRED... " >&6; }
+ am__vala_version=`$VALAC --version | sed 's/Vala *//'`
+ as_arg_v1=$VALA_REQUIRED
+as_arg_v2="$am__vala_version"
+awk "$as_awk_strverscmp" v1="$as_arg_v1" v2="$as_arg_v2" /dev/null
+case $? in #(
+ 1) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; } ;; #(
+ 0) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; } ;; #(
+ 2) :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ VALAC=valac ;; #(
+ *) :
+ ;;
+esac
+fi
+ if test "$VALAC" = valac; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no proper vala compiler found" >&5
+$as_echo "$as_me: WARNING: no proper vala compiler found" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: you will not be able to compile vala source files" >&5
+$as_echo "$as_me: WARNING: you will not be able to compile vala source files" >&2;}
+ else
+ :
+ fi
+ # Extract the first word of "vapigen", so it can be a program name with args.
+set dummy vapigen; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_VAPIGEN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $VAPIGEN in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_VAPIGEN="$VAPIGEN" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_VAPIGEN="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_VAPIGEN" && ac_cv_path_VAPIGEN="no"
+ ;;
+esac
+fi
+VAPIGEN=$ac_cv_path_VAPIGEN
+if test -n "$VAPIGEN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $VAPIGEN" >&5
+$as_echo "$VAPIGEN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$VAPIGEN" == "xno"; then
+ as_fn_error $? "Cannot find the \"vapigen\" binary in your PATH" "$LINENO" 5
+ fi
+
+fi
+
+ if test "x$enable_vala" = "xyes"; then
+ WITH_VALA_TRUE=
+ WITH_VALA_FALSE='#'
+else
+ WITH_VALA_TRUE='#'
+ WITH_VALA_FALSE=
+fi
+
+
+VAPIDIR="${datadir}/vala/vapi"
+
+
+# Check whether --enable-dbus was given.
+if test "${enable_dbus+set}" = set; then :
+ enableval=$enable_dbus;
+else
+ enable_dbus="auto"
+fi
+
+
+have_dbus=no
+if test "x$enable_dbus" != "xno"; then
+
+$as_echo "#define USE_GDBUS 1" >>confdefs.h
+
+ have_dbus=yes
+else
+ spice_warnings=$spice_warnings"|No D-Bus support, desktop integration and USB redirection may not work properly"
+fi
+
+
+ # Check whether --enable-lz4 was given.
+if test "${enable_lz4+set}" = set; then :
+ enableval=$enable_lz4;
+else
+ enable_lz4="auto"
+fi
+
+
+ have_lz4="no"
+ if test "x$enable_lz4" != "xno"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LZ4" >&5
+$as_echo_n "checking for LZ4... " >&6; }
+
+if test -n "$LZ4_CFLAGS"; then
+ pkg_cv_LZ4_CFLAGS="$LZ4_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LZ4_CFLAGS=`$PKG_CONFIG --cflags "liblz4" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$LZ4_LIBS"; then
+ pkg_cv_LZ4_LIBS="$LZ4_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblz4\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "liblz4") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LZ4_LIBS=`$PKG_CONFIG --libs "liblz4" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ LZ4_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblz4" 2>&1`
+ else
+ LZ4_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblz4" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$LZ4_PKG_ERRORS" >&5
+
+ have_lz4="no"
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_lz4="no"
+else
+ LZ4_CFLAGS=$pkg_cv_LZ4_CFLAGS
+ LZ4_LIBS=$pkg_cv_LZ4_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_lz4="yes"
+fi
+
+ if test "x$have_lz4" = "xyes"; then
+
+$as_echo "#define USE_LZ4 1" >>confdefs.h
+
+ elif test "x$enable_lz4" = "xyes"; then
+ as_fn_error $? "lz4 support requested but liblz4 could not be found" "$LINENO" 5
+ fi
+ fi
+ if test "x$have_lz4" = "xyes"; then
+ HAVE_LZ4_TRUE=
+ HAVE_LZ4_FALSE='#'
+else
+ HAVE_LZ4_TRUE='#'
+ HAVE_LZ4_FALSE=
+fi
+
+
+
+
+# some glib/gstreamer enums use 1 << 31
+dontwarn="-Wshift-overflow=2"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Werror -Wunknown-warning-option" >&5
+$as_echo_n "checking whether C compiler handles -Werror -Wunknown-warning-option... " >&6; }
+if ${gl_cv_warn_c__Werror__Wunknown_warning_option+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Werror -Wunknown-warning-option"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Werror__Wunknown_warning_option=yes
+else
+ gl_cv_warn_c__Werror__Wunknown_warning_option=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Werror__Wunknown_warning_option" >&5
+$as_echo "$gl_cv_warn_c__Werror__Wunknown_warning_option" >&6; }
+if test "x$gl_cv_warn_c__Werror__Wunknown_warning_option" = xyes; then :
+ gl_unknown_warnings_are_errors='-Wunknown-warning-option -Werror'
+else
+ gl_unknown_warnings_are_errors=
+fi
+
+
+
+ # Check whether --enable-werror was given.
+if test "${enable_werror+set}" = set; then :
+ enableval=$enable_werror; set_werror="$enableval"
+else
+ if test -d $srcdir/.git; then
+ is_git_version=true
+ set_werror=yes
+ else
+ set_werror=no
+ fi
+fi
+
+
+ # List of warnings that are not relevant / wanted
+
+ dontwarn=$dontwarn
+
+ # Don't care about C++ compiler compat
+ dontwarn="$dontwarn -Wc++-compat"
+ dontwarn="$dontwarn -Wabi"
+ dontwarn="$dontwarn -Wdeprecated"
+ # Don't care about ancient C standard compat
+ dontwarn="$dontwarn -Wtraditional"
+ # Don't care about ancient C standard compat
+ dontwarn="$dontwarn -Wtraditional-conversion"
+ # Ignore warnings in /usr/include
+ dontwarn="$dontwarn -Wsystem-headers"
+ # Happy for compiler to add struct padding
+ dontwarn="$dontwarn -Wpadded"
+ # GCC very confused with -O2
+ dontwarn="$dontwarn -Wunreachable-code"
+
+
+ dontwarn="$dontwarn -Wconversion"
+ dontwarn="$dontwarn -Wsign-conversion"
+ dontwarn="$dontwarn -Wvla"
+ dontwarn="$dontwarn -Wundef"
+ dontwarn="$dontwarn -Wcast-qual"
+ dontwarn="$dontwarn -Wlong-long"
+ dontwarn="$dontwarn -Wswitch-default"
+ dontwarn="$dontwarn -Wswitch-enum"
+ dontwarn="$dontwarn -Wstrict-overflow"
+ dontwarn="$dontwarn -Wunsafe-loop-optimizations"
+ dontwarn="$dontwarn -Wformat-nonliteral"
+ dontwarn="$dontwarn -Wfloat-equal"
+ dontwarn="$dontwarn -Wdeclaration-after-statement"
+ dontwarn="$dontwarn -Wcast-qual"
+ dontwarn="$dontwarn -Wconversion"
+ dontwarn="$dontwarn -Wsign-conversion"
+ dontwarn="$dontwarn -Wpacked"
+ dontwarn="$dontwarn -Wunused-macros"
+ dontwarn="$dontwarn -Woverlength-strings"
+ dontwarn="$dontwarn -Wstack-protector"
+ dontwarn="$dontwarn -Winline"
+ dontwarn="$dontwarn -Wbad-function-cast"
+ dontwarn="$dontwarn -Wshadow"
+
+ # Get all possible GCC warnings
+
+
+ if test -n "$GCC"; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wno-missing-field-initializers is supported" >&5
+$as_echo_n "checking whether -Wno-missing-field-initializers is supported... " >&6; }
+ if ${gl_cv_cc_nomfi_supported+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -W -Werror -Wno-missing-field-initializers"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gl_cv_cc_nomfi_supported=yes
+else
+ gl_cv_cc_nomfi_supported=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="$gl_save_CFLAGS"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_cc_nomfi_supported" >&5
+$as_echo "$gl_cv_cc_nomfi_supported" >&6; }
+
+ if test "$gl_cv_cc_nomfi_supported" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wno-missing-field-initializers is needed" >&5
+$as_echo_n "checking whether -Wno-missing-field-initializers is needed... " >&6; }
+ if ${gl_cv_cc_nomfi_needed+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -W -Werror"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+void f (void)
+ {
+ typedef struct { int a; int b; } s_t;
+ s_t s1 = { 0, };
+ }
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gl_cv_cc_nomfi_needed=no
+else
+ gl_cv_cc_nomfi_needed=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="$gl_save_CFLAGS"
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_cc_nomfi_needed" >&5
+$as_echo "$gl_cv_cc_nomfi_needed" >&6; }
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -Wuninitialized is supported" >&5
+$as_echo_n "checking whether -Wuninitialized is supported... " >&6; }
+ if ${gl_cv_cc_uninitialized_supported+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Werror -Wuninitialized"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gl_cv_cc_uninitialized_supported=yes
+else
+ gl_cv_cc_uninitialized_supported=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="$gl_save_CFLAGS"
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_cc_uninitialized_supported" >&5
+$as_echo "$gl_cv_cc_uninitialized_supported" >&6; }
+
+ fi
+
+ # List all gcc warning categories.
+ # To compare this list to your installed GCC's, run this Bash command:
+ #
+ # comm -3 \
+ # <(sed -n 's/^ *\(-[^ ]*\) .*/\1/p' manywarnings.m4 | sort) \
+ # <(gcc --help=warnings | sed -n 's/^ \(-[^ ]*\) .*/\1/p' | sort |
+ # grep -v -x -f <(
+ # awk '/^[^#]/ {print maybewarn}' ../build-aux/gcc-warning.spec))
+
+ gl_manywarn_set=
+ for gl_manywarn_item in \
+ -W \
+ -Wabi \
+ -Waddress \
+ -Waggressive-loop-optimizations \
+ -Wall \
+ -Wattributes \
+ -Wbad-function-cast \
+ -Wbool-compare \
+ -Wbuiltin-macro-redefined \
+ -Wcast-align \
+ -Wchar-subscripts \
+ -Wchkp \
+ -Wclobbered \
+ -Wcomment \
+ -Wcomments \
+ -Wcoverage-mismatch \
+ -Wcpp \
+ -Wdate-time \
+ -Wdeprecated \
+ -Wdeprecated-declarations \
+ -Wdesignated-init \
+ -Wdisabled-optimization \
+ -Wdiscarded-array-qualifiers \
+ -Wdiscarded-qualifiers \
+ -Wdiv-by-zero \
+ -Wdouble-promotion \
+ -Wduplicated-cond \
+ -Wempty-body \
+ -Wendif-labels \
+ -Wenum-compare \
+ -Wextra \
+ -Wformat-contains-nul \
+ -Wformat-extra-args \
+ -Wformat-nonliteral \
+ -Wformat-security \
+ -Wformat-signedness \
+ -Wformat-y2k \
+ -Wformat-zero-length \
+ -Wframe-address \
+ -Wfree-nonheap-object \
+ -Whsa \
+ -Wignored-attributes \
+ -Wignored-qualifiers \
+ -Wimplicit \
+ -Wimplicit-function-declaration \
+ -Wimplicit-int \
+ -Wincompatible-pointer-types \
+ -Winit-self \
+ -Winline \
+ -Wint-conversion \
+ -Wint-to-pointer-cast \
+ -Winvalid-memory-model \
+ -Winvalid-pch \
+ -Wjump-misses-init \
+ -Wlogical-not-parentheses \
+ -Wlogical-op \
+ -Wmain \
+ -Wmaybe-uninitialized \
+ -Wmemset-transposed-args \
+ -Wmisleading-indentation \
+ -Wmissing-braces \
+ -Wmissing-declarations \
+ -Wmissing-field-initializers \
+ -Wmissing-include-dirs \
+ -Wmissing-parameter-type \
+ -Wmissing-prototypes \
+ -Wmultichar \
+ -Wnarrowing \
+ -Wnested-externs \
+ -Wnonnull \
+ -Wnonnull-compare \
+ -Wnull-dereference \
+ -Wodr \
+ -Wold-style-declaration \
+ -Wold-style-definition \
+ -Wopenmp-simd \
+ -Woverflow \
+ -Woverlength-strings \
+ -Woverride-init \
+ -Wpacked \
+ -Wpacked-bitfield-compat \
+ -Wparentheses \
+ -Wpointer-arith \
+ -Wpointer-sign \
+ -Wpointer-to-int-cast \
+ -Wpragmas \
+ -Wreturn-local-addr \
+ -Wreturn-type \
+ -Wscalar-storage-order \
+ -Wsequence-point \
+ -Wshadow \
+ -Wshift-count-negative \
+ -Wshift-count-overflow \
+ -Wshift-negative-value \
+ -Wsizeof-array-argument \
+ -Wsizeof-pointer-memaccess \
+ -Wstack-protector \
+ -Wstrict-aliasing \
+ -Wstrict-overflow \
+ -Wstrict-prototypes \
+ -Wsuggest-attribute=const \
+ -Wsuggest-attribute=format \
+ -Wsuggest-attribute=noreturn \
+ -Wsuggest-attribute=pure \
+ -Wsuggest-final-methods \
+ -Wsuggest-final-types \
+ -Wswitch \
+ -Wswitch-bool \
+ -Wswitch-default \
+ -Wsync-nand \
+ -Wsystem-headers \
+ -Wtautological-compare \
+ -Wtrampolines \
+ -Wtrigraphs \
+ -Wtype-limits \
+ -Wuninitialized \
+ -Wunknown-pragmas \
+ -Wunsafe-loop-optimizations \
+ -Wunused \
+ -Wunused-but-set-parameter \
+ -Wunused-but-set-variable \
+ -Wunused-function \
+ -Wunused-label \
+ -Wunused-local-typedefs \
+ -Wunused-macros \
+ -Wunused-parameter \
+ -Wunused-result \
+ -Wunused-value \
+ -Wunused-variable \
+ -Wvarargs \
+ -Wvariadic-macros \
+ -Wvector-operation-performance \
+ -Wvla \
+ -Wvolatile-register-var \
+ -Wwrite-strings \
+ \
+ ; do
+ gl_manywarn_set="$gl_manywarn_set $gl_manywarn_item"
+ done
+
+ # gcc --help=warnings outputs an unusual form for these options; list
+ # them here so that the above 'comm' command doesn't report a false match.
+ gl_manywarn_set="$gl_manywarn_set -Warray-bounds=2"
+ gl_manywarn_set="$gl_manywarn_set -Wnormalized=nfc"
+ gl_manywarn_set="$gl_manywarn_set -Wshift-overflow=2"
+ gl_manywarn_set="$gl_manywarn_set -Wunused-const-variable=2"
+
+ # These are needed for older GCC versions.
+ if test -n "$GCC"; then
+ case `($CC --version) 2>/dev/null` in
+ 'gcc (GCC) '[0-3].* | \
+ 'gcc (GCC) '4.[0-7].*)
+ gl_manywarn_set="$gl_manywarn_set -fdiagnostics-show-option"
+ gl_manywarn_set="$gl_manywarn_set -funit-at-a-time"
+ ;;
+ esac
+ fi
+
+ # Disable specific options as needed.
+ if test "$gl_cv_cc_nomfi_needed" = yes; then
+ gl_manywarn_set="$gl_manywarn_set -Wno-missing-field-initializers"
+ fi
+
+ if test "$gl_cv_cc_uninitialized_supported" = no; then
+ gl_manywarn_set="$gl_manywarn_set -Wno-uninitialized"
+ fi
+
+ maybewarn=$gl_manywarn_set
+
+
+ # Remove the ones we don't want, blacklisted earlier
+
+ gl_warn_set=
+ set x $maybewarn; shift
+ for gl_warn_item
+ do
+ case " $dontwarn " in
+ *" $gl_warn_item "*)
+ ;;
+ *)
+ gl_warn_set="$gl_warn_set $gl_warn_item"
+ ;;
+ esac
+ done
+ wantwarn=$gl_warn_set
+
+
+ # Check for $CC support of each warning
+ for w in $wantwarn; do
+
+as_gl_Warn=`$as_echo "gl_cv_warn_c_$w" | $as_tr_sh`
+gl_positive="$w"
+case $gl_positive in
+ -Wno-*) gl_positive=-W`expr "X$gl_positive" : 'X-Wno-\(.*\)'` ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles $w" >&5
+$as_echo_n "checking whether C compiler handles $w... " >&6; }
+if eval \${$as_gl_Warn+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors $gl_positive"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$as_gl_Warn=yes"
+else
+ eval "$as_gl_Warn=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+eval ac_res=\$$as_gl_Warn
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_gl_Warn"\" = x"yes"; then :
+ as_fn_append WARN_CFLAGS " $w"
+fi
+
+
+ done
+
+ # GNULIB uses '-W' (aka -Wextra) which includes a bunch of stuff.
+ # Unfortunately, this means you can't simply use '-Wsign-compare'
+ # with gl_MANYWARN_COMPLEMENT
+ # So we have -W enabled, and then have to explicitly turn off...
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wno-sign-compare" >&5
+$as_echo_n "checking whether C compiler handles -Wno-sign-compare... " >&6; }
+if ${gl_cv_warn_c__Wno_sign_compare+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wsign-compare"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Wno_sign_compare=yes
+else
+ gl_cv_warn_c__Wno_sign_compare=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wno_sign_compare" >&5
+$as_echo "$gl_cv_warn_c__Wno_sign_compare" >&6; }
+if test "x$gl_cv_warn_c__Wno_sign_compare" = xyes; then :
+ as_fn_append WARN_CFLAGS " -Wno-sign-compare"
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wno-unused-parameter" >&5
+$as_echo_n "checking whether C compiler handles -Wno-unused-parameter... " >&6; }
+if ${gl_cv_warn_c__Wno_unused_parameter+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wunused-parameter"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Wno_unused_parameter=yes
+else
+ gl_cv_warn_c__Wno_unused_parameter=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wno_unused_parameter" >&5
+$as_echo "$gl_cv_warn_c__Wno_unused_parameter" >&6; }
+if test "x$gl_cv_warn_c__Wno_unused_parameter" = xyes; then :
+ as_fn_append WARN_CFLAGS " -Wno-unused-parameter"
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wno-missing-field-initializers" >&5
+$as_echo_n "checking whether C compiler handles -Wno-missing-field-initializers... " >&6; }
+if ${gl_cv_warn_c__Wno_missing_field_initializers+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wmissing-field-initializers"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Wno_missing_field_initializers=yes
+else
+ gl_cv_warn_c__Wno_missing_field_initializers=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wno_missing_field_initializers" >&5
+$as_echo "$gl_cv_warn_c__Wno_missing_field_initializers" >&6; }
+if test "x$gl_cv_warn_c__Wno_missing_field_initializers" = xyes; then :
+ as_fn_append WARN_CFLAGS " -Wno-missing-field-initializers"
+fi
+
+
+ # We can't enable this due to horrible spice_usb_device_get_description
+ # signature
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wno-format-nonliteral" >&5
+$as_echo_n "checking whether C compiler handles -Wno-format-nonliteral... " >&6; }
+if ${gl_cv_warn_c__Wno_format_nonliteral+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wformat-nonliteral"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Wno_format_nonliteral=yes
+else
+ gl_cv_warn_c__Wno_format_nonliteral=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wno_format_nonliteral" >&5
+$as_echo "$gl_cv_warn_c__Wno_format_nonliteral" >&6; }
+if test "x$gl_cv_warn_c__Wno_format_nonliteral" = xyes; then :
+ as_fn_append WARN_CFLAGS " -Wno-format-nonliteral"
+fi
+
+
+ # We use some deprecated functions to avoid #ifdef hell while maintaining
+ # compat with older gtk / glib versions
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wno-deprecated-declarations" >&5
+$as_echo_n "checking whether C compiler handles -Wno-deprecated-declarations... " >&6; }
+if ${gl_cv_warn_c__Wno_deprecated_declarations+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wdeprecated-declarations"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Wno_deprecated_declarations=yes
+else
+ gl_cv_warn_c__Wno_deprecated_declarations=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wno_deprecated_declarations" >&5
+$as_echo "$gl_cv_warn_c__Wno_deprecated_declarations" >&6; }
+if test "x$gl_cv_warn_c__Wno_deprecated_declarations" = xyes; then :
+ as_fn_append WARN_CFLAGS " -Wno-deprecated-declarations"
+fi
+
+
+
+
+
+ # GNULIB expects this to be part of -Wc++-compat, but we turn
+ # that one off, so we need to manually enable this again
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wjump-misses-init" >&5
+$as_echo_n "checking whether C compiler handles -Wjump-misses-init... " >&6; }
+if ${gl_cv_warn_c__Wjump_misses_init+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wjump-misses-init"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Wjump_misses_init=yes
+else
+ gl_cv_warn_c__Wjump_misses_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wjump_misses_init" >&5
+$as_echo "$gl_cv_warn_c__Wjump_misses_init" >&6; }
+if test "x$gl_cv_warn_c__Wjump_misses_init" = xyes; then :
+ as_fn_append WARN_CFLAGS " -Wjump-misses-init"
+fi
+
+
+
+ # GNULIB turns on -Wformat=2 which implies -Wformat-nonliteral,
+ # so we need to manually re-exclude it.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wno-format-nonliteral" >&5
+$as_echo_n "checking whether C compiler handles -Wno-format-nonliteral... " >&6; }
+if ${gl_cv_warn_c__Wno_format_nonliteral+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wformat-nonliteral"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Wno_format_nonliteral=yes
+else
+ gl_cv_warn_c__Wno_format_nonliteral=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wno_format_nonliteral" >&5
+$as_echo "$gl_cv_warn_c__Wno_format_nonliteral" >&6; }
+if test "x$gl_cv_warn_c__Wno_format_nonliteral" = xyes; then :
+ as_fn_append WARN_CFLAGS " -Wno-format-nonliteral"
+fi
+
+
+
+ # This should be < 1024 really. pixman_utils is the blackspot
+ # preventing lower usage
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wframe-larger-than=9216" >&5
+$as_echo_n "checking whether C compiler handles -Wframe-larger-than=9216... " >&6; }
+if ${gl_cv_warn_c__Wframe_larger_than_9216+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wframe-larger-than=9216"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Wframe_larger_than_9216=yes
+else
+ gl_cv_warn_c__Wframe_larger_than_9216=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wframe_larger_than_9216" >&5
+$as_echo "$gl_cv_warn_c__Wframe_larger_than_9216" >&6; }
+if test "x$gl_cv_warn_c__Wframe_larger_than_9216" = xyes; then :
+ as_fn_append WARN_CFLAGS " -Wframe-larger-than=9216"
+fi
+
+
+
+ # Use improved glibc headers
+
+
+ # Extra special flags
+ case $host in
+ *-*-linux*)
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fstack-protector-all" >&5
+$as_echo_n "checking whether C compiler handles -fstack-protector-all... " >&6; }
+if ${gl_cv_warn_c__fstack_protector_all+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fstack-protector-all"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__fstack_protector_all=yes
+else
+ gl_cv_warn_c__fstack_protector_all=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fstack_protector_all" >&5
+$as_echo "$gl_cv_warn_c__fstack_protector_all" >&6; }
+if test "x$gl_cv_warn_c__fstack_protector_all" = xyes; then :
+ as_fn_append WARN_CFLAGS " -fstack-protector-all"
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles --param=ssp-buffer-size=4" >&5
+$as_echo_n "checking whether C compiler handles --param=ssp-buffer-size=4... " >&6; }
+if ${gl_cv_warn_c___param_ssp_buffer_size_4+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors --param=ssp-buffer-size=4"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c___param_ssp_buffer_size_4=yes
+else
+ gl_cv_warn_c___param_ssp_buffer_size_4=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c___param_ssp_buffer_size_4" >&5
+$as_echo "$gl_cv_warn_c___param_ssp_buffer_size_4" >&6; }
+if test "x$gl_cv_warn_c___param_ssp_buffer_size_4" = xyes; then :
+ as_fn_append WARN_CFLAGS " --param=ssp-buffer-size=4"
+fi
+
+
+ ;;
+ esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fexceptions" >&5
+$as_echo_n "checking whether C compiler handles -fexceptions... " >&6; }
+if ${gl_cv_warn_c__fexceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fexceptions"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__fexceptions=yes
+else
+ gl_cv_warn_c__fexceptions=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fexceptions" >&5
+$as_echo "$gl_cv_warn_c__fexceptions" >&6; }
+if test "x$gl_cv_warn_c__fexceptions" = xyes; then :
+ as_fn_append WARN_CFLAGS " -fexceptions"
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fasynchronous-unwind-tables" >&5
+$as_echo_n "checking whether C compiler handles -fasynchronous-unwind-tables... " >&6; }
+if ${gl_cv_warn_c__fasynchronous_unwind_tables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fasynchronous-unwind-tables"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__fasynchronous_unwind_tables=yes
+else
+ gl_cv_warn_c__fasynchronous_unwind_tables=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fasynchronous_unwind_tables" >&5
+$as_echo "$gl_cv_warn_c__fasynchronous_unwind_tables" >&6; }
+if test "x$gl_cv_warn_c__fasynchronous_unwind_tables" = xyes; then :
+ as_fn_append WARN_CFLAGS " -fasynchronous-unwind-tables"
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fdiagnostics-show-option" >&5
+$as_echo_n "checking whether C compiler handles -fdiagnostics-show-option... " >&6; }
+if ${gl_cv_warn_c__fdiagnostics_show_option+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fdiagnostics-show-option"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__fdiagnostics_show_option=yes
+else
+ gl_cv_warn_c__fdiagnostics_show_option=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fdiagnostics_show_option" >&5
+$as_echo "$gl_cv_warn_c__fdiagnostics_show_option" >&6; }
+if test "x$gl_cv_warn_c__fdiagnostics_show_option" = xyes; then :
+ as_fn_append WARN_CFLAGS " -fdiagnostics-show-option"
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -funit-at-a-time" >&5
+$as_echo_n "checking whether C compiler handles -funit-at-a-time... " >&6; }
+if ${gl_cv_warn_c__funit_at_a_time+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -funit-at-a-time"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__funit_at_a_time=yes
+else
+ gl_cv_warn_c__funit_at_a_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__funit_at_a_time" >&5
+$as_echo "$gl_cv_warn_c__funit_at_a_time" >&6; }
+if test "x$gl_cv_warn_c__funit_at_a_time" = xyes; then :
+ as_fn_append WARN_CFLAGS " -funit-at-a-time"
+fi
+
+
+
+ # Need -fipa-pure-const in order to make -Wsuggest-attribute=pure
+ # fire even without -O.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -fipa-pure-const" >&5
+$as_echo_n "checking whether C compiler handles -fipa-pure-const... " >&6; }
+if ${gl_cv_warn_c__fipa_pure_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -fipa-pure-const"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__fipa_pure_const=yes
+else
+ gl_cv_warn_c__fipa_pure_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__fipa_pure_const" >&5
+$as_echo "$gl_cv_warn_c__fipa_pure_const" >&6; }
+if test "x$gl_cv_warn_c__fipa_pure_const" = xyes; then :
+ as_fn_append WARN_CFLAGS " -fipa-pure-const"
+fi
+
+
+
+ # We should eventually enable this, but right now there are at
+ # least 75 functions triggering warnings.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wno-suggest-attribute=pure" >&5
+$as_echo_n "checking whether C compiler handles -Wno-suggest-attribute=pure... " >&6; }
+if ${gl_cv_warn_c__Wno_suggest_attribute_pure+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wsuggest-attribute=pure"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Wno_suggest_attribute_pure=yes
+else
+ gl_cv_warn_c__Wno_suggest_attribute_pure=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wno_suggest_attribute_pure" >&5
+$as_echo "$gl_cv_warn_c__Wno_suggest_attribute_pure" >&6; }
+if test "x$gl_cv_warn_c__Wno_suggest_attribute_pure" = xyes; then :
+ as_fn_append WARN_CFLAGS " -Wno-suggest-attribute=pure"
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wno-suggest-attribute=const" >&5
+$as_echo_n "checking whether C compiler handles -Wno-suggest-attribute=const... " >&6; }
+if ${gl_cv_warn_c__Wno_suggest_attribute_const+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wsuggest-attribute=const"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Wno_suggest_attribute_const=yes
+else
+ gl_cv_warn_c__Wno_suggest_attribute_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wno_suggest_attribute_const" >&5
+$as_echo "$gl_cv_warn_c__Wno_suggest_attribute_const" >&6; }
+if test "x$gl_cv_warn_c__Wno_suggest_attribute_const" = xyes; then :
+ as_fn_append WARN_CFLAGS " -Wno-suggest-attribute=const"
+fi
+
+
+
+ if test "$set_werror" = "yes"
+ then
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Werror" >&5
+$as_echo_n "checking whether C compiler handles -Werror... " >&6; }
+if ${gl_cv_warn_c__Werror+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Werror"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Werror=yes
+else
+ gl_cv_warn_c__Werror=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Werror" >&5
+$as_echo "$gl_cv_warn_c__Werror" >&6; }
+if test "x$gl_cv_warn_c__Werror" = xyes; then :
+ as_fn_append WARN_CFLAGS " -Werror"
+fi
+
+
+ fi
+
+ WARN_LDFLAGS=$WARN_CFLAGS
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler handles -Wno-write-strings" >&5
+$as_echo_n "checking whether C compiler handles -Wno-write-strings... " >&6; }
+if ${gl_cv_warn_c__Wno_write_strings+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ gl_save_compiler_FLAGS="$CFLAGS"
+ as_fn_append CFLAGS " $gl_unknown_warnings_are_errors -Wwrite-strings"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gl_cv_warn_c__Wno_write_strings=yes
+else
+ gl_cv_warn_c__Wno_write_strings=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS="$gl_save_compiler_FLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_warn_c__Wno_write_strings" >&5
+$as_echo "$gl_cv_warn_c__Wno_write_strings" >&6; }
+if test "x$gl_cv_warn_c__Wno_write_strings" = xyes; then :
+ as_fn_append WARN_CFLAGS " -Wno-write-strings"
+fi
+
+
+ WARN_PYFLAGS=$WARN_CFLAGS
+
+
+
+SPICE_CFLAGS="$SPICE_CFLAGS $WARN_CFLAGS"
+
+
+
+SPICE_GLIB_CFLAGS="$PIXMAN_CFLAGS $PULSE_CFLAGS $GSTAUDIO_CFLAGS $GSTVIDEO_CFLAGS $GLIB2_CFLAGS $GIO_CFLAGS $GOBJECT2_CFLAGS $SSL_CFLAGS $SASL_CFLAGS"
+SPICE_GTK_CFLAGS="$SPICE_GLIB_CFLAGS $GTK_CFLAGS "
+
+
+
+
+
+
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+
+ if test x"$enable_static" = xyes; then
+ BUILD_TESTS_TRUE=
+ BUILD_TESTS_FALSE='#'
+else
+ BUILD_TESTS_TRUE='#'
+ BUILD_TESTS_FALSE=
+fi
+
+
+ac_config_files="$ac_config_files Makefile spice-client-glib-2.0.pc spice-client-gtk-3.0.pc spice-controller.pc data/Makefile po/Makefile.in src/Makefile src/spice-version.h src/controller/Makefile doc/Makefile doc/reference/Makefile man/Makefile vapi/Makefile tests/Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ ac_libobjs=$ac_libobjs" \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ ac_ltlibobjs=$ac_ltlibobjs" \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+ ac_config_commands="$ac_config_commands po/stamp-it"
+
+
+if test -z "${HAVE_GTK_DOC_TRUE}" && test -z "${HAVE_GTK_DOC_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_GTK_DOC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_GTK_DOC_TRUE}" && test -z "${ENABLE_GTK_DOC_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_GTK_DOC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${GTK_DOC_BUILD_HTML_TRUE}" && test -z "${GTK_DOC_BUILD_HTML_FALSE}"; then
+ as_fn_error $? "conditional \"GTK_DOC_BUILD_HTML\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${GTK_DOC_BUILD_PDF_TRUE}" && test -z "${GTK_DOC_BUILD_PDF_FALSE}"; then
+ as_fn_error $? "conditional \"GTK_DOC_BUILD_PDF\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${GTK_DOC_USE_LIBTOOL_TRUE}" && test -z "${GTK_DOC_USE_LIBTOOL_FALSE}"; then
+ as_fn_error $? "conditional \"GTK_DOC_USE_LIBTOOL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${GTK_DOC_USE_REBASE_TRUE}" && test -z "${GTK_DOC_USE_REBASE_FALSE}"; then
+ as_fn_error $? "conditional \"GTK_DOC_USE_REBASE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+if test -z "${HAVE_LD_VERSION_SCRIPT_TRUE}" && test -z "${HAVE_LD_VERSION_SCRIPT_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_LD_VERSION_SCRIPT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${OS_WIN32_TRUE}" && test -z "${OS_WIN32_FALSE}"; then
+ as_fn_error $? "conditional \"OS_WIN32\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_GTK_TRUE}" && test -z "${WITH_GTK_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_GTK\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${USE_INTERNAL_PNP_IDS_TRUE}" && test -z "${USE_INTERNAL_PNP_IDS_FALSE}"; then
+ as_fn_error $? "conditional \"USE_INTERNAL_PNP_IDS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_PHODAV_TRUE}" && test -z "${WITH_PHODAV_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_PHODAV\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_PULSE_TRUE}" && test -z "${HAVE_PULSE_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_PULSE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_GSTAUDIO_TRUE}" && test -z "${HAVE_GSTAUDIO_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_GSTAUDIO\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_GSTVIDEO_TRUE}" && test -z "${HAVE_GSTVIDEO_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_GSTVIDEO\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_BUILTIN_MJPEG_TRUE}" && test -z "${HAVE_BUILTIN_MJPEG_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_BUILTIN_MJPEG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_SMARTCARD_TRUE}" && test -z "${HAVE_SMARTCARD_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_SMARTCARD\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_SMARTCARD_TRUE}" && test -z "${WITH_SMARTCARD_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_SMARTCARD\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_USBREDIR_TRUE}" && test -z "${WITH_USBREDIR_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_USBREDIR\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_POLKIT_TRUE}" && test -z "${WITH_POLKIT_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_POLKIT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_POLKIT_TRUE}" && test -z "${WITH_POLKIT_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_POLKIT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_UCONTEXT_TRUE}" && test -z "${WITH_UCONTEXT_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_UCONTEXT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_WINFIBER_TRUE}" && test -z "${WITH_WINFIBER_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_WINFIBER\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_GTHREAD_TRUE}" && test -z "${WITH_GTHREAD_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_GTHREAD\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_INTROSPECTION_TRUE}" && test -z "${HAVE_INTROSPECTION_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_INTROSPECTION\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_INTROSPECTION_TRUE}" && test -z "${HAVE_INTROSPECTION_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_INTROSPECTION\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${G_IR_SCANNER_SYMBOL_PREFIX_TRUE}" && test -z "${G_IR_SCANNER_SYMBOL_PREFIX_FALSE}"; then
+ as_fn_error $? "conditional \"G_IR_SCANNER_SYMBOL_PREFIX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_CONTROLLER_TRUE}" && test -z "${WITH_CONTROLLER_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_CONTROLLER\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${WITH_VALA_TRUE}" && test -z "${WITH_VALA_FALSE}"; then
+ as_fn_error $? "conditional \"WITH_VALA\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_LZ4_TRUE}" && test -z "${HAVE_LZ4_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_LZ4\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUILD_TESTS_TRUE}" && test -z "${BUILD_TESTS_FALSE}"; then
+ as_fn_error $? "conditional \"BUILD_TESTS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by spice-gtk $as_me 0.33, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <spice-devel@lists.freedesktop.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+spice-gtk config.status 0.33
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ CONFIG_FILES=$CONFIG_FILES" '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_HEADERS=$CONFIG_HEADERS" '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) ac_config_targets=$ac_config_targets" $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
+configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in AS \
+DLLTOOL \
+OBJDUMP \
+SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_import \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_cv_nm_interface \
+nm_file_list_spec \
+lt_cv_truncate_bin \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+configure_time_dlsearch_path \
+configure_time_lt_sys_library_path; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "spice-client-glib-2.0.pc") CONFIG_FILES="$CONFIG_FILES spice-client-glib-2.0.pc" ;;
+ "spice-client-gtk-3.0.pc") CONFIG_FILES="$CONFIG_FILES spice-client-gtk-3.0.pc" ;;
+ "spice-controller.pc") CONFIG_FILES="$CONFIG_FILES spice-controller.pc" ;;
+ "data/Makefile") CONFIG_FILES="$CONFIG_FILES data/Makefile" ;;
+ "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;;
+ "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+ "src/spice-version.h") CONFIG_FILES="$CONFIG_FILES src/spice-version.h" ;;
+ "src/controller/Makefile") CONFIG_FILES="$CONFIG_FILES src/controller/Makefile" ;;
+ "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "doc/reference/Makefile") CONFIG_FILES="$CONFIG_FILES doc/reference/Makefile" ;;
+ "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
+ "vapi/Makefile") CONFIG_FILES="$CONFIG_FILES vapi/Makefile" ;;
+ "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+ "po/stamp-it") CONFIG_COMMANDS="$CONFIG_COMMANDS po/stamp-it" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = "\a"
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = "\a"
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ ac_file_inputs=$ac_file_inputs" '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "$am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=''
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Assembler program.
+AS=$lt_AS
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Object dumper program.
+OBJDUMP=$lt_OBJDUMP
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shared archive member basename,for filename based shared library versioning on AIX.
+shared_archive_member_spec=$shared_archive_member_spec
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm into a list of symbols to manually relocate.
+global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name lister interface.
+nm_interface=$lt_lt_cv_nm_interface
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and where our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# Command to truncate a binary pipe.
+lt_truncate_bin=$lt_lt_cv_truncate_bin
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Detected run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
+
+# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
+configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+ ;;
+ "default-1":C) case "$CONFIG_FILES" in *po/Makefile.in*)
+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
+ esac ;;
+ "po/stamp-it":C)
+ if ! grep "^# INTLTOOL_MAKEFILE$" "po/Makefile.in" > /dev/null ; then
+ as_fn_error $? "po/Makefile.in.in was not created by intltoolize." "$LINENO" 5
+ fi
+ rm -f "po/stamp-it" "po/stamp-it.tmp" "po/POTFILES" "po/Makefile.tmp"
+ >"po/stamp-it.tmp"
+ sed '/^#/d
+ s/^[[].*] *//
+ /^[ ]*$/d
+ '"s|^| $ac_top_srcdir/|" \
+ "$srcdir/po/POTFILES.in" | sed '$!s/$/ \\/' >"po/POTFILES"
+
+ sed '/^POTFILES =/,/[^\\]$/ {
+ /^POTFILES =/!d
+ r po/POTFILES
+ }
+ ' "po/Makefile.in" >"po/Makefile"
+ rm -f "po/Makefile.tmp"
+ mv "po/stamp-it.tmp" "po/stamp-it"
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+
+#
+# CONFIG_SUBDIRS section.
+#
+if test "$no_recursion" != yes; then
+
+ # Remove --cache-file, --srcdir, and --disable-option-checking arguments
+ # so they do not pile up.
+ ac_sub_configure_args=
+ ac_prev=
+ eval "set x $ac_configure_args"
+ shift
+ for ac_arg
+ do
+ if test -n "$ac_prev"; then
+ ac_prev=
+ continue
+ fi
+ case $ac_arg in
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \
+ | --c=*)
+ ;;
+ --config-cache | -C)
+ ;;
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ ;;
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ ;;
+ --disable-option-checking)
+ ;;
+ *)
+ case $ac_arg in
+ *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ ac_sub_configure_args=$ac_sub_configure_args" '$ac_arg'" ;;
+ esac
+ done
+
+ # Always prepend --prefix to ensure using the same prefix
+ # in subdir configurations.
+ ac_arg="--prefix=$prefix"
+ case $ac_arg in
+ *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args"
+
+ # Pass --silent
+ if test "$silent" = yes; then
+ ac_sub_configure_args="--silent $ac_sub_configure_args"
+ fi
+
+ # Always prepend --disable-option-checking to silence warnings, since
+ # different subdirs can have different --enable and --with options.
+ ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args"
+
+ ac_popdir=`pwd`
+ for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue
+
+ # Do not complain, so a configure script can configure whichever
+ # parts of a large source tree are present.
+ test -d "$srcdir/$ac_dir" || continue
+
+ ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)"
+ $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5
+ $as_echo "$ac_msg" >&6
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ cd "$ac_dir"
+
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ ac_sub_configure=$ac_srcdir/configure.gnu
+ elif test -f "$ac_srcdir/configure"; then
+ ac_sub_configure=$ac_srcdir/configure
+ elif test -f "$ac_srcdir/configure.in"; then
+ # This should be Cygnus configure.
+ ac_sub_configure=$ac_aux_dir/configure
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5
+$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
+ ac_sub_configure=
+ fi
+
+ # The recursion is here.
+ if test -n "$ac_sub_configure"; then
+ # Make the cache file name correct relative to the subdirectory.
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;;
+ *) # Relative name.
+ ac_sub_cache_file=$ac_top_build_prefix$cache_file ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
+$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
+ # The eval makes quoting arguments work.
+ eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \
+ --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" ||
+ as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5
+ fi
+
+ cd "$ac_popdir"
+ done
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}:
+
+ Spice-Gtk $VERSION
+ ==============
+
+ prefix: ${prefix}
+ c compiler: ${CC}
+ Target: ${red_target}
+
+ Gtk: ${with_gtk}
+ Coroutine: ${with_coroutine}
+ PulseAudio: ${enable_pulse}
+ GStreamer Audio: ${have_gstaudio}
+ GStreamer Video: ${have_gstvideo}
+ SASL support: ${have_sasl}
+ Smartcard support: ${have_smartcard}
+ USB redirection support: ${have_usbredir} ${with_usbredir_hotplug}
+ DBus: ${have_dbus}
+ WebDAV support: ${have_phodav}
+ LZ4 support: ${have_lz4}
+
+ Now type 'make' to build $PACKAGE
+
+" >&5
+$as_echo "$as_me:
+
+ Spice-Gtk $VERSION
+ ==============
+
+ prefix: ${prefix}
+ c compiler: ${CC}
+ Target: ${red_target}
+
+ Gtk: ${with_gtk}
+ Coroutine: ${with_coroutine}
+ PulseAudio: ${enable_pulse}
+ GStreamer Audio: ${have_gstaudio}
+ GStreamer Video: ${have_gstvideo}
+ SASL support: ${have_sasl}
+ Smartcard support: ${have_smartcard}
+ USB redirection support: ${have_usbredir} ${with_usbredir_hotplug}
+ DBus: ${have_dbus}
+ WebDAV support: ${have_phodav}
+ LZ4 support: ${have_lz4}
+
+ Now type 'make' to build $PACKAGE
+
+" >&6;}
+
+ ac_save_IFS="$IFS"
+ IFS="|"
+ for msg in $spice_warnings; do
+ IFS="$ac_save_IFS"
+ if ${msg:+false} :; then :
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $msg" >&5
+$as_echo "$as_me: WARNING: $msg" >&2;}; echo >&2
+fi
+ done
+ IFS="$ac_save_IFS"
+
--- /dev/null
+AC_PREREQ([2.57])
+
+AC_INIT([spice-gtk], [m4_esyscmd(build-aux/git-version-gen .tarball-version)],
+ [spice-devel@lists.freedesktop.org])
+
+AC_CONFIG_MACRO_DIR([m4])
+m4_include([spice-common/m4/spice-deps.m4])
+AC_CONFIG_HEADER([config.h])
+AC_CONFIG_AUX_DIR([build-aux])
+
+AM_INIT_AUTOMAKE([foreign dist-bzip2 -Wall -Werror -Wno-portability])
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+LT_INIT([disable-static win32-dll])
+AM_MAINTAINER_MODE
+
+IT_PROG_INTLTOOL([0.40.0])
+GETTEXT_PACKAGE=spice-gtk
+AC_SUBST(GETTEXT_PACKAGE)
+AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],"$GETTEXT_PACKAGE", [GETTEXT package name])
+AM_GLIB_GNU_GETTEXT
+
+
+SPICE_GTK_LOCALEDIR=[${datadir}/locale]
+AC_SUBST(SPICE_GTK_LOCALEDIR)
+
+GTK_DOC_CHECK([1.14],[--flavour no-tmpl])
+
+AC_PROG_CC
+AC_PROG_CC_C99
+if test "x$ac_cv_prog_cc_c99" = xno; then
+ AC_MSG_ERROR([C99 compiler is required.])
+fi
+
+
+AC_CHECK_PROG([STOW], [stow], [yes], [no])
+AS_IF([test "x$STOW" = "xyes" && test -d /usr/local/stow], [
+ AC_MSG_NOTICE([*** Found /usr/local/stow: default install prefix set to /usr/local/stow/${PACKAGE_NAME} ***])
+ ac_default_prefix="/usr/local/stow/${PACKAGE_NAME}"
+])
+
+AC_PROG_INSTALL
+AC_CANONICAL_HOST
+AC_PROG_LIBTOOL
+AM_PROG_CC_C_O
+AC_C_BIGENDIAN
+AC_PATH_PROGS(PYTHON, python2 python)
+RRA_LD_VERSION_SCRIPT
+
+AC_MSG_CHECKING([for native Win32])
+case "$host_os" in
+ *mingw*|*cygwin*)
+ os_win32=yes
+ gio_os=gio-windows-2.0
+ red_target=Windows
+ ;;
+ *)
+ os_win32=no
+ gio_os=gio-unix-2.0
+ red_target=Unix
+ ;;
+esac
+AC_MSG_RESULT([$os_win32])
+AM_CONDITIONAL([OS_WIN32],[test "$os_win32" = "yes"])
+
+AC_CHECK_HEADERS([sys/socket.h netinet/in.h arpa/inet.h])
+AC_CHECK_HEADERS([termios.h])
+
+AC_CHECK_LIBM
+AC_SUBST(LIBM)
+
+AC_CONFIG_SUBDIRS([spice-common])
+PKG_CHECK_MODULES([SPICE_PROTOCOL], [spice-protocol >= 0.12.12])
+
+COMMON_CFLAGS='-I${top_builddir}/spice-common/ -I${top_srcdir}/spice-common/ ${SPICE_PROTOCOL_CFLAGS}'
+AC_SUBST(COMMON_CFLAGS)
+
+SPICE_GTK_MAJOR_VERSION=`echo $PACKAGE_VERSION | cut -d. -f1`
+SPICE_GTK_MINOR_VERSION=`echo $PACKAGE_VERSION | cut -d. -f2`
+SPICE_GTK_MICRO_VERSION=`echo $PACKAGE_VERSION | cut -d. -f3 | cut -d- -f1`
+AS_IF([test "x$SPICE_GTK_MICRO_VERSION" = "x"], [SPICE_GTK_MICRO_VERSION=0])
+
+AC_SUBST(SPICE_GTK_MAJOR_VERSION)
+AC_SUBST(SPICE_GTK_MINOR_VERSION)
+AC_SUBST(SPICE_GTK_MICRO_VERSION)
+
+dnl =========================================================================
+dnl Chek optional features
+
+srcdir="$(dirname $0)"
+if test ! -e "$srcdir/src/vncdisplaykeymap_osx2xtkbd.c"; then
+ AC_MSG_CHECKING([for Text::CSV Perl module])
+ perl -MText::CSV -e "" >/dev/null 2>&1
+ if test $? -ne 0 ; then
+ AC_MSG_RESULT([not found])
+ AC_MSG_ERROR([Text::CSV Perl module is required to compile this package])
+ fi
+ AC_MSG_RESULT([found])
+fi
+
+SPICE_GLIB_REQUIRES=""
+SPICE_GTK_REQUIRES=""
+
+PKG_CHECK_MODULES(PIXMAN, pixman-1 >= 0.17.7)
+
+SPICE_GLIB_REQUIRES="${SPICE_GLIB_REQUIRES} pixman-1 >= 0.17.7"
+
+PKG_CHECK_MODULES(SSL, openssl)
+
+SPICE_GLIB_REQUIRES="${SPICE_GLIB_REQUIRES} openssl"
+
+SPICE_CHECK_SASL
+
+AC_MSG_CHECKING([which gtk+ version to compile against])
+AC_ARG_WITH([gtk],
+ [AS_HELP_STRING([--with-gtk=@<:@3.0/no@:>@],[which gtk+ version to compile against @<:@default=3.0@:>@])],
+ [case "$with_gtk" in
+ 3.0) AC_MSG_RESULT([$with_gtk]) ;;
+ no) AC_MSG_RESULT([none]) ;;
+ *) AC_MSG_ERROR([invalid gtk version specified]) ;;
+ esac],
+ [with_gtk=3.0])
+
+case "$with_gtk" in
+ 3.0) GTK_REQUIRED=3.12
+ GTK_ENCODED_VERSION="GDK_VERSION_3_12"
+ ;;
+ no)
+ AS_IF([test x$enable_gtk_doc = xyes],
+ [AC_MSG_ERROR([Without GTK+, gtk-doc must be disabled])])
+esac
+
+AC_SUBST([GTK_REQUIRED])
+AM_CONDITIONAL([WITH_GTK],[test "$with_gtk" != "no"])
+
+AS_IF([test "x$with_gtk" != "xno"],
+ [AS_IF([test "x$os_win32" = "xyes"],
+ [PKG_CHECK_MODULES(GTK, gtk+-3.0 >= $GTK_REQUIRED)],
+ [PKG_CHECK_MODULES(GTK, gtk+-3.0 >= $GTK_REQUIRED epoxy)])]
+ [GTK_CFLAGS="$GTK_CFLAGS -DGDK_VERSION_MIN_REQUIRED=$GTK_ENCODED_VERSION \
+ -DGDK_VERSION_MAX_ALLOWED=$GTK_ENCODED_VERSION"])
+SPICE_GTK_REQUIRES="${SPICE_GTK_REQUIRES} gtk+-3.0 >= $GTK_REQUIRED"
+
+# Check for gdk_event_get_scancode function
+# This was added in Gdk 3.22
+# The check allows the usage of the function in case the function is
+# backported or in case of compilation from Gdk master branch
+old_LIBS="$LIBS"
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $GTK_CFLAGS"
+LIBS="$LIBS $GTK_LIBS"
+AC_CHECK_FUNCS(gdk_event_get_scancode)
+LIBS="$old_LIBS"
+CFLAGS="$old_CFLAGS"
+
+PKG_CHECK_EXISTS([gtk+-x11-$with_gtk], [PKG_CHECK_MODULES(X11, x11)])
+AC_CHECK_HEADERS([X11/XKBlib.h])
+
+AC_ARG_WITH([pnp-ids-path],
+ AC_HELP_STRING([--with-pnp-ids-path],
+ [Specify the path to pnp.ids @<:@default=(internal)@:>@]),
+ [],
+ [with_pnp_ids_path="\${pnpdatadir}/pnp.ids"])
+
+AM_CONDITIONAL(USE_INTERNAL_PNP_IDS, test "x$with_pnp_ids_path" = "x\${pnpdatadir}/pnp.ids")
+PNP_IDS=$with_pnp_ids_path
+AC_SUBST(PNP_IDS)
+if test "x$with_pnp_ids_path" = "x\${pnpdatadir}/pnp.ids"; then
+ EXTERNAL_PNP_IDS="no (internal)"
+else
+ EXTERNAL_PNP_IDS="$with_pnp_ids_path"
+fi
+
+AC_CHECK_FUNCS(clearenv strtok_r)
+
+# Keep these two definitions in agreement.
+GLIB2_REQUIRED="2.36"
+GLIB2_ENCODED_VERSION="GLIB_VERSION_2_36"
+
+PKG_CHECK_MODULES(GLIB2, glib-2.0 >= $GLIB2_REQUIRED)
+GLIB2_CFLAGS="$GLIB2_CFLAGS -DGLIB_VERSION_MIN_REQUIRED=$GLIB2_ENCODED_VERSION \
+ -DGLIB_VERSION_MAX_ALLOWED=$GLIB2_ENCODED_VERSION"
+
+PKG_CHECK_MODULES(GOBJECT2, gobject-2.0)
+
+PKG_CHECK_MODULES(GIO, gio-2.0 >= 2.36 $gio_os)
+
+PKG_CHECK_MODULES(CAIRO, cairo >= 1.2.0)
+
+PKG_CHECK_MODULES(GTHREAD, gthread-2.0)
+
+AC_ARG_ENABLE([webdav],
+ AS_HELP_STRING([--enable-webdav=@<:@auto/yes/no@:>@],
+ [Enable webdav support @<:@default=auto@:>@]),
+ [],
+ [enable_webdav="auto"])
+
+if test "x$enable_webdav" = "xno"; then
+ have_phodav="no"
+else
+ PKG_CHECK_MODULES(PHODAV, [libphodav-2.0 glib-2.0 >= 2.43.90 libsoup-2.4 >= 2.49.91], [have_phodav=yes], [have_phodav=no])
+
+ if test "x$have_phodav" = "xno" && test "x$enable_webdav" = "xyes"; then
+ AC_MSG_ERROR([webdav support explicitly requested, but some required packages are not available])
+ fi
+fi
+AS_IF([test "x$have_phodav" = "xyes"],
+ AC_DEFINE([USE_PHODAV], [1], [Define if supporting phodav]))
+
+AM_CONDITIONAL([WITH_PHODAV], [test "x$have_phodav" = "xyes"])
+
+AC_ARG_WITH([audio],
+ AS_HELP_STRING([--with-audio=@<:@gstreamer/pulse/auto/no@:>@], [For legacy compatibility only]),
+ [SPICE_WARNING([--with-audio is deprecated. Use --enable-pulse and/or --enable-gstaudio instead])
+ case "$with_audio" in
+ pulse) enable_pulse="yes"; enable_gstaudio="no" ;;
+ gstreamer) enable_pulse="no"; enable_gstaudio="yes" ;;
+ no) enable_pulse="no"; enable_gstaudio="no" ;;
+ esac
+])
+
+AC_ARG_ENABLE([pulse],
+ AS_HELP_STRING([--enable-pulse=@<:@yes/auto/no@:>@], [Enable the PulseAudio backend @<:@default=auto@:>@]),
+ [],
+ [enable_pulse="auto"])
+AS_IF([test "x$enable_pulse" != "xno"],
+ [PKG_CHECK_MODULES(PULSE, [libpulse libpulse-mainloop-glib],
+ [AC_DEFINE([HAVE_PULSE], 1, [Have PulseAudio support?])
+ enable_pulse="yes"],
+ [AS_IF([test "x$enable_pulse" = "xyes"],
+ AC_MSG_ERROR([PulseAudio requested but not found]))
+ enable_pulse="no"
+ ])
+])
+AM_CONDITIONAL([HAVE_PULSE], [test "x$enable_pulse" = "xyes"])
+
+AC_ARG_ENABLE([gstaudio],
+ AS_HELP_STRING([--enable-gstaudio=@<:@yes/auto/no@:>@], [Enable the GStreamer 1.0 audio backend @<:@default=auto@:>@]),
+ [],
+ [enable_gstaudio="auto"])
+AS_IF([test "x$enable_gstaudio" != "xno"],
+ [SPICE_CHECK_GSTREAMER(GSTAUDIO, 1.0, [gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-audio-1.0],
+ [SPICE_CHECK_GSTREAMER_ELEMENTS($GST_INSPECT_1_0, [gst-plugins-base 1.0], [audioconvert audioresample appsink])
+ SPICE_CHECK_GSTREAMER_ELEMENTS($GST_INSPECT_1_0, [gst-plugins-good 1.0], [autoaudiosrc])
+ AS_IF([test x"$missing_gstreamer_elements" = "xyes"],
+ SPICE_WARNING([The GStreamer 1.0 audio backend can be built but may not work.]))
+ ],
+ [AS_IF([test "x$enable_gstaudio" = "xyes"],
+ AC_MSG_ERROR([GStreamer 1.0 audio requested but not found]))
+ ])
+ ], [have_gstaudio="no"]
+)
+AM_CONDITIONAL([HAVE_GSTAUDIO], [test "x$have_gstaudio" = "xyes"])
+
+AS_IF([test "x$enable_pulse$have_gstaudio" = "xnono"],
+ [SPICE_WARNING([No PulseAudio or GStreamer 1.0 audio decoder, audio will not be streamed])
+])
+
+AC_ARG_ENABLE([gstvideo],
+ AS_HELP_STRING([--enable-gstvideo=@<:@auto/yes/no@:>@],
+ [Enable GStreamer video support @<:@default=auto@:>@]),
+ [],
+ [enable_gstvideo="auto"])
+AS_IF([test "x$enable_gstvideo" != "xno"],
+ [SPICE_CHECK_GSTREAMER(GSTVIDEO, 1.0,
+ [gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-video-1.0],
+ [missing_gstreamer_elements=""
+ SPICE_CHECK_GSTREAMER_ELEMENTS($GST_INSPECT_1_0, [gst-plugins-base 1.0], [appsrc videoconvert appsink])
+ SPICE_CHECK_GSTREAMER_ELEMENTS($GST_INSPECT_1_0, [gst-plugins-good 1.0], [jpegdec vp8dec])
+ SPICE_CHECK_GSTREAMER_ELEMENTS($GST_INSPECT_1_0, [gst-plugins-bad 1.0], [h264parse])
+ SPICE_CHECK_GSTREAMER_ELEMENTS($GST_INSPECT_1_0, [gstreamer-libav 1.0], [avdec_h264])
+ AS_IF([test x"$missing_gstreamer_elements" = "xyes"],
+ SPICE_WARNING([The GStreamer video decoder can be built but may not work.]))
+ ],
+ [AS_IF([test "x$enable_gstvideo" = "xyes"],
+ AC_MSG_ERROR([GStreamer 1.0 video requested but not found]))
+ ])
+ ], [have_gstvideo="no"]
+)
+AM_CONDITIONAL([HAVE_GSTVIDEO], [test "x$have_gstvideo" = "xyes"])
+
+AC_ARG_ENABLE([builtin-mjpeg],
+ AS_HELP_STRING([--enable-builtin-mjpeg], [Enable the builtin mjpeg video decoder @<:@default=yes@:>@]),
+ [],
+ enable_builtin_mjpeg="yes")
+AS_IF([test "x$enable_builtin_mjpeg" = "xyes"],
+ [AC_DEFINE([HAVE_BUILTIN_MJPEG], 1, [Use the builtin mjpeg decoder?])])
+AM_CONDITIONAL(HAVE_BUILTIN_MJPEG, [test "x$enable_builtin_mjpeg" != "xno"])
+
+AS_IF([test "x$enable_builtin_mjpeg$enable_gstvideo" = "xnono"],
+ [SPICE_WARNING([No builtin MJPEG or GStreamer decoder, video will not be streamed])])
+
+AC_CHECK_LIB(jpeg, jpeg_destroy_decompress,
+ AC_MSG_CHECKING([for jpeglib.h])
+ AC_TRY_CPP(
+[#include <stdio.h>
+#undef PACKAGE
+#undef VERSION
+#undef HAVE_STDLIB_H
+#include <jpeglib.h>],
+ JPEG_LIBS='-ljpeg'
+ AC_MSG_RESULT($jpeg_ok),
+ AC_MSG_ERROR([jpeglib.h not found])),
+ AC_MSG_ERROR([libjpeg not found]))
+AC_SUBST(JPEG_LIBS)
+
+AC_CHECK_LIB(z, deflate, Z_LIBS='-lz', AC_MSG_ERROR([zlib not found]))
+AC_SUBST(Z_LIBS)
+
+SPICE_CHECK_SMARTCARD
+AM_CONDITIONAL([WITH_SMARTCARD], [test "x$have_smartcard" = "xyes"])
+
+AC_ARG_ENABLE([usbredir],
+ AS_HELP_STRING([--enable-usbredir=@<:@auto/yes/no@:>@],
+ [Enable usbredir support @<:@default=auto@:>@]),
+ [],
+ [enable_usbredir="auto"])
+
+if test "x$enable_usbredir" = "xno"; then
+ have_usbredir="no"
+else
+ if ${PKG_CONFIG} libusbredirparser-0.5; then
+ PKG_CHECK_MODULES([USBREDIR],
+ [libusb-1.0 >= 1.0.9 libusbredirhost libusbredirparser-0.5],
+ [have_usbredir=yes],
+ [have_usbredir=no])
+ else
+ PKG_CHECK_MODULES([USBREDIR],
+ [libusb-1.0 >= 1.0.9 libusbredirhost >= 0.4.2 libusbredirparser >= 0.4],
+ [have_usbredir=yes],
+ [have_usbredir=no])
+ fi
+ if test "x$have_usbredir" = "xno" && test "x$enable_usbredir" = "xyes"; then
+ AC_MSG_ERROR([usbredir support explicitly requested, but some required packages are not available])
+ fi
+
+ # On non windows we need either libusb hotplug support or gudev
+ if test "x$have_usbredir" = "xyes" && test "x$os_win32" = "xno"; then
+ PKG_CHECK_MODULES([LIBUSB_HOTPLUG], [libusb-1.0 >= 1.0.16],
+ [have_libusb_hotplug=yes], [have_libusb_hotplug=no])
+ if test "x$have_libusb_hotplug" = "xyes"; then
+ AC_DEFINE([USE_LIBUSB_HOTPLUG], [1], [Define if libusb has hotplug support])
+ with_usbredir_hotplug="with libusb hotplug"
+ else
+ PKG_CHECK_MODULES([GUDEV],
+ [gudev-1.0],
+ [have_gudev=yes],
+ [have_gudev=no])
+
+ if test "x$have_gudev" = "xno" && test "x$enable_usbredir" = "xyes"; then
+ AC_MSG_ERROR([usbredir requested but required gudev is not available])
+ fi
+ if test "x$have_gudev" = "xyes"; then
+ AC_DEFINE([USE_GUDEV], [1], [Define if supporting gudev])
+ with_usbredir_hotplug="with gudev hotplug"
+ else
+ have_usbredir=no
+ fi
+ fi
+ fi
+
+ if test "x$have_usbredir" = "xyes"; then
+ AC_DEFINE([USE_USBREDIR], [1], [Define if supporting usbredir proxying])
+ fi
+fi
+AM_CONDITIONAL([WITH_USBREDIR], [test "x$have_usbredir" = "xyes"])
+
+AC_ARG_ENABLE([polkit],
+ AS_HELP_STRING([--enable-polkit=@<:@auto/yes/no@:>@],
+ [Enable PolicyKit support (for the usb acl helper)@<:@default=auto@:>@]),
+ [],
+ [enable_polkit="auto"])
+
+if test "x$have_usbredir" = "xyes" && test "x$enable_polkit" != "xno"; then
+ PKG_CHECK_MODULES([POLKIT], [polkit-gobject-1 >= 0.96],
+ [have_polkit=yes],
+ [have_polkit=no])
+ AC_CHECK_HEADER([acl/libacl.h], [], [have_polkit=no])
+ AC_CHECK_LIB([acl], [acl_get_file], [ACL_LIBS=-lacl], [have_polkit=no])
+ if test "x$enable_polkit" = "xyes" && test "x$have_polkit" = "xno"; then
+ AC_MSG_ERROR([PolicyKit support explicitly requested, but some required packages are not available])
+ fi
+
+ if test "x$have_polkit" = "xyes"; then
+ AC_SUBST(ACL_LIBS)
+ AC_DEFINE([USE_POLKIT], [1], [Define if supporting polkit])
+ fi
+ AM_CONDITIONAL([WITH_POLKIT], [test "x$have_polkit" = "xyes"])
+ POLICYDIR=`${PKG_CONFIG} polkit-gobject-1 --variable=policydir`
+ AC_SUBST(POLICYDIR)
+ # Check for polkit_authority_get_sync()
+ AC_CHECK_LIB([polkit-gobject-1], [polkit_authority_get_sync], ac_have_pk_auth_get_sync="1", ac_have_pk_auth_get_sync="0")
+ AC_DEFINE_UNQUOTED([HAVE_POLKIT_AUTHORITY_GET_SYNC], $ac_have_pk_auth_get_sync, [Define if you have a polkit with polkit_authority_get_sync()])
+ AC_CHECK_LIB([polkit-gobject-1], [polkit_authorization_result_get_dismissed], ac_have_pk_authorization_result_get_dismissed="1", ac_have_pk_authorization_result_get_dismissed="0")
+ AC_DEFINE_UNQUOTED([HAVE_POLKIT_AUTHORIZATION_RESULT_GET_DISMISSED], $ac_have_pk_authorization_result_get_dismissed, [Define if you have a polkit with polkit_authorization_result_get_dismissed()])
+else
+ AM_CONDITIONAL(WITH_POLKIT, false)
+fi
+
+if test "x$have_usbredir" = "xyes" && test "x$have_polkit" != "xyes"; then
+ AC_MSG_WARN([Building with usbredir support, but *not* building the usb acl helper])
+fi
+
+AC_ARG_ENABLE([pie],
+ AS_HELP_STRING([--enable-pie=@<:@auto/yes/no@:>@],
+ [Enable position-independent-executable support (for the usb acl helper)@<:@default=auto@:>@]),
+ [],
+ [enable_pie="auto"])
+
+if test "x$have_polkit" = "xyes" && test "x$enable_pie" != "xno"; then
+ save_CFLAGS="$CFLAGS"
+ save_LDFLAGS="$LDFLAGS"
+ CFLAGS="$CFLAGS -fPIE"
+ LDFLAGS="$LDFLAGS -pie -Wl,-z,relro -Wl,-z,now"
+ AC_MSG_CHECKING([for PIE support])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([void main () {}])],
+ [have_pie=yes],
+ [have_pie=no])
+ AC_MSG_RESULT([$have_pie])
+ if test "x$have_pie" = "xno" && test "x$enable_pie" = "xyes"; then
+ AC_MSG_ERROR([pie support explicitly requested, but your toolchain does not support it])
+ fi
+ if test "x$have_pie" = "xyes"; then
+ PIE_CFLAGS="-fPIE"
+ PIE_LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now"
+ AC_SUBST(PIE_CFLAGS)
+ AC_SUBST(PIE_LDFLAGS)
+ fi
+ CFLAGS="$save_CFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+fi
+
+AC_ARG_WITH([usb-acl-helper-dir],
+ AS_HELP_STRING([--with-usb-acl-helper-dir=DIR],
+ [Directory where the USB ACL helper binary should be installed]),
+ [ACL_HELPER_DIR="$with_usb_acl_helper_dir"],
+ [ACL_HELPER_DIR="${bindir}/"])
+AC_SUBST([ACL_HELPER_DIR])
+
+AC_ARG_WITH([usb-ids-path],
+ AC_HELP_STRING([--with-usb-ids-path],
+ [Specify the path to usb.ids @<:@default=auto@:>@]),
+ [USB_IDS="$with_usb_ids_path"],
+ [USB_IDS="auto"])
+AC_MSG_CHECKING([for usb.ids])
+if test "x$USB_IDS" = "xauto"; then
+ if test -n "$PKG_CONFIG"; then
+ USB_IDS=$($PKG_CONFIG --variable=usbids usbutils)
+ else
+ USB_IDS=
+ fi
+fi
+if test -n "$USB_IDS"; then
+ AC_MSG_RESULT([$USB_IDS])
+ AC_SUBST(USB_IDS)
+ AC_DEFINE([WITH_USBIDS], [1], [Define if compiling with usb.ids support])
+else
+ AC_MSG_RESULT([not found])
+fi
+
+AC_ARG_WITH([coroutine],
+ AS_HELP_STRING([--with-coroutine=@<:@ucontext/gthread/winfiber/auto@:>@],
+ [use ucontext or GThread for coroutines @<:@default=auto@:>@]),
+ [],
+ [with_coroutine=auto])
+
+case $with_coroutine in
+ ucontext|gthread|winfiber|auto) ;;
+ *) AC_MSG_ERROR(Unsupported coroutine type)
+esac
+
+if test "$with_coroutine" = "auto"; then
+ if test "$os_win32" = "yes"; then
+ with_coroutine=winfiber
+ else
+ with_coroutine=ucontext
+ fi
+fi
+
+if test "$with_coroutine" = "ucontext"; then
+ AC_CHECK_FUNC(makecontext, [],[with_coroutine=gthread])
+ AC_CHECK_FUNC(swapcontext, [],[with_coroutine=gthread])
+ AC_CHECK_FUNC(getcontext, [],[with_coroutine=gthread])
+fi
+
+WITH_UCONTEXT=0
+WITH_GTHREAD=0
+WITH_WINFIBER=0
+
+case $with_coroutine in
+ ucontext) WITH_UCONTEXT=1 ;;
+ gthread) WITH_GTHREAD=1 ;;
+ winfiber) WITH_WINFIBER=1 ;;
+ *) AC_MSG_ERROR(Unsupported coroutine type)
+esac
+
+AC_DEFINE_UNQUOTED([WITH_UCONTEXT],[$WITH_UCONTEXT], [Whether to use ucontext coroutine impl])
+AM_CONDITIONAL(WITH_UCONTEXT, [test "x$WITH_UCONTEXT" = "x1"])
+
+AC_DEFINE_UNQUOTED([WITH_WINFIBER],[$WITH_WINFIBER], [Whether to use fiber coroutine impl])
+AM_CONDITIONAL(WITH_WINFIBER, [test "x$WITH_WINFIBER" = "x1"])
+
+AC_DEFINE_UNQUOTED([WITH_GTHREAD],[$WITH_GTHREAD], [Whether to use gthread coroutine impl])
+AM_CONDITIONAL(WITH_GTHREAD, [test "x$WITH_GTHREAD" = "x1"])
+
+AM_CONDITIONAL([HAVE_INTROSPECTION], [test "0" = "1"])
+m4_ifdef([GOBJECT_INTROSPECTION_CHECK],[
+ PKG_CHECK_EXISTS([GOBJECT_INTROSPECTION],
+ [gobject-introspection-1.0 >= 0.9.4],
+ [has_symbol_prefix=yes], [:])
+ GOBJECT_INTROSPECTION_CHECK([0.6.7])
+])
+AM_CONDITIONAL([G_IR_SCANNER_SYMBOL_PREFIX], [test "x$has_symbol_prefix" = "xyes"])
+
+AC_ARG_ENABLE([controller],
+ AS_HELP_STRING([--enable-controller], [Enable controller build @<:@default=yes@:>@]),
+ [],
+ enable_controller="yes")
+
+AM_CONDITIONAL(WITH_CONTROLLER, [test "x$enable_controller" != "xno"])
+
+AC_ARG_ENABLE([vala],
+ AS_HELP_STRING([--enable-vala], [Check for vala requirements @<:@default=no@:>@]),
+ [],
+ enable_vala="no")
+
+VALA_REQUIRED=0.14
+if test x$enable_vala = xyes ; then
+ # check for vala
+ AM_PROG_VALAC([$VALA_REQUIRED])
+ AC_PATH_PROG(VAPIGEN, vapigen, no)
+ if test "x$VAPIGEN" == "xno"; then
+ AC_MSG_ERROR([Cannot find the "vapigen" binary in your PATH])
+ fi
+ AC_SUBST(VAPIGEN)
+fi
+
+AM_CONDITIONAL(WITH_VALA, [test "x$enable_vala" = "xyes"])
+
+VAPIDIR="${datadir}/vala/vapi"
+AC_SUBST(VAPIDIR)
+
+AC_ARG_ENABLE([dbus],
+ AS_HELP_STRING([--enable-dbus=@<:@auto/yes/no@:>@],
+ [Enable dbus support for desktop integration (disabling automount) @<:@default=auto@:>@]),
+ [],
+ [enable_dbus="auto"])
+
+have_dbus=no
+if test "x$enable_dbus" != "xno"; then
+ AC_DEFINE([USE_GDBUS], [1], [Define if supporting gdbus])
+ have_dbus=yes
+else
+ SPICE_WARNING([No D-Bus support, desktop integration and USB redirection may not work properly])
+fi
+
+SPICE_CHECK_LZ4
+
+dnl ===========================================================================
+dnl check compiler flags
+
+# some glib/gstreamer enums use 1 << 31
+dontwarn="-Wshift-overflow=2"
+
+SPICE_COMPILE_WARNINGS([$dontwarn])
+
+SPICE_CFLAGS="$SPICE_CFLAGS $WARN_CFLAGS"
+
+AC_SUBST(SPICE_CFLAGS)
+
+SPICE_GLIB_CFLAGS="$PIXMAN_CFLAGS $PULSE_CFLAGS $GSTAUDIO_CFLAGS $GSTVIDEO_CFLAGS $GLIB2_CFLAGS $GIO_CFLAGS $GOBJECT2_CFLAGS $SSL_CFLAGS $SASL_CFLAGS"
+SPICE_GTK_CFLAGS="$SPICE_GLIB_CFLAGS $GTK_CFLAGS "
+
+AC_SUBST(SPICE_GLIB_CFLAGS)
+AC_SUBST(SPICE_GTK_CFLAGS)
+
+AC_SUBST(SPICE_GLIB_REQUIRES)
+AC_SUBST(SPICE_GTK_REQUIRES)
+
+m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
+
+AM_CONDITIONAL([BUILD_TESTS], [test x"$enable_static" = xyes])
+
+AC_OUTPUT([
+Makefile
+spice-client-glib-2.0.pc
+spice-client-gtk-3.0.pc
+spice-controller.pc
+data/Makefile
+po/Makefile.in
+src/Makefile
+src/spice-version.h
+src/controller/Makefile
+doc/Makefile
+doc/reference/Makefile
+man/Makefile
+vapi/Makefile
+tests/Makefile
+])
+
+dnl ==========================================================================
+AC_MSG_NOTICE([
+
+ Spice-Gtk $VERSION
+ ==============
+
+ prefix: ${prefix}
+ c compiler: ${CC}
+ Target: ${red_target}
+
+ Gtk: ${with_gtk}
+ Coroutine: ${with_coroutine}
+ PulseAudio: ${enable_pulse}
+ GStreamer Audio: ${have_gstaudio}
+ GStreamer Video: ${have_gstvideo}
+ SASL support: ${have_sasl}
+ Smartcard support: ${have_smartcard}
+ USB redirection support: ${have_usbredir} ${with_usbredir_hotplug}
+ DBus: ${have_dbus}
+ WebDAV support: ${have_phodav}
+ LZ4 support: ${have_lz4}
+
+ Now type 'make' to build $PACKAGE
+
+])
+SPICE_PRINT_MESSAGES
--- /dev/null
+NULL=
+
+EXTRA_DIST = \
+ spice-protocol.vapi \
+ org.spice-space.lowlevelusbaccess.policy \
+ $(NULL)
+
+vapidir = $(VAPIDIR)
+vapi_DATA = spice-protocol.vapi
+
+policydir = $(POLICYDIR)
+policy_DATA = org.spice-space.lowlevelusbaccess.policy
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = data
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/ld-version.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/manywarnings.m4 \
+ $(top_srcdir)/m4/spice-compile-warnings.m4 \
+ $(top_srcdir)/m4/warnings.m4 \
+ $(top_srcdir)/spice-common/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(policydir)" "$(DESTDIR)$(vapidir)"
+DATA = $(policy_DATA) $(vapi_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACL_HELPER_DIR = @ACL_HELPER_DIR@
+ACL_LIBS = @ACL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMMON_CFLAGS = @COMMON_CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GOBJECT2_CFLAGS = @GOBJECT2_CFLAGS@
+GOBJECT2_LIBS = @GOBJECT2_LIBS@
+GREP = @GREP@
+GSTAUDIO_CFLAGS = @GSTAUDIO_CFLAGS@
+GSTAUDIO_LIBS = @GSTAUDIO_LIBS@
+GSTVIDEO_CFLAGS = @GSTVIDEO_CFLAGS@
+GSTVIDEO_LIBS = @GSTVIDEO_LIBS@
+GST_INSPECT_1_0 = @GST_INSPECT_1_0@
+GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
+GTHREAD_LIBS = @GTHREAD_LIBS@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_REQUIRED = @GTK_REQUIRED@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+JPEG_LIBS = @JPEG_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUSB_HOTPLUG_CFLAGS = @LIBUSB_HOTPLUG_CFLAGS@
+LIBUSB_HOTPLUG_LIBS = @LIBUSB_HOTPLUG_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PHODAV_CFLAGS = @PHODAV_CFLAGS@
+PHODAV_LIBS = @PHODAV_LIBS@
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PNP_IDS = @PNP_IDS@
+POFILES = @POFILES@
+POLICYDIR = @POLICYDIR@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PULSE_CFLAGS = @PULSE_CFLAGS@
+PULSE_LIBS = @PULSE_LIBS@
+PYTHON = @PYTHON@
+RANLIB = @RANLIB@
+SASL_CFLAGS = @SASL_CFLAGS@
+SASL_LIBS = @SASL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_CFLAGS = @SPICE_CFLAGS@
+SPICE_GLIB_CFLAGS = @SPICE_GLIB_CFLAGS@
+SPICE_GLIB_REQUIRES = @SPICE_GLIB_REQUIRES@
+SPICE_GTK_CFLAGS = @SPICE_GTK_CFLAGS@
+SPICE_GTK_LOCALEDIR = @SPICE_GTK_LOCALEDIR@
+SPICE_GTK_MAJOR_VERSION = @SPICE_GTK_MAJOR_VERSION@
+SPICE_GTK_MICRO_VERSION = @SPICE_GTK_MICRO_VERSION@
+SPICE_GTK_MINOR_VERSION = @SPICE_GTK_MINOR_VERSION@
+SPICE_GTK_REQUIRES = @SPICE_GTK_REQUIRES@
+SPICE_PROTOCOL_CFLAGS = @SPICE_PROTOCOL_CFLAGS@
+SPICE_PROTOCOL_LIBS = @SPICE_PROTOCOL_LIBS@
+SSL_CFLAGS = @SSL_CFLAGS@
+SSL_LIBS = @SSL_LIBS@
+STOW = @STOW@
+STRIP = @STRIP@
+USBREDIR_CFLAGS = @USBREDIR_CFLAGS@
+USBREDIR_LIBS = @USBREDIR_LIBS@
+USB_IDS = @USB_IDS@
+USE_NLS = @USE_NLS@
+VALAC = @VALAC@
+VAPIDIR = @VAPIDIR@
+VAPIGEN = @VAPIGEN@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_LDFLAGS = @WARN_LDFLAGS@
+WARN_PYFLAGS = @WARN_PYFLAGS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+XGETTEXT = @XGETTEXT@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+EXTRA_DIST = \
+ spice-protocol.vapi \
+ org.spice-space.lowlevelusbaccess.policy \
+ $(NULL)
+
+vapidir = $(VAPIDIR)
+vapi_DATA = spice-protocol.vapi
+policydir = $(POLICYDIR)
+policy_DATA = org.spice-space.lowlevelusbaccess.policy
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign data/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign data/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-policyDATA: $(policy_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(policy_DATA)'; test -n "$(policydir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(policydir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(policydir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(policydir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(policydir)" || exit $$?; \
+ done
+
+uninstall-policyDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(policy_DATA)'; test -n "$(policydir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(policydir)'; $(am__uninstall_files_from_dir)
+install-vapiDATA: $(vapi_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(vapi_DATA)'; test -n "$(vapidir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(vapidir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(vapidir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(vapidir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(vapidir)" || exit $$?; \
+ done
+
+uninstall-vapiDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(vapi_DATA)'; test -n "$(vapidir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(vapidir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(policydir)" "$(DESTDIR)$(vapidir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-policyDATA install-vapiDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-policyDATA uninstall-vapiDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-policyDATA install-ps \
+ install-ps-am install-strip install-vapiDATA installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am uninstall-policyDATA uninstall-vapiDATA
+
+.PRECIOUS: Makefile
+
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+<policyconfig>
+
+ <vendor>The Spice Project</vendor>
+ <vendor_url>http://spice-space.org/</vendor_url>
+ <icon_name>spice</icon_name>
+
+ <action id="org.spice-space.lowlevelusbaccess">
+ <description>Low level USB device access</description>
+ <message>Privileges are required for low level USB device access (for usb device pass through).</message>
+ <defaults>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+
+</policyconfig>
--- /dev/null
+namespace SpiceProtocol {
+ [CCode (cprefix = "Controller", cheader_filename = "spice/controller_prot.h")]
+ namespace Controller {
+ [CCode (cname = "CONTROLLER_MAGIC")]
+ public const uint32 MAGIC;
+ [CCode (cname = "CONTROLLER_VERSION")]
+ public const int VERSION;
+
+ [Compact]
+ public struct InitHeader {
+ uint32 magic;
+ uint32 version;
+ uint32 size;
+ }
+
+ [Compact]
+ public struct Init {
+ InitHeader base;
+ uint64 credentials;
+ uint32 flags;
+ }
+
+ [CCode (cprefix = "CONTROLLER_FLAG_")]
+ [Flags]
+ public enum Flag {
+ EXCLUSIVE,
+ }
+
+ [Compact]
+ public struct Msg {
+ uint32 id;
+ uint32 size;
+ }
+
+ [CCode (cprefix = "CONTROLLER_")]
+ public enum MsgId {
+ //external app -> spice client
+ HOST,
+ PORT,
+ SPORT,
+ PASSWORD,
+
+ SECURE_CHANNELS,
+ DISABLE_CHANNELS,
+
+ TLS_CIPHERS,
+ CA_FILE,
+ HOST_SUBJECT,
+
+ FULL_SCREEN,
+ SET_TITLE,
+
+ CREATE_MENU,
+ DELETE_MENU,
+
+ HOTKEYS,
+ SEND_CAD,
+
+ CONNECT,
+ SHOW,
+ HIDE,
+
+ ENABLE_SMARTCARD,
+
+ ENABLE_USB,
+ ENABLE_USB_AUTOSHARE,
+ USB_FILTER,
+
+ PROXY,
+
+ //spice client -> external app
+ MENU_ITEM_CLICK,
+
+ COLOR_DEPTH,
+ DISABLE_EFFECTS,
+ }
+
+ [CCode (cname = "unsigned int", cprefix = "CONTROLLER_", has_type_id = false)]
+ [Flags]
+ public enum Display {
+ SET_FULL_SCREEN,
+ AUTO_DISPLAY_RES,
+ }
+
+ [Compact]
+ [CCode (cname = "ControllerValue")]
+ public struct MsgValue: Msg {
+ Msg base;
+ uint32 value;
+ }
+
+ [Compact]
+ [CCode (cname = "ControllerData")]
+ public struct MsgData {
+ Msg base;
+ uint8 data[0];
+ }
+
+ [CCode (cname = "CONTROLLER_MENU_ITEM_DELIMITER")]
+ public static string MENU_ITEM_DELIMITER;
+ [CCode (cname = "CONTROLLER_MENU_PARAM_DELIMITER")]
+ public static string MENU_PARAM_DELIMITER;
+
+ [CCode (cname = "SPICE_MENU_INTERNAL_ID_BASE")]
+ public static int MENU_INTERNAL_ID_BASE;
+ [CCode (cname = "SPICE_MENU_INTERNAL_ID_SHIFT")]
+ public static int MENU_INTERNAL_ID_SHIFT;
+
+ [CCode (cprefix = "CONTROLLER_MENU_FLAGS_", cname = "unsigned int", has_type_id = false)]
+ [Flags]
+ public enum MenuFlags {
+ SEPARATOR,
+ DISABLED,
+ POPUP,
+ CHECKED,
+ GRAYED,
+ }
+ }
+
+ [CCode (cprefix = "FrgMenu", cheader_filename = "spice/foreign_menu_prot.h")]
+ namespace ForeignMenu {
+ [CCode (cname = "FOREIGN_MENU_MAGIC")]
+ public const uint32 MAGIC;
+ [CCode (cname = "FOREIGN_MENU_VERSION")]
+ public const int VERSION;
+
+ [Compact]
+ public struct InitHeader {
+ uint32 magic;
+ uint32 version;
+ uint32 size;
+ }
+
+ [Compact]
+ [CCode (has_destroy_function = false)]
+ public struct Init {
+ InitHeader base;
+ uint64 credentials;
+ string title; // utf8
+ }
+
+ [Compact]
+ public struct Msg {
+ uint32 id;
+ uint32 size;
+ }
+
+ [CCode (cprefix = "FOREIGN_MENU_", cname = "int")]
+ public enum MsgId {
+ //external app -> spice client
+ SET_TITLE,
+ ADD_ITEM,
+ MODIFY_ITEM,
+ REMOVE_ITEM,
+ CLEAR,
+
+ //spice client -> external app
+ ITEM_EVENT,
+ APP_ACTIVATED,
+ APP_DEACTIVATED,
+ }
+
+ [Compact]
+ [CCode (cname = "FrgMenuSetTitle")]
+ public struct SetTitle {
+ Msg base;
+ string string; // utf8
+ }
+
+ [CCode (cprefix = "FOREIGN_MENU_ITEM_TYPE_", cname = "unsigned int", has_type_id = false)]
+ [Flags]
+ public enum MenuFlags {
+ CHECKED,
+ DIM,
+ SEPARATOR
+ }
+
+ [Compact]
+ [CCode (cname = "FrgMenuAddItem")]
+ public struct AddItem {
+ Msg base;
+ uint32 id;
+ uint32 type;
+ uint32 position;
+ string string; // utf8
+ }
+
+ [Compact]
+ [CCode (cname = "FrgMenuRmItem")]
+ public struct RmItem {
+ Msg base;
+ uint32 id;
+ }
+
+ [CCode (cprefix = "FOREIGN_MENU_EVENT_", cname = "int")]
+ public enum EventType {
+ CLICK,
+ CHECKED,
+ UNCHECKED,
+ }
+
+ [Compact]
+ [CCode (cname = "FrgMenuEvent")]
+ public struct Event {
+ Msg base;
+ uint32 id;
+ uint32 action;
+ }
+ }
+}
--- /dev/null
+SUBDIRS = reference
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = doc
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/ld-version.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/manywarnings.m4 \
+ $(top_srcdir)/m4/spice-compile-warnings.m4 \
+ $(top_srcdir)/m4/warnings.m4 \
+ $(top_srcdir)/spice-common/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ACL_HELPER_DIR = @ACL_HELPER_DIR@
+ACL_LIBS = @ACL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMMON_CFLAGS = @COMMON_CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GOBJECT2_CFLAGS = @GOBJECT2_CFLAGS@
+GOBJECT2_LIBS = @GOBJECT2_LIBS@
+GREP = @GREP@
+GSTAUDIO_CFLAGS = @GSTAUDIO_CFLAGS@
+GSTAUDIO_LIBS = @GSTAUDIO_LIBS@
+GSTVIDEO_CFLAGS = @GSTVIDEO_CFLAGS@
+GSTVIDEO_LIBS = @GSTVIDEO_LIBS@
+GST_INSPECT_1_0 = @GST_INSPECT_1_0@
+GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
+GTHREAD_LIBS = @GTHREAD_LIBS@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_REQUIRED = @GTK_REQUIRED@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+JPEG_LIBS = @JPEG_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUSB_HOTPLUG_CFLAGS = @LIBUSB_HOTPLUG_CFLAGS@
+LIBUSB_HOTPLUG_LIBS = @LIBUSB_HOTPLUG_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PHODAV_CFLAGS = @PHODAV_CFLAGS@
+PHODAV_LIBS = @PHODAV_LIBS@
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PNP_IDS = @PNP_IDS@
+POFILES = @POFILES@
+POLICYDIR = @POLICYDIR@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PULSE_CFLAGS = @PULSE_CFLAGS@
+PULSE_LIBS = @PULSE_LIBS@
+PYTHON = @PYTHON@
+RANLIB = @RANLIB@
+SASL_CFLAGS = @SASL_CFLAGS@
+SASL_LIBS = @SASL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_CFLAGS = @SPICE_CFLAGS@
+SPICE_GLIB_CFLAGS = @SPICE_GLIB_CFLAGS@
+SPICE_GLIB_REQUIRES = @SPICE_GLIB_REQUIRES@
+SPICE_GTK_CFLAGS = @SPICE_GTK_CFLAGS@
+SPICE_GTK_LOCALEDIR = @SPICE_GTK_LOCALEDIR@
+SPICE_GTK_MAJOR_VERSION = @SPICE_GTK_MAJOR_VERSION@
+SPICE_GTK_MICRO_VERSION = @SPICE_GTK_MICRO_VERSION@
+SPICE_GTK_MINOR_VERSION = @SPICE_GTK_MINOR_VERSION@
+SPICE_GTK_REQUIRES = @SPICE_GTK_REQUIRES@
+SPICE_PROTOCOL_CFLAGS = @SPICE_PROTOCOL_CFLAGS@
+SPICE_PROTOCOL_LIBS = @SPICE_PROTOCOL_LIBS@
+SSL_CFLAGS = @SSL_CFLAGS@
+SSL_LIBS = @SSL_LIBS@
+STOW = @STOW@
+STRIP = @STRIP@
+USBREDIR_CFLAGS = @USBREDIR_CFLAGS@
+USBREDIR_LIBS = @USBREDIR_LIBS@
+USB_IDS = @USB_IDS@
+USE_NLS = @USE_NLS@
+VALAC = @VALAC@
+VAPIDIR = @VAPIDIR@
+VAPIGEN = @VAPIGEN@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_LDFLAGS = @WARN_LDFLAGS@
+WARN_PYFLAGS = @WARN_PYFLAGS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+XGETTEXT = @XGETTEXT@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = reference
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign doc/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+NULL =
+
+AUTOMAKE_OPTIONS = 1.6
+DOC_MODULE = spice-gtk
+
+# The top-level SGML file
+DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml
+
+# Source code location
+DOC_SOURCE_DIR = $(top_srcdir)/src
+
+# Extra options to supply to gtkdoc-scan.
+SCAN_OPTIONS = \
+ --deprecated-guards="SPICE_DISABLE_DEPRECATED" \
+ --ignore-decorators="G_GNUC_INTERNAL"
+
+# Extra options to supply to gtkdoc-mkdb.
+MKDB_OPTIONS = --xml-mode --output-format=xml
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+HFILE_GLOB = $(top_srcdir)/src/*.h
+CFILE_GLOB = $(top_srcdir)/src/*.c
+
+# Header files to ignore when scanning. Use base file name, no paths
+IGNORE_HFILES= \
+ bio-gio.h \
+ channel-display-priv.h \
+ channel-usbredir-priv.h \
+ client_sw_canvas.h \
+ continuation.h \
+ controller \
+ coroutine.h \
+ decode.h \
+ desktop-integration.h \
+ display \
+ gio-coroutine.h \
+ giopipe.h \
+ smartcard-manager-priv.h \
+ spice-audio-priv.h \
+ spice-channel-cache.h \
+ spice-channel-priv.h \
+ spice-cmdline.h \
+ spice-common.h \
+ spice-file-transfer-task-priv.h \
+ spice-grabsequence-priv.h \
+ spice-gstaudio.h \
+ spice-gtk-session-priv.h \
+ spice-marshal.h \
+ spice-pulse.h \
+ spice-session-priv.h \
+ spice-uri-priv.h \
+ spice-util-priv.h \
+ spice-widget-priv.h \
+ spicy-connect.h \
+ usb-acl-helper.h \
+ usb-device-manager-priv.h \
+ usbdk_api.h \
+ usbutil.h \
+ vmcstream.h \
+ vncdisplaykeymap.h \
+ win-usb-clerk.h \
+ win-usb-dev.h \
+ win-usb-driver-install.h \
+ wocky-http-proxy.h \
+ $(NULL)
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+GTKDOC_CFLAGS = -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src -I$(top_builddir)/src $(SPICE_GLIB_CFLAGS) $(SPICE_GTK_CFLAGS) $(COMMON_CFLAGS) -DSPICE_COMPILATION
+GTKDOC_LIBS = $(top_builddir)/src/libspice-client-glib-2.0.la $(top_builddir)/src/libspice-client-gtk-3.0.la $(GTK_LIBS)
+
+include $(top_srcdir)/gtk-doc.make
+
+# Comment this out if you want 'make check' to test you doc status
+# and run some sanity checks
+if ENABLE_GTK_DOC
+TESTS_ENVIRONMENT = cd $(srcdir) && \
+ DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \
+ SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir)
+#TESTS = $(GTKDOC_CHECK)
+endif
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# -*- mode: makefile -*-
+
+####################################
+# Everything below here is generic #
+####################################
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = doc/reference
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/ld-version.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/manywarnings.m4 \
+ $(top_srcdir)/m4/spice-compile-warnings.m4 \
+ $(top_srcdir)/m4/warnings.m4 \
+ $(top_srcdir)/spice-common/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/gtk-doc.make
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACL_HELPER_DIR = @ACL_HELPER_DIR@
+ACL_LIBS = @ACL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMMON_CFLAGS = @COMMON_CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GOBJECT2_CFLAGS = @GOBJECT2_CFLAGS@
+GOBJECT2_LIBS = @GOBJECT2_LIBS@
+GREP = @GREP@
+GSTAUDIO_CFLAGS = @GSTAUDIO_CFLAGS@
+GSTAUDIO_LIBS = @GSTAUDIO_LIBS@
+GSTVIDEO_CFLAGS = @GSTVIDEO_CFLAGS@
+GSTVIDEO_LIBS = @GSTVIDEO_LIBS@
+GST_INSPECT_1_0 = @GST_INSPECT_1_0@
+GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
+GTHREAD_LIBS = @GTHREAD_LIBS@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_REQUIRED = @GTK_REQUIRED@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+JPEG_LIBS = @JPEG_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUSB_HOTPLUG_CFLAGS = @LIBUSB_HOTPLUG_CFLAGS@
+LIBUSB_HOTPLUG_LIBS = @LIBUSB_HOTPLUG_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PHODAV_CFLAGS = @PHODAV_CFLAGS@
+PHODAV_LIBS = @PHODAV_LIBS@
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PNP_IDS = @PNP_IDS@
+POFILES = @POFILES@
+POLICYDIR = @POLICYDIR@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PULSE_CFLAGS = @PULSE_CFLAGS@
+PULSE_LIBS = @PULSE_LIBS@
+PYTHON = @PYTHON@
+RANLIB = @RANLIB@
+SASL_CFLAGS = @SASL_CFLAGS@
+SASL_LIBS = @SASL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_CFLAGS = @SPICE_CFLAGS@
+SPICE_GLIB_CFLAGS = @SPICE_GLIB_CFLAGS@
+SPICE_GLIB_REQUIRES = @SPICE_GLIB_REQUIRES@
+SPICE_GTK_CFLAGS = @SPICE_GTK_CFLAGS@
+SPICE_GTK_LOCALEDIR = @SPICE_GTK_LOCALEDIR@
+SPICE_GTK_MAJOR_VERSION = @SPICE_GTK_MAJOR_VERSION@
+SPICE_GTK_MICRO_VERSION = @SPICE_GTK_MICRO_VERSION@
+SPICE_GTK_MINOR_VERSION = @SPICE_GTK_MINOR_VERSION@
+SPICE_GTK_REQUIRES = @SPICE_GTK_REQUIRES@
+SPICE_PROTOCOL_CFLAGS = @SPICE_PROTOCOL_CFLAGS@
+SPICE_PROTOCOL_LIBS = @SPICE_PROTOCOL_LIBS@
+SSL_CFLAGS = @SSL_CFLAGS@
+SSL_LIBS = @SSL_LIBS@
+STOW = @STOW@
+STRIP = @STRIP@
+USBREDIR_CFLAGS = @USBREDIR_CFLAGS@
+USBREDIR_LIBS = @USBREDIR_LIBS@
+USB_IDS = @USB_IDS@
+USE_NLS = @USE_NLS@
+VALAC = @VALAC@
+VAPIDIR = @VAPIDIR@
+VAPIGEN = @VAPIGEN@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_LDFLAGS = @WARN_LDFLAGS@
+WARN_PYFLAGS = @WARN_PYFLAGS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+XGETTEXT = @XGETTEXT@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+AUTOMAKE_OPTIONS = 1.6
+DOC_MODULE = spice-gtk
+
+# The top-level SGML file
+DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml
+
+# Source code location
+DOC_SOURCE_DIR = $(top_srcdir)/src
+
+# Extra options to supply to gtkdoc-scan.
+SCAN_OPTIONS = \
+ --deprecated-guards="SPICE_DISABLE_DEPRECATED" \
+ --ignore-decorators="G_GNUC_INTERNAL"
+
+
+# Extra options to supply to gtkdoc-mkdb.
+MKDB_OPTIONS = --xml-mode --output-format=xml
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+HFILE_GLOB = $(top_srcdir)/src/*.h
+CFILE_GLOB = $(top_srcdir)/src/*.c
+
+# Header files to ignore when scanning. Use base file name, no paths
+IGNORE_HFILES = \
+ bio-gio.h \
+ channel-display-priv.h \
+ channel-usbredir-priv.h \
+ client_sw_canvas.h \
+ continuation.h \
+ controller \
+ coroutine.h \
+ decode.h \
+ desktop-integration.h \
+ display \
+ gio-coroutine.h \
+ giopipe.h \
+ smartcard-manager-priv.h \
+ spice-audio-priv.h \
+ spice-channel-cache.h \
+ spice-channel-priv.h \
+ spice-cmdline.h \
+ spice-common.h \
+ spice-file-transfer-task-priv.h \
+ spice-grabsequence-priv.h \
+ spice-gstaudio.h \
+ spice-gtk-session-priv.h \
+ spice-marshal.h \
+ spice-pulse.h \
+ spice-session-priv.h \
+ spice-uri-priv.h \
+ spice-util-priv.h \
+ spice-widget-priv.h \
+ spicy-connect.h \
+ usb-acl-helper.h \
+ usb-device-manager-priv.h \
+ usbdk_api.h \
+ usbutil.h \
+ vmcstream.h \
+ vncdisplaykeymap.h \
+ win-usb-clerk.h \
+ win-usb-dev.h \
+ win-usb-driver-install.h \
+ wocky-http-proxy.h \
+ $(NULL)
+
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+GTKDOC_CFLAGS = -I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src -I$(top_builddir)/src $(SPICE_GLIB_CFLAGS) $(SPICE_GTK_CFLAGS) $(COMMON_CFLAGS) -DSPICE_COMPILATION
+GTKDOC_LIBS = $(top_builddir)/src/libspice-client-glib-2.0.la $(top_builddir)/src/libspice-client-gtk-3.0.la $(GTK_LIBS)
+@GTK_DOC_USE_LIBTOOL_FALSE@GTKDOC_CC = $(CC) $(INCLUDES) $(GTKDOC_DEPS_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+@GTK_DOC_USE_LIBTOOL_TRUE@GTKDOC_CC = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(INCLUDES) $(GTKDOC_DEPS_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+@GTK_DOC_USE_LIBTOOL_FALSE@GTKDOC_LD = $(CC) $(GTKDOC_DEPS_LIBS) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS)
+@GTK_DOC_USE_LIBTOOL_TRUE@GTKDOC_LD = $(LIBTOOL) --tag=CC --mode=link $(CC) $(GTKDOC_DEPS_LIBS) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS)
+@GTK_DOC_USE_LIBTOOL_FALSE@GTKDOC_RUN =
+@GTK_DOC_USE_LIBTOOL_TRUE@GTKDOC_RUN = $(LIBTOOL) --mode=execute
+
+# We set GPATH here; this gives us semantics for GNU make
+# which are more like other make's VPATH, when it comes to
+# whether a source that is a target of one rule is then
+# searched for in VPATH/GPATH.
+#
+GPATH = $(srcdir)
+TARGET_DIR = $(HTML_DIR)/$(DOC_MODULE)
+SETUP_FILES = \
+ $(content_files) \
+ $(expand_content_files) \
+ $(DOC_MAIN_SGML_FILE) \
+ $(DOC_MODULE)-sections.txt \
+ $(DOC_MODULE)-overrides.txt
+
+EXTRA_DIST = \
+ $(HTML_IMAGES) \
+ $(SETUP_FILES)
+
+DOC_STAMPS = setup-build.stamp scan-build.stamp sgml-build.stamp \
+ html-build.stamp pdf-build.stamp \
+ sgml.stamp html.stamp pdf.stamp
+
+SCANOBJ_FILES = \
+ $(DOC_MODULE).args \
+ $(DOC_MODULE).hierarchy \
+ $(DOC_MODULE).interfaces \
+ $(DOC_MODULE).prerequisites \
+ $(DOC_MODULE).signals
+
+REPORT_FILES = \
+ $(DOC_MODULE)-undocumented.txt \
+ $(DOC_MODULE)-undeclared.txt \
+ $(DOC_MODULE)-unused.txt
+
+CLEANFILES = $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS) gtkdoc-check.test
+@GTK_DOC_BUILD_HTML_FALSE@HTML_BUILD_STAMP =
+@GTK_DOC_BUILD_HTML_TRUE@HTML_BUILD_STAMP = html-build.stamp
+@GTK_DOC_BUILD_PDF_FALSE@PDF_BUILD_STAMP =
+@GTK_DOC_BUILD_PDF_TRUE@PDF_BUILD_STAMP = pdf-build.stamp
+
+#### setup ####
+GTK_DOC_V_SETUP = $(GTK_DOC_V_SETUP_$(V))
+GTK_DOC_V_SETUP_ = $(GTK_DOC_V_SETUP_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_SETUP_0 = @echo " DOC Preparing build";
+
+#### scan ####
+GTK_DOC_V_SCAN = $(GTK_DOC_V_SCAN_$(V))
+GTK_DOC_V_SCAN_ = $(GTK_DOC_V_SCAN_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_SCAN_0 = @echo " DOC Scanning header files";
+GTK_DOC_V_INTROSPECT = $(GTK_DOC_V_INTROSPECT_$(V))
+GTK_DOC_V_INTROSPECT_ = $(GTK_DOC_V_INTROSPECT_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_INTROSPECT_0 = @echo " DOC Introspecting gobjects";
+
+#### xml ####
+GTK_DOC_V_XML = $(GTK_DOC_V_XML_$(V))
+GTK_DOC_V_XML_ = $(GTK_DOC_V_XML_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_XML_0 = @echo " DOC Building XML";
+
+#### html ####
+GTK_DOC_V_HTML = $(GTK_DOC_V_HTML_$(V))
+GTK_DOC_V_HTML_ = $(GTK_DOC_V_HTML_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_HTML_0 = @echo " DOC Building HTML";
+GTK_DOC_V_XREF = $(GTK_DOC_V_XREF_$(V))
+GTK_DOC_V_XREF_ = $(GTK_DOC_V_XREF_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_XREF_0 = @echo " DOC Fixing cross-references";
+
+#### pdf ####
+GTK_DOC_V_PDF = $(GTK_DOC_V_PDF_$(V))
+GTK_DOC_V_PDF_ = $(GTK_DOC_V_PDF_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_PDF_0 = @echo " DOC Building PDF";
+
+# Comment this out if you want 'make check' to test you doc status
+# and run some sanity checks
+@ENABLE_GTK_DOC_TRUE@TESTS_ENVIRONMENT = cd $(srcdir) && \
+@ENABLE_GTK_DOC_TRUE@ DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \
+@ENABLE_GTK_DOC_TRUE@ SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir)
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/gtk-doc.make $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign doc/reference/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign doc/reference/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+$(top_srcdir)/gtk-doc.make $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+check-am: all-am
+check: check-am
+@ENABLE_GTK_DOC_FALSE@all-local:
+all-am: Makefile all-local
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-local
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic \
+ maintainer-clean-local
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-local
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am all-local check check-am clean clean-generic \
+ clean-libtool clean-local cscopelist-am ctags-am dist-hook \
+ distclean distclean-generic distclean-libtool distclean-local \
+ distdir dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-data-local \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ maintainer-clean-local mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am uninstall-local
+
+.PRECIOUS: Makefile
+
+
+gtkdoc-check.test: Makefile
+ $(AM_V_GEN)echo "#!/bin/sh -e" > $@; \
+ echo "$(GTKDOC_CHECK_PATH) || exit 1" >> $@; \
+ chmod +x $@
+
+all-gtk-doc: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP)
+.PHONY: all-gtk-doc
+
+@ENABLE_GTK_DOC_TRUE@all-local: all-gtk-doc
+
+docs: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP)
+
+$(REPORT_FILES): sgml-build.stamp
+
+setup-build.stamp:
+ -$(GTK_DOC_V_SETUP)if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \
+ files=`echo $(SETUP_FILES) $(DOC_MODULE).types`; \
+ if test "x$$files" != "x" ; then \
+ for file in $$files ; do \
+ destdir=`dirname $(abs_builddir)/$$file`; \
+ test -d "$$destdir" || mkdir -p "$$destdir"; \
+ test -f $(abs_srcdir)/$$file && \
+ cp -pf $(abs_srcdir)/$$file $(abs_builddir)/$$file || true; \
+ done; \
+ fi; \
+ fi
+ $(AM_V_at)touch setup-build.stamp
+
+scan-build.stamp: setup-build.stamp $(HFILE_GLOB) $(CFILE_GLOB)
+ $(GTK_DOC_V_SCAN)_source_dir='' ; \
+ for i in $(DOC_SOURCE_DIR) ; do \
+ _source_dir="$${_source_dir} --source-dir=$$i" ; \
+ done ; \
+ gtkdoc-scan --module=$(DOC_MODULE) --ignore-headers="$(IGNORE_HFILES)" $${_source_dir} $(SCAN_OPTIONS) $(EXTRA_HFILES)
+ $(GTK_DOC_V_INTROSPECT)if grep -l '^..*$$' $(DOC_MODULE).types > /dev/null 2>&1 ; then \
+ scanobj_options=""; \
+ gtkdoc-scangobj 2>&1 --help | grep >/dev/null "\-\-verbose"; \
+ if test "$$?" = "0"; then \
+ if test "x$(V)" = "x1"; then \
+ scanobj_options="--verbose"; \
+ fi; \
+ fi; \
+ CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" RUN="$(GTKDOC_RUN)" CFLAGS="$(GTKDOC_CFLAGS) $(CFLAGS)" LDFLAGS="$(GTKDOC_LIBS) $(LDFLAGS)" \
+ gtkdoc-scangobj $(SCANGOBJ_OPTIONS) $$scanobj_options --module=$(DOC_MODULE); \
+ else \
+ for i in $(SCANOBJ_FILES) ; do \
+ test -f $$i || touch $$i ; \
+ done \
+ fi
+ $(AM_V_at)touch scan-build.stamp
+
+$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp
+ @true
+
+sgml-build.stamp: setup-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(HFILE_GLOB) $(CFILE_GLOB) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt $(expand_content_files) xml/gtkdocentities.ent
+ $(GTK_DOC_V_XML)_source_dir='' ; \
+ for i in $(DOC_SOURCE_DIR) ; do \
+ _source_dir="$${_source_dir} --source-dir=$$i" ; \
+ done ; \
+ gtkdoc-mkdb --module=$(DOC_MODULE) --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $${_source_dir} $(MKDB_OPTIONS)
+ $(AM_V_at)touch sgml-build.stamp
+
+sgml.stamp: sgml-build.stamp
+ @true
+
+xml/gtkdocentities.ent: Makefile
+ $(GTK_DOC_V_XML)$(MKDIR_P) $(@D) && ( \
+ echo "<!ENTITY package \"$(PACKAGE)\">"; \
+ echo "<!ENTITY package_bugreport \"$(PACKAGE_BUGREPORT)\">"; \
+ echo "<!ENTITY package_name \"$(PACKAGE_NAME)\">"; \
+ echo "<!ENTITY package_string \"$(PACKAGE_STRING)\">"; \
+ echo "<!ENTITY package_tarname \"$(PACKAGE_TARNAME)\">"; \
+ echo "<!ENTITY package_url \"$(PACKAGE_URL)\">"; \
+ echo "<!ENTITY package_version \"$(PACKAGE_VERSION)\">"; \
+ ) > $@
+
+html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files)
+ $(GTK_DOC_V_HTML)rm -rf html && mkdir html && \
+ mkhtml_options=""; \
+ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-verbose"; \
+ if test "$$?" = "0"; then \
+ if test "x$(V)" = "x1"; then \
+ mkhtml_options="$$mkhtml_options --verbose"; \
+ fi; \
+ fi; \
+ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \
+ if test "$$?" = "0"; then \
+ mkhtml_options="$$mkhtml_options --path=\"$(abs_srcdir)\""; \
+ fi; \
+ cd html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
+ -@test "x$(HTML_IMAGES)" = "x" || \
+ for file in $(HTML_IMAGES) ; do \
+ if test -f $(abs_srcdir)/$$file ; then \
+ cp $(abs_srcdir)/$$file $(abs_builddir)/html; \
+ fi; \
+ if test -f $(abs_builddir)/$$file ; then \
+ cp $(abs_builddir)/$$file $(abs_builddir)/html; \
+ fi; \
+ done;
+ $(GTK_DOC_V_XREF)gtkdoc-fixxref --module=$(DOC_MODULE) --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
+ $(AM_V_at)touch html-build.stamp
+
+pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files)
+ $(GTK_DOC_V_PDF)rm -f $(DOC_MODULE).pdf && \
+ mkpdf_options=""; \
+ gtkdoc-mkpdf 2>&1 --help | grep >/dev/null "\-\-verbose"; \
+ if test "$$?" = "0"; then \
+ if test "x$(V)" = "x1"; then \
+ mkpdf_options="$$mkpdf_options --verbose"; \
+ fi; \
+ fi; \
+ if test "x$(HTML_IMAGES)" != "x"; then \
+ for img in $(HTML_IMAGES); do \
+ part=`dirname $$img`; \
+ echo $$mkpdf_options | grep >/dev/null "\-\-imgdir=$$part "; \
+ if test $$? != 0; then \
+ mkpdf_options="$$mkpdf_options --imgdir=$$part"; \
+ fi; \
+ done; \
+ fi; \
+ gtkdoc-mkpdf --path="$(abs_srcdir)" $$mkpdf_options $(DOC_MODULE) $(DOC_MAIN_SGML_FILE) $(MKPDF_OPTIONS)
+ $(AM_V_at)touch pdf-build.stamp
+
+##############
+
+clean-local:
+ @rm -f *~ *.bak
+ @rm -rf .libs
+ @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-types" ; then \
+ rm -f $(DOC_MODULE).types; \
+ fi
+ @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-sections" ; then \
+ rm -f $(DOC_MODULE)-sections.txt; \
+ fi
+
+distclean-local:
+ @rm -rf xml html $(REPORT_FILES) $(DOC_MODULE).pdf \
+ $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt
+ @if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \
+ rm -f $(SETUP_FILES) $(DOC_MODULE).types; \
+ fi
+
+maintainer-clean-local:
+ @rm -rf xml html
+
+install-data-local:
+ @installfiles=`echo $(builddir)/html/*`; \
+ if test "$$installfiles" = '$(builddir)/html/*'; \
+ then echo 1>&2 'Nothing to install' ; \
+ else \
+ if test -n "$(DOC_MODULE_VERSION)"; then \
+ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \
+ else \
+ installdir="$(DESTDIR)$(TARGET_DIR)"; \
+ fi; \
+ $(mkinstalldirs) $${installdir} ; \
+ for i in $$installfiles; do \
+ echo ' $(INSTALL_DATA) '$$i ; \
+ $(INSTALL_DATA) $$i $${installdir}; \
+ done; \
+ if test -n "$(DOC_MODULE_VERSION)"; then \
+ mv -f $${installdir}/$(DOC_MODULE).devhelp2 \
+ $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp2; \
+ fi; \
+ $(GTKDOC_REBASE) --relative --dest-dir=$(DESTDIR) --html-dir=$${installdir}; \
+ fi
+
+uninstall-local:
+ @if test -n "$(DOC_MODULE_VERSION)"; then \
+ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \
+ else \
+ installdir="$(DESTDIR)$(TARGET_DIR)"; \
+ fi; \
+ rm -rf $${installdir}
+
+#
+# Require gtk-doc when making dist
+#
+@HAVE_GTK_DOC_TRUE@dist-check-gtkdoc: docs
+@HAVE_GTK_DOC_FALSE@dist-check-gtkdoc:
+@HAVE_GTK_DOC_FALSE@ @echo "*** gtk-doc is needed to run 'make dist'. ***"
+@HAVE_GTK_DOC_FALSE@ @echo "*** gtk-doc was not found when 'configure' ran. ***"
+@HAVE_GTK_DOC_FALSE@ @echo "*** please install gtk-doc and rerun 'configure'. ***"
+@HAVE_GTK_DOC_FALSE@ @false
+
+dist-hook: dist-check-gtkdoc all-gtk-doc dist-hook-local
+ @mkdir $(distdir)/html
+ @cp ./html/* $(distdir)/html
+ @-cp ./$(DOC_MODULE).pdf $(distdir)/
+ @-cp ./$(DOC_MODULE).types $(distdir)/
+ @-cp ./$(DOC_MODULE)-sections.txt $(distdir)/
+ @cd $(distdir) && rm -f $(DISTCLEANFILES)
+ @$(GTKDOC_REBASE) --online --relative --html-dir=$(distdir)/html
+
+.PHONY : dist-hook-local docs
+#TESTS = $(GTKDOC_CHECK)
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Spice Audio: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="application-support.html" title="Application Support, from spice-client-glib">
+<link rel="prev" href="application-support.html" title="Application Support, from spice-client-glib">
+<link rel="next" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceAudio.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceAudio.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_properties"> <span class="dim">|</span>
+ <a href="#SpiceAudio.properties" class="shortcut">Properties</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="application-support.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="application-support.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceSmartcardManager.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceAudio"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceAudio.top_of_page"></a>Spice Audio</span></h2>
+<p>Spice Audio — a helper to play and to record audio channels</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceAudio.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceAudio.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="returnvalue">SpiceAudio</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceAudio.html#spice-audio-get" title="spice_audio_get ()">spice_audio_get</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="returnvalue">SpiceAudio</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceAudio.html#spice-audio-new" title="spice_audio_new ()">spice_audio_new</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceAudio.properties"></a><h2>Properties</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="properties_type">
+<col width="300px" class="properties_name">
+<col width="200px" class="properties_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-The-Main-Event-Loop.html#GMainContext"><span class="type">GMainContext</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceAudio.html#SpiceAudio--main-context" title="The “main-context” property">main-context</a></td>
+<td class="property_flags">Read / Write / Construct Only</td>
+</tr>
+<tr>
+<td class="property_type">
+<a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceAudio.html#SpiceAudio--session" title="The “session” property">session</a></td>
+<td class="property_flags">Read / Write / Construct Only</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceAudio.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceAudio.html#SpiceAudio-struct" title="struct SpiceAudio">SpiceAudio</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceAudio.html#SpiceAudioClass" title="struct SpiceAudioClass">SpiceAudioClass</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceAudio.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> SpiceAudio
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceAudio.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceAudio.description"></a><h2>Description</h2>
+<p>A class that handles the playback and record channels for your
+application, and connect them to the default sound system.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceAudio.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-audio-get"></a><h3>spice_audio_get ()</h3>
+<pre class="programlisting"><a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="returnvalue">SpiceAudio</span></a> *
+spice_audio_get (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-The-Main-Event-Loop.html#GMainContext"><span class="type">GMainContext</span></a> *context</code></em>);</pre>
+<p>Gets the <a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="type">SpiceAudio</span></a> associated with the passed in <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a>.
+A new <a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="type">SpiceAudio</span></a> instance will be created the first time this
+function is called for a certain <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a>.</p>
+<p>Note that this function returns a weak reference, which should not be used
+after the <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> itself has been unref-ed by the caller.</p>
+<div class="refsect3">
+<a name="spice-audio-get.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> to connect to</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>context</p></td>
+<td class="parameter_description"><p> a <a href="/usr/share/gtk-doc/html/glibglib-The-Main-Event-Loop.html#GMainContext"><span class="type">GMainContext</span></a> to attach to (or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> for default). </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-audio-get.returns"></a><h4>Returns</h4>
+<p> a weak reference to a <a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="type">SpiceAudio</span></a>
+instance or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if failed. </p>
+<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-audio-new"></a><h3>spice_audio_new ()</h3>
+<pre class="programlisting"><a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="returnvalue">SpiceAudio</span></a> *
+spice_audio_new (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-The-Main-Event-Loop.html#GMainContext"><span class="type">GMainContext</span></a> *context</code></em>,
+ <em class="parameter"><code>const <span class="type">char</span> *name</code></em>);</pre>
+<div class="warning">
+<p><code class="literal">spice_audio_new</code> has been deprecated since version 0.8 and should not be used in newly-written code.</p>
+<p>Use <a class="link" href="SpiceAudio.html#spice-audio-get" title="spice_audio_get ()"><code class="function">spice_audio_get()</code></a> instead</p>
+</div>
+<p>Once instantiated, <a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="type">SpiceAudio</span></a> will handle the playback and record
+channels to stream to your local audio system.</p>
+<div class="refsect3">
+<a name="spice-audio-new.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> to connect to</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>context</p></td>
+<td class="parameter_description"><p> a <a href="/usr/share/gtk-doc/html/glibglib-The-Main-Event-Loop.html#GMainContext"><span class="type">GMainContext</span></a> to attach to (or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> for
+default). </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>name</p></td>
+<td class="parameter_description"><p> a name for the audio channels (or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> for
+application name). </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-audio-new.returns"></a><h4>Returns</h4>
+<p> a new <a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="type">SpiceAudio</span></a> instance or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if no backend or failed.</p>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceAudio.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceAudio-struct"></a><h3>struct SpiceAudio</h3>
+<pre class="programlisting">struct SpiceAudio;</pre>
+<p>The <a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="type">SpiceAudio</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceAudioClass"></a><h3>struct SpiceAudioClass</h3>
+<pre class="programlisting">struct SpiceAudioClass {
+ GObjectClass parent_class;
+};
+</pre>
+<p>Class structure for <a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="type">SpiceAudio</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceAudioClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody></tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceAudio.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="SpiceAudio--main-context"></a><h3>The <code class="literal">“main-context”</code> property</h3>
+<pre class="programlisting"> “main-context” <a href="/usr/share/gtk-doc/html/glibglib-The-Main-Event-Loop.html#GMainContext"><span class="type">GMainContext</span></a> *</pre>
+<p>GMainContext to use for the event source.</p>
+<p>Flags: Read / Write / Construct Only</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceAudio--session"></a><h3>The <code class="literal">“session”</code> property</h3>
+<pre class="programlisting"> “session” <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *</pre>
+<p><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> this <a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="type">SpiceAudio</span></a> is associated with</p>
+<p>Flags: Read / Write / Construct Only</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceAudio.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceRecordChannel.html" title="Record Channel"><span class="type">SpiceRecordChannel</span></a>, and <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Spice Channel: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="prev" href="SpiceSession.html" title="Spice Session">
+<link rel="next" href="SpiceCursorChannel.html" title="Cursor Channel">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceChannel.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceChannel.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_properties"> <span class="dim">|</span>
+ <a href="#SpiceChannel.properties" class="shortcut">Properties</a></span><span id="nav_signals"> <span class="dim">|</span>
+ <a href="#SpiceChannel.signals" class="shortcut">Signals</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceSession.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceCursorChannel.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceChannel"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceChannel.top_of_page"></a>Spice Channel</span></h2>
+<p>Spice Channel — the base channel class</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceChannel.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceChannel.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="returnvalue">SpiceChannel</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-new" title="spice_channel_new ()">spice_channel_new</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-destroy" title="spice_channel_destroy ()">spice_channel_destroy</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-connect" title="spice_channel_connect ()">spice_channel_connect</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-open-fd" title="spice_channel_open_fd ()">spice_channel_open_fd</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-disconnect" title="spice_channel_disconnect ()">spice_channel_disconnect</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-test-capability" title="spice_channel_test_capability ()">spice_channel_test_capability</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-test-common-capability" title="spice_channel_test_common_capability ()">spice_channel_test_common_capability</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-type-to-string" title="spice_channel_type_to_string ()">spice_channel_type_to_string</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="returnvalue">gint</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-string-to-type" title="spice_channel_string_to_type ()">spice_channel_string_to_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-set-capability" title="spice_channel_set_capability ()">spice_channel_set_capability</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-flush-async" title="spice_channel_flush_async ()">spice_channel_flush_async</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-flush-finish" title="spice_channel_flush_finish ()">spice_channel_flush_finish</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">const <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="returnvalue">GError</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceChannel.html#spice-channel-get-error" title="spice_channel_get_error ()">spice_channel_get_error</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceChannel.properties"></a><h2>Properties</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="properties_type">
+<col width="300px" class="properties_name">
+<col width="200px" class="properties_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceChannel.html#SpiceChannel--channel-id" title="The “channel-id” property">channel-id</a></td>
+<td class="property_flags">Read / Write / Construct Only</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceChannel.html#SpiceChannel--channel-type" title="The “channel-type” property">channel-type</a></td>
+<td class="property_flags">Read / Write / Construct Only</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/gioGSocket.html#GSocket-struct"><span class="type">GSocket</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceChannel.html#SpiceChannel--socket" title="The “socket” property">socket</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type">
+<a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceChannel.html#SpiceChannel--spice-session" title="The “spice-session” property">spice-session</a></td>
+<td class="property_flags">Read / Write / Construct Only</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gulong"><span class="type">gulong</span></a></td>
+<td class="property_name"><a class="link" href="SpiceChannel.html#SpiceChannel--total-read-bytes" title="The “total-read-bytes” property">total-read-bytes</a></td>
+<td class="property_flags">Read</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceChannel.signals"></a><h2>Signals</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="signals_return">
+<col width="300px" class="signals_name">
+<col width="200px" class="signals_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceChannel.html#SpiceChannel-channel-event" title="The “channel-event” signal">channel-event</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceChannel.html#SpiceChannel-open-fd" title="The “open-fd” signal">open-fd</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceChannel.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="SpiceChannel.html#SpiceChannelEvent" title="enum SpiceChannelEvent">SpiceChannelEvent</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword"> </td>
+<td class="function_name"><a class="link" href="SpiceChannel.html#SpiceChannel-struct" title="SpiceChannel">SpiceChannel</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword"> </td>
+<td class="function_name"><a class="link" href="SpiceChannel.html#SpiceChannelClass" title="SpiceChannelClass">SpiceChannelClass</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceChannel.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="https://developer.gnome.org/gobject/unstable/gobject-Enumeration-and-Flag-Types.html">GEnum</a>
+ <span class="lineart">╰──</span> SpiceChannelEvent
+ <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> SpiceChannel
+ <span class="lineart">├──</span> <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel">SpiceCursorChannel</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+ <span class="lineart">├──</span> <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceRecordChannel.html" title="Record Channel">SpiceRecordChannel</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceSmartcardChannel.html" title="Smartcard Channel">SpiceSmartcardChannel</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceUsbredirChannel.html" title="USB Redirection Channel">SpiceUsbredirChannel</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceChannel.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceChannel.description"></a><h2>Description</h2>
+<p><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> is the base class for the different kind of Spice
+channel connections, such as <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a>, or
+<a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a>.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceChannel.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-channel-new"></a><h3>spice_channel_new ()</h3>
+<pre class="programlisting"><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="returnvalue">SpiceChannel</span></a> *
+spice_channel_new (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *s</code></em>,
+ <em class="parameter"><code><span class="type">int</span> type</code></em>,
+ <em class="parameter"><code><span class="type">int</span> id</code></em>);</pre>
+<p>Create a new <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> of type <em class="parameter"><code>type</code></em>
+, and channel ID <em class="parameter"><code>id</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-channel-new.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>s</p></td>
+<td class="parameter_description"><p>the <em class="parameter"><code>SpiceSession</code></em>
+the channel is linked to</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>type</p></td>
+<td class="parameter_description"><p>the requested SPICECHANNELPRIVATE type</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>id</p></td>
+<td class="parameter_description"><p>the channel-id</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-channel-new.returns"></a><h4>Returns</h4>
+<p> a weak reference to <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a>, the session owns the reference</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-channel-destroy"></a><h3>spice_channel_destroy ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_channel_destroy (<em class="parameter"><code><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel</code></em>);</pre>
+<div class="warning">
+<p><code class="literal">spice_channel_destroy</code> has been deprecated since version 0.27 and should not be used in newly-written code.</p>
+<p>this function has been deprecated because it is
+misleading, the object is not actually destroyed. Instead, it is
+recommended to call explicitely <a class="link" href="SpiceChannel.html#spice-channel-disconnect" title="spice_channel_disconnect ()"><code class="function">spice_channel_disconnect()</code></a> and
+<a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#g-object-unref"><code class="function">g_object_unref()</code></a>.</p>
+</div>
+<p>Disconnect and unref the <em class="parameter"><code>channel</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-channel-destroy.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-channel-connect"></a><h3>spice_channel_connect ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_channel_connect (<em class="parameter"><code><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel</code></em>);</pre>
+<p>Connect the channel, using <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> connection informations</p>
+<div class="refsect3">
+<a name="spice-channel-connect.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-channel-connect.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> on success.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-channel-open-fd"></a><h3>spice_channel_open_fd ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_channel_open_fd (<em class="parameter"><code><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><span class="type">int</span> fd</code></em>);</pre>
+<p>Connect the channel using <em class="parameter"><code>fd</code></em>
+ socket.</p>
+<p>If <em class="parameter"><code>fd</code></em>
+ is -1, a valid fd will be requested later via the
+SpiceChannel::open-fd signal.</p>
+<div class="refsect3">
+<a name="spice-channel-open-fd.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>fd</p></td>
+<td class="parameter_description"><p>a file descriptor (socket) or -1.
+request mechanism</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-channel-open-fd.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> on success.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-channel-disconnect"></a><h3>spice_channel_disconnect ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_channel_disconnect (<em class="parameter"><code><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a class="link" href="SpiceChannel.html#SpiceChannelEvent" title="enum SpiceChannelEvent"><span class="type">SpiceChannelEvent</span></a> reason</code></em>);</pre>
+<p>Close the socket and reset connection specific data. Finally, emit
+<em class="parameter"><code>reason</code></em>
+ <a class="link" href="SpiceChannel.html#SpiceChannel-channel-event" title="The “channel-event” signal"><span class="type">“channel-event”</span></a> on main context if not
+<a class="link" href="SpiceChannel.html#SPICE-CHANNEL-NONE:CAPS"><span class="type">SPICE_CHANNEL_NONE</span></a>.</p>
+<div class="refsect3">
+<a name="spice-channel-disconnect.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>reason</p></td>
+<td class="parameter_description"><p>a channel event emitted on main context (or <a class="link" href="SpiceChannel.html#SPICE-CHANNEL-NONE:CAPS"><span class="type">SPICE_CHANNEL_NONE</span></a>)</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-channel-test-capability"></a><h3>spice_channel_test_capability ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_channel_test_capability (<em class="parameter"><code><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> cap</code></em>);</pre>
+<p>Test availability of remote "channel kind capability".</p>
+<div class="refsect3">
+<a name="spice-channel-test-capability.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>cap</p></td>
+<td class="parameter_description"><p>a capability</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-channel-test-capability.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if <em class="parameter"><code>cap</code></em>
+(channel kind capability) is available.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-channel-test-common-capability"></a><h3>spice_channel_test_common_capability ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_channel_test_common_capability (<em class="parameter"><code><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> cap</code></em>);</pre>
+<p>Test availability of remote "common channel capability".</p>
+<div class="refsect3">
+<a name="spice-channel-test-common-capability.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>cap</p></td>
+<td class="parameter_description"><p>a capability</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-channel-test-common-capability.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if <em class="parameter"><code>cap</code></em>
+(common channel capability) is available.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-channel-type-to-string"></a><h3>spice_channel_type_to_string ()</h3>
+<pre class="programlisting">const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+spice_channel_type_to_string (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> type</code></em>);</pre>
+<p>Convert a channel-type property value to a string.</p>
+<div class="refsect3">
+<a name="spice-channel-type-to-string.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>type</p></td>
+<td class="parameter_description"><p>a channel-type property value</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-channel-type-to-string.returns"></a><h4>Returns</h4>
+<p> string representation of <em class="parameter"><code>type</code></em>
+.</p>
+</div>
+<p class="since">Since: 0.20</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-channel-string-to-type"></a><h3>spice_channel_string_to_type ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="returnvalue">gint</span></a>
+spice_channel_string_to_type (<em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *str</code></em>);</pre>
+<p>Convert a channel-type property value to a string.</p>
+<div class="refsect3">
+<a name="spice-channel-string-to-type.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>str</p></td>
+<td class="parameter_description"><p>a string representation of the channel-type property</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-channel-string-to-type.returns"></a><h4>Returns</h4>
+<p> the channel-type property value for a <em class="parameter"><code>str</code></em>
+channel</p>
+</div>
+<p class="since">Since: 0.21</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-channel-set-capability"></a><h3>spice_channel_set_capability ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_channel_set_capability (<em class="parameter"><code><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> cap</code></em>);</pre>
+<div class="warning">
+<p><code class="literal">spice_channel_set_capability</code> has been deprecated since version 0.13 and should not be used in newly-written code.</p>
+<p>this function has been removed</p>
+</div>
+<p>Enable specific channel-kind capability.</p>
+<div class="refsect3">
+<a name="spice-channel-set-capability.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>cap</p></td>
+<td class="parameter_description"><p>a capability</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-channel-flush-async"></a><h3>spice_channel_flush_async ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_channel_flush_async (<em class="parameter"><code><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGCancellable.html#GCancellable-struct"><span class="type">GCancellable</span></a> *cancellable</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncReadyCallback"><span class="type">GAsyncReadyCallback</span></a> callback</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data</code></em>);</pre>
+<p>Forces an asynchronous write of all user-space buffered data for
+the given channel.</p>
+<p>When the operation is finished callback will be called. You can
+then call <a class="link" href="SpiceChannel.html#spice-channel-flush-finish" title="spice_channel_flush_finish ()"><code class="function">spice_channel_flush_finish()</code></a> to get the result of the
+operation.</p>
+<div class="refsect3">
+<a name="spice-channel-flush-async.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>cancellable</p></td>
+<td class="parameter_description"><p> optional GCancellable object, <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> to ignore. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>callback</p></td>
+<td class="parameter_description"><p> callback to call when the request is satisfied. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="The callback is valid until first called."><span class="acronym">scope async</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p> the data to pass to callback function. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="This parameter is a 'user_data', for callbacks; many bindings can pass NULL here."><span class="acronym">closure</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.15</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-channel-flush-finish"></a><h3>spice_channel_flush_finish ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_channel_flush_finish (<em class="parameter"><code><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncResult-struct"><span class="type">GAsyncResult</span></a> *result</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> **error</code></em>);</pre>
+<p>Finishes flushing a channel.</p>
+<div class="refsect3">
+<a name="spice-channel-flush-finish.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>result</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncResult-struct"><span class="type">GAsyncResult</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>error</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> location to store the error occurring, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>
+to ignore.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-channel-flush-finish.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if flush operation succeeded, <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> otherwise.</p>
+</div>
+<p class="since">Since: 0.15</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-channel-get-error"></a><h3>spice_channel_get_error ()</h3>
+<pre class="programlisting">const <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="returnvalue">GError</span></a> *
+spice_channel_get_error (<em class="parameter"><code><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel</code></em>);</pre>
+<p>Retrieves the <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> currently set on channel, if the <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a>
+is in error state and can provide additional error details.</p>
+<div class="refsect3">
+<a name="spice-channel-get-error.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-channel-get-error.returns"></a><h4>Returns</h4>
+<p> the pointer to the error, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a></p>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceChannel.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceChannelEvent"></a><h3>enum SpiceChannelEvent</h3>
+<p>An event, emitted by <a class="link" href="SpiceChannel.html#SpiceChannel-channel-event" title="The “channel-event” signal"><span class="type">“channel-event”</span></a> signal.</p>
+<div class="refsect3">
+<a name="SpiceChannelEvent.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CHANNEL-NONE:CAPS"></a>SPICE_CHANNEL_NONE</p></td>
+<td class="enum_member_description">
+<p>no event, or ignored event</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CHANNEL-OPENED:CAPS"></a>SPICE_CHANNEL_OPENED</p></td>
+<td class="enum_member_description">
+<p>connection is authentified and ready</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CHANNEL-SWITCHING:CAPS"></a>SPICE_CHANNEL_SWITCHING</p></td>
+<td class="enum_member_description">
+<p>disconnecting from the current host and connecting to the target host.</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CHANNEL-CLOSED:CAPS"></a>SPICE_CHANNEL_CLOSED</p></td>
+<td class="enum_member_description">
+<p>connection is closed normally (sent if channel was ready)</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CHANNEL-ERROR-CONNECT:CAPS"></a>SPICE_CHANNEL_ERROR_CONNECT</p></td>
+<td class="enum_member_description">
+<p>connection error</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CHANNEL-ERROR-TLS:CAPS"></a>SPICE_CHANNEL_ERROR_TLS</p></td>
+<td class="enum_member_description">
+<p>SSL error</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CHANNEL-ERROR-LINK:CAPS"></a>SPICE_CHANNEL_ERROR_LINK</p></td>
+<td class="enum_member_description">
+<p>error during link process</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CHANNEL-ERROR-AUTH:CAPS"></a>SPICE_CHANNEL_ERROR_AUTH</p></td>
+<td class="enum_member_description">
+<p>authentication error</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CHANNEL-ERROR-IO:CAPS"></a>SPICE_CHANNEL_ERROR_IO</p></td>
+<td class="enum_member_description">
+<p>IO error</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceChannel-struct"></a><h3>SpiceChannel</h3>
+<pre class="programlisting">typedef struct _SpiceChannel SpiceChannel;</pre>
+<p>The <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceChannelClass"></a><h3>SpiceChannelClass</h3>
+<pre class="programlisting">typedef struct {
+ GObjectClass parent_class;
+
+ /* signals, main context */
+ void (*channel_event)(SpiceChannel *channel, SpiceChannelEvent event);
+ void (*open_fd)(SpiceChannel *channel, int with_tls);
+} SpiceChannelClass;
+</pre>
+<p>Class structure for <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceChannelClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceChannelClass.channel-event"></a>channel_event</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceChannel.html#SpiceChannel-channel-event" title="The “channel-event” signal"><span class="type">“channel_event”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceChannelClass.open-fd"></a>open_fd</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceChannel.html#SpiceChannel-open-fd" title="The “open-fd” signal"><span class="type">“open_fd”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceChannel.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="SpiceChannel--channel-id"></a><h3>The <code class="literal">“channel-id”</code> property</h3>
+<pre class="programlisting"> “channel-id” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>Channel ID.</p>
+<p>Flags: Read / Write / Construct Only</p>
+<p>Allowed values: >= -1</p>
+<p>Default value: -1</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceChannel--channel-type"></a><h3>The <code class="literal">“channel-type”</code> property</h3>
+<pre class="programlisting"> “channel-type” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>Channel type.</p>
+<p>Flags: Read / Write / Construct Only</p>
+<p>Allowed values: >= -1</p>
+<p>Default value: -1</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceChannel--socket"></a><h3>The <code class="literal">“socket”</code> property</h3>
+<pre class="programlisting"> “socket” <a href="/usr/share/gtk-doc/html/gioGSocket.html#GSocket-struct"><span class="type">GSocket</span></a> *</pre>
+<p>Get the underlying <a href="/usr/share/gtk-doc/html/gioGSocket.html#GSocket-struct"><span class="type">GSocket</span></a>. Note that you should not read or
+write any data to it directly since this will likely corrupt
+the channel stream. This property is mainly useful to get some
+connections details.</p>
+<p>Flags: Read</p>
+<p class="since">Since: 0.33</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceChannel--spice-session"></a><h3>The <code class="literal">“spice-session”</code> property</h3>
+<pre class="programlisting"> “spice-session” <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *</pre>
+<p>Spice session.</p>
+<p>Flags: Read / Write / Construct Only</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceChannel--total-read-bytes"></a><h3>The <code class="literal">“total-read-bytes”</code> property</h3>
+<pre class="programlisting"> “total-read-bytes” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gulong"><span class="type">gulong</span></a></pre>
+<p>Total read bytes.</p>
+<p>Flags: Read</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceChannel.signal-details"></a><h2>Signal Details</h2>
+<div class="refsect2">
+<a name="SpiceChannel-channel-event"></a><h3>The <code class="literal">“channel-event”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel,
+ <a class="link" href="SpiceChannel.html#SpiceChannelEvent" title="enum SpiceChannelEvent"><span class="type">SpiceChannelEvent</span></a> event,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceChannel.html#SpiceChannel-channel-event" title="The “channel-event” signal"><span class="type">“channel-event”</span></a> signal is emitted when the
+state of the connection is changed. In case of errors,
+<a class="link" href="SpiceChannel.html#spice-channel-get-error" title="spice_channel_get_error ()"><code class="function">spice_channel_get_error()</code></a> may provide additional informations
+on the source of the error.</p>
+<div class="refsect3">
+<a name="SpiceChannel-channel-event.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>the channel that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>event</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceChannel.html#SpiceChannelEvent" title="enum SpiceChannelEvent"><span class="type">SpiceChannelEvent</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceChannel-open-fd"></a><h3>The <code class="literal">“open-fd”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> with_tls,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceChannel.html#SpiceChannel-open-fd" title="The “open-fd” signal"><span class="type">“open-fd”</span></a> signal is emitted when a new
+connection is requested. This signal is emitted when the
+connection is made with <a class="link" href="SpiceSession.html#spice-session-open-fd" title="spice_session_open_fd ()"><code class="function">spice_session_open_fd()</code></a>.</p>
+<div class="refsect3">
+<a name="SpiceChannel-open-fd.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>the channel that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>with_tls</p></td>
+<td class="parameter_description"><p>wether TLS connection is requested</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceChannel.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a>, <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> and other channels</p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Cursor Channel: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="prev" href="SpiceChannel.html" title="Spice Channel">
+<link rel="next" href="SpiceDisplayChannel.html" title="Display Channel">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceCursorChannel.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceCursorChannel.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_signals"> <span class="dim">|</span>
+ <a href="#SpiceCursorChannel.signals" class="shortcut">Signals</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceChannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceDisplayChannel.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceCursorChannel"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceCursorChannel.top_of_page"></a>Cursor Channel</span></h2>
+<p>Cursor Channel — update cursor shape and position</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceCursorChannel.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceCursorChannel.signals"></a><h2>Signals</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="signals_return">
+<col width="300px" class="signals_name">
+<col width="200px" class="signals_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-hide" title="The “cursor-hide” signal">cursor-hide</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-move" title="The “cursor-move” signal">cursor-move</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-reset" title="The “cursor-reset” signal">cursor-reset</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-set" title="The “cursor-set” signal">cursor-set</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceCursorChannel.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-struct" title="struct SpiceCursorChannel">SpiceCursorChannel</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceCursorChannel.html#SpiceCursorChannelClass" title="struct SpiceCursorChannelClass">SpiceCursorChannelClass</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceCursorChannel.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+ <span class="lineart">╰──</span> SpiceCursorChannel
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceCursorChannel.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceCursorChannel.description"></a><h2>Description</h2>
+<p>The Spice protocol defines a set of messages for controlling cursor
+shape and position on the remote display area. The cursor changes
+that should be reflected on the display are notified by
+signals. See for example <a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-set" title="The “cursor-set” signal"><span class="type">“cursor-set”</span></a>
+<a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-move" title="The “cursor-move” signal"><span class="type">“cursor-move”</span></a> signals.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceCursorChannel.functions_details"></a><h2>Functions</h2>
+<p></p>
+</div>
+<div class="refsect1">
+<a name="SpiceCursorChannel.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceCursorChannel-struct"></a><h3>struct SpiceCursorChannel</h3>
+<pre class="programlisting">struct SpiceCursorChannel;</pre>
+<p>The <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel"><span class="type">SpiceCursorChannel</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceCursorChannelClass"></a><h3>struct SpiceCursorChannelClass</h3>
+<pre class="programlisting">struct SpiceCursorChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*cursor_set)(SpiceCursorChannel *channel, gint width, gint height,
+ gint hot_x, gint hot_y, gpointer rgba);
+ void (*cursor_move)(SpiceCursorChannel *channel, gint x, gint y);
+ void (*cursor_hide)(SpiceCursorChannel *channel);
+ void (*cursor_reset)(SpiceCursorChannel *channel);
+};
+</pre>
+<p>Class structure for <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel"><span class="type">SpiceCursorChannel</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceCursorChannelClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceCursorChannelClass.cursor-set"></a>cursor_set</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-set" title="The “cursor-set” signal"><span class="type">“cursor-set”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceCursorChannelClass.cursor-move"></a>cursor_move</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-move" title="The “cursor-move” signal"><span class="type">“cursor-move”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceCursorChannelClass.cursor-hide"></a>cursor_hide</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-hide" title="The “cursor-hide” signal"><span class="type">“cursor-hide”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceCursorChannelClass.cursor-reset"></a>cursor_reset</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-reset" title="The “cursor-reset” signal"><span class="type">“cursor-reset”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceCursorChannel.signal-details"></a><h2>Signal Details</h2>
+<div class="refsect2">
+<a name="SpiceCursorChannel-cursor-hide"></a><h3>The <code class="literal">“cursor-hide”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceCursorChannel.html" title="Cursor Channel"><span class="type">SpiceCursorChannel</span></a> *cursor,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-hide" title="The “cursor-hide” signal"><span class="type">“cursor-hide”</span></a> signal is emitted to hide
+the cursor/pointer on the display area.</p>
+<div class="refsect3">
+<a name="SpiceCursorChannel-cursor-hide.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>cursor</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel"><span class="type">SpiceCursorChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceCursorChannel-cursor-move"></a><h3>The <code class="literal">“cursor-move”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceCursorChannel.html" title="Cursor Channel"><span class="type">SpiceCursorChannel</span></a> *cursor,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> x,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> y,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-move" title="The “cursor-move” signal"><span class="type">“cursor-move”</span></a> signal is emitted to update
+the cursor position on the display area.</p>
+<div class="refsect3">
+<a name="SpiceCursorChannel-cursor-move.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>cursor</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel"><span class="type">SpiceCursorChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>x</p></td>
+<td class="parameter_description"><p>x position</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>y</p></td>
+<td class="parameter_description"><p>y position</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceCursorChannel-cursor-reset"></a><h3>The <code class="literal">“cursor-reset”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceCursorChannel.html" title="Cursor Channel"><span class="type">SpiceCursorChannel</span></a> *cursor,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-reset" title="The “cursor-reset” signal"><span class="type">“cursor-reset”</span></a> signal is emitted to
+reset the cursor to its default context.</p>
+<div class="refsect3">
+<a name="SpiceCursorChannel-cursor-reset.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>cursor</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel"><span class="type">SpiceCursorChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceCursorChannel-cursor-set"></a><h3>The <code class="literal">“cursor-set”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceCursorChannel.html" title="Cursor Channel"><span class="type">SpiceCursorChannel</span></a> *cursor,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> width,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> height,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> hot_x,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> hot_y,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> rgba,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-set" title="The “cursor-set” signal"><span class="type">“cursor-set”</span></a> signal is emitted to modify
+cursor aspect and position on the display area.</p>
+<div class="refsect3">
+<a name="SpiceCursorChannel-cursor-set.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>cursor</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel"><span class="type">SpiceCursorChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>width</p></td>
+<td class="parameter_description"><p>width of the shape</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>height</p></td>
+<td class="parameter_description"><p>height of the shape</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>hot_x</p></td>
+<td class="parameter_description"><p>horizontal offset of the 'hotspot' of the cursor</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>hot_y</p></td>
+<td class="parameter_description"><p>vertical offset of the 'hotspot' of the cursor</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>rgba</p></td>
+<td class="parameter_description"><p>32bits shape data, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if default cursor. It might
+be freed after the signal is emitted, so make sure to copy it
+if you need it later!</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceCursorChannel.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a>, and the GTK widget <span class="type">SpiceDisplay</span></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Display Channel: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="prev" href="SpiceCursorChannel.html" title="Cursor Channel">
+<link rel="next" href="SpiceInputsChannel.html" title="Inputs Channel">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceDisplayChannel.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceDisplayChannel.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_properties"> <span class="dim">|</span>
+ <a href="#SpiceDisplayChannel.properties" class="shortcut">Properties</a></span><span id="nav_signals"> <span class="dim">|</span>
+ <a href="#SpiceDisplayChannel.signals" class="shortcut">Signals</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceCursorChannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceInputsChannel.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceDisplayChannel"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceDisplayChannel.top_of_page"></a>Display Channel</span></h2>
+<p>Display Channel — remote display area</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceDisplayChannel.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceDisplayChannel.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">const <a class="link" href="SpiceDisplayChannel.html#SpiceGlScanout"><span class="returnvalue">SpiceGlScanout</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceDisplayChannel.html#spice-display-get-gl-scanout" title="spice_display_get_gl_scanout ()">spice_display_get_gl_scanout</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceDisplayChannel.html#spice-display-gl-draw-done" title="spice_display_gl_draw_done ()">spice_display_gl_draw_done</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceDisplayChannel.html#spice-display-get-primary" title="spice_display_get_primary ()">spice_display_get_primary</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceDisplayChannel.html#spice-display-change-preferred-compression" title="spice_display_change_preferred_compression ()">spice_display_change_preferred_compression</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceDisplayChannel.html#spice-gl-scanout-free" title="spice_gl_scanout_free ()">spice_gl_scanout_free</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceDisplayChannel.properties"></a><h2>Properties</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="properties_type">
+<col width="300px" class="properties_name">
+<col width="200px" class="properties_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="property_type">
+<a class="link" href="SpiceDisplayChannel.html#SpiceGlScanout"><span class="type">SpiceGlScanout</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel--gl-scanout" title="The “gl-scanout” property">gl-scanout</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel--height" title="The “height” property">height</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Arrays.html#GArray"><span class="type">GArray</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel--monitors" title="The “monitors” property">monitors</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel--monitors-max" title="The “monitors-max” property">monitors-max</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel--width" title="The “width” property">width</a></td>
+<td class="property_flags">Read</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceDisplayChannel.signals"></a><h2>Signals</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="signals_return">
+<col width="300px" class="signals_name">
+<col width="200px" class="signals_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-invalidate" title="The “display-invalidate” signal">display-invalidate</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-mark" title="The “display-mark” signal">display-mark</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-primary-create" title="The “display-primary-create” signal">display-primary-create</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-primary-destroy" title="The “display-primary-destroy” signal">display-primary-destroy</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-gl-draw" title="The “gl-draw” signal">gl-draw</a></td>
+<td class="signal_flags"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<a name="SpiceGlScanout"></a><div class="refsect1">
+<a name="SpiceDisplayChannel.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-struct" title="struct SpiceDisplayChannel">SpiceDisplayChannel</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannelClass" title="struct SpiceDisplayChannelClass">SpiceDisplayChannelClass</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayMonitorConfig" title="struct SpiceDisplayMonitorConfig">SpiceDisplayMonitorConfig</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayPrimary" title="struct SpiceDisplayPrimary">SpiceDisplayPrimary</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceDisplayChannel.html#SpiceGlScanout-struct" title="struct SpiceGlScanout">SpiceGlScanout</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceDisplayChannel.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="https://developer.gnome.org/gobject/unstable/gobject-Boxed-Types.html">GBoxed</a>
+ <span class="lineart">╰──</span> SpiceGlScanout
+ <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+ <span class="lineart">╰──</span> SpiceDisplayChannel
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceDisplayChannel.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceDisplayChannel.description"></a><h2>Description</h2>
+<p>A class that handles the rendering of the remote display and inform
+of its updates.</p>
+<p>The creation of the main graphic buffer is signaled with
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-primary-create" title="The “display-primary-create” signal"><span class="type">“display-primary-create”</span></a>.</p>
+<p>The update of regions is notified by
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-invalidate" title="The “display-invalidate” signal"><span class="type">“display-invalidate”</span></a> signals.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceDisplayChannel.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-display-get-gl-scanout"></a><h3>spice_display_get_gl_scanout ()</h3>
+<pre class="programlisting">const <a class="link" href="SpiceDisplayChannel.html#SpiceGlScanout"><span class="returnvalue">SpiceGlScanout</span></a> *
+spice_display_get_gl_scanout (<em class="parameter"><code><a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> *channel</code></em>);</pre>
+<p>Retrieves the GL scanout if available</p>
+<div class="refsect3">
+<a name="spice-display-get-gl-scanout.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-display-get-gl-scanout.returns"></a><h4>Returns</h4>
+<p> the current GL scanout, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if none or not valid</p>
+</div>
+<p class="since">Since: 0.31</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-display-gl-draw-done"></a><h3>spice_display_gl_draw_done ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_display_gl_draw_done (<em class="parameter"><code><a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> *channel</code></em>);</pre>
+<p>After a SpiceDisplayChannel::gl-draw is emitted, the client should
+draw the current display with the current GL scanout, and must
+release the GL resource with a call to <a class="link" href="SpiceDisplayChannel.html#spice-display-gl-draw-done" title="spice_display_gl_draw_done ()"><code class="function">spice_display_gl_draw_done()</code></a>
+(failing to do so for each gl-draw may result in a frozen display).</p>
+<div class="refsect3">
+<a name="spice-display-gl-draw-done.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.31</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-display-get-primary"></a><h3>spice_display_get_primary ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_display_get_primary (<em class="parameter"><code><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> surface_id</code></em>,
+ <em class="parameter"><code><a class="link" href="SpiceDisplayChannel.html#SpiceDisplayPrimary" title="struct SpiceDisplayPrimary"><span class="type">SpiceDisplayPrimary</span></a> *primary</code></em>);</pre>
+<p>Retrieve primary display surface <em class="parameter"><code>surface_id</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-display-get-primary.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>surface_id</p></td>
+<td class="parameter_description"><p>a surface id</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>primary</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceDisplayChannel.html#SpiceDisplayPrimary" title="struct SpiceDisplayPrimary"><span class="type">SpiceDisplayPrimary</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-display-get-primary.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if the primary surface was found and its details
+collected in <em class="parameter"><code>primary</code></em>
+.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-display-change-preferred-compression"></a><h3>spice_display_change_preferred_compression ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_display_change_preferred_compression
+ (<em class="parameter"><code><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> compression</code></em>);</pre>
+<p>Tells the spice server to change the preferred image compression
+for the <em class="parameter"><code>channel</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-display-change-preferred-compression.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>compression</p></td>
+<td class="parameter_description"><p>a <span class="type">SpiceImageCompression</span></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.31</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-gl-scanout-free"></a><h3>spice_gl_scanout_free ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_gl_scanout_free (<em class="parameter"><code><a class="link" href="SpiceDisplayChannel.html#SpiceGlScanout"><span class="type">SpiceGlScanout</span></a> *scanout</code></em>);</pre>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceDisplayChannel.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceDisplayChannel-struct"></a><h3>struct SpiceDisplayChannel</h3>
+<pre class="programlisting">struct SpiceDisplayChannel;</pre>
+<p>The <a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceDisplayChannelClass"></a><h3>struct SpiceDisplayChannelClass</h3>
+<pre class="programlisting">struct SpiceDisplayChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*display_primary_create)(SpiceChannel *channel, gint format,
+ gint width, gint height, gint stride,
+ gint shmid, gpointer data);
+ void (*display_primary_destroy)(SpiceChannel *channel);
+ void (*display_invalidate)(SpiceChannel *channel,
+ gint x, gint y, gint w, gint h);
+ void (*display_mark)(SpiceChannel *channel,
+ gboolean mark);
+};
+</pre>
+<p>Class structure for <a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceDisplayChannelClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceDisplayChannelClass.display-primary-create"></a>display_primary_create</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-primary-create" title="The “display-primary-create” signal"><span class="type">“display-primary-create”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceDisplayChannelClass.display-primary-destroy"></a>display_primary_destroy</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-primary-destroy" title="The “display-primary-destroy” signal"><span class="type">“display-primary-destroy”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceDisplayChannelClass.display-invalidate"></a>display_invalidate</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-invalidate" title="The “display-invalidate” signal"><span class="type">“display-invalidate”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceDisplayChannelClass.display-mark"></a>display_mark</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-mark" title="The “display-mark” signal"><span class="type">“display-mark”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceDisplayMonitorConfig"></a><h3>struct SpiceDisplayMonitorConfig</h3>
+<pre class="programlisting">struct SpiceDisplayMonitorConfig {
+ guint id;
+ guint surface_id;
+ guint x;
+ guint y;
+ guint width;
+ guint height;
+};
+</pre>
+<p>Holds a monitor configuration.</p>
+<div class="refsect3">
+<a name="SpiceDisplayMonitorConfig.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="SpiceDisplayMonitorConfig.id"></a>id</code></em>;</p></td>
+<td class="struct_member_description"><p>monitor id</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="SpiceDisplayMonitorConfig.surface-id"></a>surface_id</code></em>;</p></td>
+<td class="struct_member_description"><p>monitor surface id</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="SpiceDisplayMonitorConfig.x"></a>x</code></em>;</p></td>
+<td class="struct_member_description"><p>x position of the monitor</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="SpiceDisplayMonitorConfig.y"></a>y</code></em>;</p></td>
+<td class="struct_member_description"><p>y position of the monitor</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="SpiceDisplayMonitorConfig.width"></a>width</code></em>;</p></td>
+<td class="struct_member_description"><p>width of the monitor</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> <em class="structfield"><code><a name="SpiceDisplayMonitorConfig.height"></a>height</code></em>;</p></td>
+<td class="struct_member_description"><p>height of the monitor</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceDisplayPrimary"></a><h3>struct SpiceDisplayPrimary</h3>
+<pre class="programlisting">struct SpiceDisplayPrimary {
+ enum SpiceSurfaceFmt format;
+ gint width;
+ gint height;
+ gint stride;
+ gint shmid;
+ guint8 *data;
+ gboolean marked;
+};
+</pre>
+<p>Holds the information necessary to use the primary surface.</p>
+<div class="refsect3">
+<a name="SpiceDisplayPrimary.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p>enum <span class="type">SpiceSurfaceFmt</span> <em class="structfield"><code><a name="SpiceDisplayPrimary.format"></a>format</code></em>;</p></td>
+<td class="struct_member_description"><p>primary buffer format</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> <em class="structfield"><code><a name="SpiceDisplayPrimary.width"></a>width</code></em>;</p></td>
+<td class="struct_member_description"><p>width of the primary</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> <em class="structfield"><code><a name="SpiceDisplayPrimary.height"></a>height</code></em>;</p></td>
+<td class="struct_member_description"><p>height of the primary</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> <em class="structfield"><code><a name="SpiceDisplayPrimary.stride"></a>stride</code></em>;</p></td>
+<td class="struct_member_description"><p>stride of the primary</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> <em class="structfield"><code><a name="SpiceDisplayPrimary.shmid"></a>shmid</code></em>;</p></td>
+<td class="struct_member_description"><p>identifier of the shared memory segment associated with
+the <em class="parameter"><code>data</code></em>
+, or -1 if not shm</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint8"><span class="type">guint8</span></a> *<em class="structfield"><code><a name="SpiceDisplayPrimary.data"></a>data</code></em>;</p></td>
+<td class="struct_member_description"><p>pointer to primary buffer</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a> <em class="structfield"><code><a name="SpiceDisplayPrimary.marked"></a>marked</code></em>;</p></td>
+<td class="struct_member_description"><p>whether the display is marked ready</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceGlScanout-struct"></a><h3>struct SpiceGlScanout</h3>
+<pre class="programlisting">struct SpiceGlScanout {
+ gint fd;
+ guint32 width;
+ guint32 height;
+ guint32 stride;
+ guint32 format;
+ gboolean y0top;
+};
+</pre>
+<p>Holds the information necessary for using the GL display scanout.</p>
+<div class="refsect3">
+<a name="SpiceGlScanout.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> <em class="structfield"><code><a name="SpiceGlScanout-struct.fd"></a>fd</code></em>;</p></td>
+<td class="struct_member_description"><p>a drm DMABUF file that can be imported with eglCreateImageKHR</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> <em class="structfield"><code><a name="SpiceGlScanout-struct.width"></a>width</code></em>;</p></td>
+<td class="struct_member_description"><p>width of the scanout</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> <em class="structfield"><code><a name="SpiceGlScanout-struct.height"></a>height</code></em>;</p></td>
+<td class="struct_member_description"><p>height of the scanout</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> <em class="structfield"><code><a name="SpiceGlScanout-struct.stride"></a>stride</code></em>;</p></td>
+<td class="struct_member_description"><p>stride of the scanout</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> <em class="structfield"><code><a name="SpiceGlScanout-struct.format"></a>format</code></em>;</p></td>
+<td class="struct_member_description"><p>the drm fourcc format</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a> <em class="structfield"><code><a name="SpiceGlScanout-struct.y0top"></a>y0top</code></em>;</p></td>
+<td class="struct_member_description"><p>orientation of the scanout</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceDisplayChannel.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="SpiceDisplayChannel--gl-scanout"></a><h3>The <code class="literal">“gl-scanout”</code> property</h3>
+<pre class="programlisting"> “gl-scanout” <a class="link" href="SpiceDisplayChannel.html#SpiceGlScanout"><span class="type">SpiceGlScanout</span></a> *</pre>
+<p>The last <a class="link" href="SpiceDisplayChannel.html#SpiceGlScanout"><span class="type">SpiceGlScanout</span></a> received.</p>
+<p>Flags: Read</p>
+<p class="since">Since: 0.31</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceDisplayChannel--height"></a><h3>The <code class="literal">“height”</code> property</h3>
+<pre class="programlisting"> “height” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>The primary surface height.</p>
+<p>Flags: Read</p>
+<p>Default value: 0</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceDisplayChannel--monitors"></a><h3>The <code class="literal">“monitors”</code> property</h3>
+<pre class="programlisting"> “monitors” <a href="/usr/share/gtk-doc/html/glibglib-Arrays.html#GArray"><span class="type">GArray</span></a> *</pre>
+<p>Current monitors configuration.</p>
+<p>Flags: Read</p>
+<p class="since">Since: 0.13</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceDisplayChannel--monitors-max"></a><h3>The <code class="literal">“monitors-max”</code> property</h3>
+<pre class="programlisting"> “monitors-max” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>The maximum number of monitors the server or guest supports.
+May change during client lifetime, for instance guest may
+reboot or dynamically adjust this.</p>
+<p>Flags: Read</p>
+<p>Allowed values: [1,256]</p>
+<p>Default value: 1</p>
+<p class="since">Since: 0.13</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceDisplayChannel--width"></a><h3>The <code class="literal">“width”</code> property</h3>
+<pre class="programlisting"> “width” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>The primary surface width.</p>
+<p>Flags: Read</p>
+<p>Default value: 0</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceDisplayChannel.signal-details"></a><h2>Signal Details</h2>
+<div class="refsect2">
+<a name="SpiceDisplayChannel-display-invalidate"></a><h3>The <code class="literal">“display-invalidate”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> *display,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> x,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> y,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> width,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> height,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-invalidate" title="The “display-invalidate” signal"><span class="type">“display-invalidate”</span></a> signal is emitted
+when the rectangular region x/y/w/h of the primary buffer is
+updated.</p>
+<div class="refsect3">
+<a name="SpiceDisplayChannel-display-invalidate.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>display</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>x</p></td>
+<td class="parameter_description"><p>x position</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>y</p></td>
+<td class="parameter_description"><p>y position</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>width</p></td>
+<td class="parameter_description"><p>width</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>height</p></td>
+<td class="parameter_description"><p>height</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceDisplayChannel-display-mark"></a><h3>The <code class="literal">“display-mark”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> *display,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> mark,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-mark" title="The “display-mark” signal"><span class="type">“display-mark”</span></a> signal is emitted when
+the <code class="literal">RED_DISPLAY_MARK</code> command is received, and the display
+should be exposed.</p>
+<div class="refsect3">
+<a name="SpiceDisplayChannel-display-mark.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>display</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>mark</p></td>
+<td class="parameter_description"><p><a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> when the display mark has been received</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceDisplayChannel-display-primary-create"></a><h3>The <code class="literal">“display-primary-create”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> *display,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> format,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> width,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> height,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> stride,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> shmid,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> imgdata,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-primary-create" title="The “display-primary-create” signal"><span class="type">“display-primary-create”</span></a> signal
+provides main display buffer data.</p>
+<div class="refsect3">
+<a name="SpiceDisplayChannel-display-primary-create.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>display</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>format</p></td>
+<td class="parameter_description"><p><code class="literal">SPICE_SURFACE_FMT_32_xRGB</code> or <code class="literal">SPICE_SURFACE_FMT_16_555</code>;</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>width</p></td>
+<td class="parameter_description"><p>width resolution</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>height</p></td>
+<td class="parameter_description"><p>height resolution</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>stride</p></td>
+<td class="parameter_description"><p>the buffer stride ("width" padding)</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>shmid</p></td>
+<td class="parameter_description"><p>identifier of the shared memory segment associated with
+the <em class="parameter"><code>imgdata</code></em>
+, or -1 if not shm</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>imgdata</p></td>
+<td class="parameter_description"><p>pointer to surface buffer</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceDisplayChannel-display-primary-destroy"></a><h3>The <code class="literal">“display-primary-destroy”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> *display,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-primary-destroy" title="The “display-primary-destroy” signal"><span class="type">“display-primary-destroy”</span></a> signal is
+emitted when the primary surface is freed and should not be
+accessed anymore.</p>
+<div class="refsect3">
+<a name="SpiceDisplayChannel-display-primary-destroy.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>display</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceDisplayChannel-gl-draw"></a><h3>The <code class="literal">“gl-draw”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> *display,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> x,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> y,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> width,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> height,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <span class="type">“draw”</span> signal is emitted when the
+rectangular region x/y/w/h of the GL scanout is updated and
+must be drawn. When the draw is finished, you must call
+<a class="link" href="SpiceDisplayChannel.html#spice-display-gl-draw-done" title="spice_display_gl_draw_done ()"><code class="function">spice_display_gl_draw_done()</code></a> in order to release the GL
+resources.</p>
+<div class="refsect3">
+<a name="SpiceDisplayChannel-gl-draw.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>display</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceDisplayChannel.html" title="Display Channel"><span class="type">SpiceDisplayChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>x</p></td>
+<td class="parameter_description"><p>x position</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>y</p></td>
+<td class="parameter_description"><p>y position</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>width</p></td>
+<td class="parameter_description"><p>width</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>height</p></td>
+<td class="parameter_description"><p>height</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.31</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceDisplayChannel.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a>, and the GTK widget <span class="type">SpiceDisplay</span></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>File Transfer Task: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="application-support.html" title="Application Support, from spice-client-glib">
+<link rel="prev" href="spice-gtk-SpiceURI.html" title="SpiceURI">
+<link rel="next" href="object-tree.html" title="Object Hierarchy">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceFileTransferTask.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceFileTransferTask.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_properties"> <span class="dim">|</span>
+ <a href="#SpiceFileTransferTask.properties" class="shortcut">Properties</a></span><span id="nav_signals"> <span class="dim">|</span>
+ <a href="#SpiceFileTransferTask.signals" class="shortcut">Signals</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="application-support.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="spice-gtk-SpiceURI.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="object-tree.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceFileTransferTask"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceFileTransferTask.top_of_page"></a>File Transfer Task</span></h2>
+<p>File Transfer Task — Monitoring file transfers</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceFileTransferTask.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceFileTransferTask.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<span class="returnvalue">double</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceFileTransferTask.html#spice-file-transfer-task-get-progress" title="spice_file_transfer_task_get_progress ()">spice_file_transfer_task_get_progress</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">char</span> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceFileTransferTask.html#spice-file-transfer-task-get-filename" title="spice_file_transfer_task_get_filename ()">spice_file_transfer_task_get_filename</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="returnvalue">guint64</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceFileTransferTask.html#spice-file-transfer-task-get-total-bytes" title="spice_file_transfer_task_get_total_bytes ()">spice_file_transfer_task_get_total_bytes</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="returnvalue">guint64</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceFileTransferTask.html#spice-file-transfer-task-get-transferred-bytes" title="spice_file_transfer_task_get_transferred_bytes ()">spice_file_transfer_task_get_transferred_bytes</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceFileTransferTask.html#spice-file-transfer-task-cancel" title="spice_file_transfer_task_cancel ()">spice_file_transfer_task_cancel</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceFileTransferTask.properties"></a><h2>Properties</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="properties_type">
+<col width="300px" class="properties_name">
+<col width="200px" class="properties_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/gioGCancellable.html#GCancellable-struct"><span class="type">GCancellable</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--cancellable" title="The “cancellable” property">cancellable</a></td>
+<td class="property_flags">Read / Write / Construct Only</td>
+</tr>
+<tr>
+<td class="property_type">
+<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--channel" title="The “channel” property">channel</a></td>
+<td class="property_flags">Read / Write / Construct Only</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/gioGFile.html#GFile-struct"><span class="type">GFile</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--file" title="The “file” property">file</a></td>
+<td class="property_flags">Read / Write / Construct Only</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--id" title="The “id” property">id</a></td>
+<td class="property_flags">Read / Write / Construct Only</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gdouble"><span class="type">gdouble</span></a></td>
+<td class="property_name"><a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--progress" title="The “progress” property">progress</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="type">guint64</span></a></td>
+<td class="property_name"><a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--total-bytes" title="The “total-bytes” property">total-bytes</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="type">guint64</span></a></td>
+<td class="property_name"><a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--transferred-bytes" title="The “transferred-bytes” property">transferred-bytes</a></td>
+<td class="property_flags">Read</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceFileTransferTask.signals"></a><h2>Signals</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="signals_return">
+<col width="300px" class="signals_name">
+<col width="200px" class="signals_flags">
+</colgroup>
+<tbody><tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask-finished" title="The “finished” signal">finished</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceFileTransferTask.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> SpiceFileTransferTask
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceFileTransferTask.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceFileTransferTask.description"></a><h2>Description</h2>
+<p>SpiceFileTransferTask is an object that represents a particular file
+transfer between the client and the guest. The properties and signals of the
+object can be used to monitor the status and result of the transfer. The
+Main Channel's <a class="link" href="SpiceMainChannel.html#SpiceMainChannel-new-file-transfer" title="The “new-file-transfer” signal"><span class="type">“new-file-transfer”</span></a> signal will be emitted
+whenever a new file transfer task is initiated.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceFileTransferTask.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-file-transfer-task-get-progress"></a><h3>spice_file_transfer_task_get_progress ()</h3>
+<pre class="programlisting"><span class="returnvalue">double</span>
+spice_file_transfer_task_get_progress (<em class="parameter"><code><a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task"><span class="type">SpiceFileTransferTask</span></a> *self</code></em>);</pre>
+<p>Convenience function for retrieving the current progress of this file
+transfer task.</p>
+<div class="refsect3">
+<a name="spice-file-transfer-task-get-progress.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p>a file transfer task</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-file-transfer-task-get-progress.returns"></a><h4>Returns</h4>
+<p> A fractional value between 0 and 1.0</p>
+</div>
+<p class="since">Since: 0.31</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-file-transfer-task-get-filename"></a><h3>spice_file_transfer_task_get_filename ()</h3>
+<pre class="programlisting"><span class="returnvalue">char</span> *
+spice_file_transfer_task_get_filename (<em class="parameter"><code><a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task"><span class="type">SpiceFileTransferTask</span></a> *self</code></em>);</pre>
+<p>Gets the name of the file being transferred in this task</p>
+<div class="refsect3">
+<a name="spice-file-transfer-task-get-filename.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p>a file transfer task</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-file-transfer-task-get-filename.returns"></a><h4>Returns</h4>
+<p> The basename of the file. </p>
+<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
+</div>
+<p class="since">Since: 0.31</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-file-transfer-task-get-total-bytes"></a><h3>spice_file_transfer_task_get_total_bytes ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="returnvalue">guint64</span></a>
+spice_file_transfer_task_get_total_bytes
+ (<em class="parameter"><code><a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task"><span class="type">SpiceFileTransferTask</span></a> *self</code></em>);</pre>
+<p>Gets the total size in bytes of the file transfer.</p>
+<div class="refsect3">
+<a name="spice-file-transfer-task-get-total-bytes.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p>a file transfer task</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-file-transfer-task-get-total-bytes.returns"></a><h4>Returns</h4>
+<p> The total size of the file transfer</p>
+</div>
+<p class="since">Since: 0.33</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-file-transfer-task-get-transferred-bytes"></a><h3>spice_file_transfer_task_get_transferred_bytes ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="returnvalue">guint64</span></a>
+spice_file_transfer_task_get_transferred_bytes
+ (<em class="parameter"><code><a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task"><span class="type">SpiceFileTransferTask</span></a> *self</code></em>);</pre>
+<p>Gets the number of bytes that have been transferred so far.</p>
+<div class="refsect3">
+<a name="spice-file-transfer-task-get-transferred-bytes.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p>a file transfer task</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-file-transfer-task-get-transferred-bytes.returns"></a><h4>Returns</h4>
+<p> The number of transferred bytes</p>
+</div>
+<p class="since">Since: 0.33</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-file-transfer-task-cancel"></a><h3>spice_file_transfer_task_cancel ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_file_transfer_task_cancel (<em class="parameter"><code><a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task"><span class="type">SpiceFileTransferTask</span></a> *self</code></em>);</pre>
+<p>Cancels the file transfer task. Note that depending on how the file transfer
+was initiated, multiple file transfer tasks may share a single
+<span class="type">“cancellable”</span> object, so canceling one task may result
+in the cancellation of other tasks.</p>
+<div class="refsect3">
+<a name="spice-file-transfer-task-cancel.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p>a file transfer task</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.31</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceFileTransferTask.other_details"></a><h2>Types and Values</h2>
+</div>
+<div class="refsect1">
+<a name="SpiceFileTransferTask.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="SpiceFileTransferTask--cancellable"></a><h3>The <code class="literal">“cancellable”</code> property</h3>
+<pre class="programlisting"> “cancellable” <a href="/usr/share/gtk-doc/html/gioGCancellable.html#GCancellable-struct"><span class="type">GCancellable</span></a> *</pre>
+<p>A cancellable object used to cancel the file transfer</p>
+<p>Flags: Read / Write / Construct Only</p>
+<p class="since">Since: 0.31</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceFileTransferTask--channel"></a><h3>The <code class="literal">“channel”</code> property</h3>
+<pre class="programlisting"> “channel” <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *</pre>
+<p>The main channel that owns the file transfer task</p>
+<p>Flags: Read / Write / Construct Only</p>
+<p class="since">Since: 0.31</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceFileTransferTask--file"></a><h3>The <code class="literal">“file”</code> property</h3>
+<pre class="programlisting"> “file” <a href="/usr/share/gtk-doc/html/gioGFile.html#GFile-struct"><span class="type">GFile</span></a> *</pre>
+<p>The file that is being transferred in this file transfer task</p>
+<p>Flags: Read / Write / Construct Only</p>
+<p class="since">Since: 0.31</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceFileTransferTask--id"></a><h3>The <code class="literal">“id”</code> property</h3>
+<pre class="programlisting"> “id” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>The ID of the file transfer task</p>
+<p>Flags: Read / Write / Construct Only</p>
+<p>Default value: 0</p>
+<p class="since">Since: 0.31</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceFileTransferTask--progress"></a><h3>The <code class="literal">“progress”</code> property</h3>
+<pre class="programlisting"> “progress” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gdouble"><span class="type">gdouble</span></a></pre>
+<p>The current state of the file transfer. This value indicates a
+fraction, and ranges from 0 to 1.0. Listen for change notifications on
+this property to be updated whenever the file transfer progress changes.</p>
+<p>Flags: Read</p>
+<p>Allowed values: [0,1]</p>
+<p>Default value: 0</p>
+<p class="since">Since: 0.31</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceFileTransferTask--total-bytes"></a><h3>The <code class="literal">“total-bytes”</code> property</h3>
+<pre class="programlisting"> “total-bytes” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="type">guint64</span></a></pre>
+<p>The total size in bytes of this file transfer.</p>
+<p>Flags: Read</p>
+<p>Default value: 0</p>
+<p class="since">Since: 0.33</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceFileTransferTask--transferred-bytes"></a><h3>The <code class="literal">“transferred-bytes”</code> property</h3>
+<pre class="programlisting"> “transferred-bytes” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint64"><span class="type">guint64</span></a></pre>
+<p>The number of bytes that have been transferred so far.</p>
+<p>Flags: Read</p>
+<p>Default value: 0</p>
+<p class="since">Since: 0.33</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceFileTransferTask.signal-details"></a><h2>Signal Details</h2>
+<div class="refsect2">
+<a name="SpiceFileTransferTask-finished"></a><h3>The <code class="literal">“finished”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task"><span class="type">SpiceFileTransferTask</span></a> *task,
+ <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> *error,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask-finished" title="The “finished” signal"><span class="type">“finished”</span></a> signal is emitted when the file
+transfer has completed transferring to the guest.</p>
+<div class="refsect3">
+<a name="SpiceFileTransferTask-finished.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>task</p></td>
+<td class="parameter_description"><p>the file transfer task that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>error</p></td>
+<td class="parameter_description"><p> the error state of the transfer. Will be <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>
+if the file transfer was successful. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+<p class="since">Since: 0.31</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceFileTransferTask.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Inputs Channel: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="prev" href="SpiceDisplayChannel.html" title="Display Channel">
+<link rel="next" href="SpiceMainChannel.html" title="Main Channel">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceInputsChannel.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceInputsChannel.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_properties"> <span class="dim">|</span>
+ <a href="#SpiceInputsChannel.properties" class="shortcut">Properties</a></span><span id="nav_signals"> <span class="dim">|</span>
+ <a href="#SpiceInputsChannel.signals" class="shortcut">Signals</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceDisplayChannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceMainChannel.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceInputsChannel"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceInputsChannel.top_of_page"></a>Inputs Channel</span></h2>
+<p>Inputs Channel — control the server mouse and keyboard</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-motion" title="spice_inputs_motion ()">spice_inputs_motion</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-position" title="spice_inputs_position ()">spice_inputs_position</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-button-press" title="spice_inputs_button_press ()">spice_inputs_button_press</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-button-release" title="spice_inputs_button_release ()">spice_inputs_button_release</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-key-press" title="spice_inputs_key_press ()">spice_inputs_key_press</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-key-press-and-release" title="spice_inputs_key_press_and_release ()">spice_inputs_key_press_and_release</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-key-release" title="spice_inputs_key_release ()">spice_inputs_key_release</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-set-key-locks" title="spice_inputs_set_key_locks ()">spice_inputs_set_key_locks</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.properties"></a><h2>Properties</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="properties_type">
+<col width="300px" class="properties_name">
+<col width="200px" class="properties_flags">
+</colgroup>
+<tbody><tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceInputsChannel.html#SpiceInputsChannel--key-modifiers" title="The “key-modifiers” property">key-modifiers</a></td>
+<td class="property_flags">Read</td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.signals"></a><h2>Signals</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="signals_return">
+<col width="300px" class="signals_name">
+<col width="200px" class="signals_flags">
+</colgroup>
+<tbody><tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceInputsChannel.html#SpiceInputsChannel-inputs-modifiers" title="The “inputs-modifiers” signal">inputs-modifiers</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceInputsChannel.html#SpiceInputsChannel-struct" title="struct SpiceInputsChannel">SpiceInputsChannel</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceInputsChannel.html#SpiceInputsChannelClass" title="struct SpiceInputsChannelClass">SpiceInputsChannelClass</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="SpiceInputsChannel.html#SpiceInputsLock" title="enum SpiceInputsLock">SpiceInputsLock</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="https://developer.gnome.org/gobject/unstable/gobject-Enumeration-and-Flag-Types.html">GFlags</a>
+ <span class="lineart">╰──</span> SpiceInputsLock
+ <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+ <span class="lineart">╰──</span> SpiceInputsChannel
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.description"></a><h2>Description</h2>
+<p>Spice supports sending keyboard key events and keyboard leds
+synchronization. The key events are sent using
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-key-press" title="spice_inputs_key_press ()"><code class="function">spice_inputs_key_press()</code></a> and <a class="link" href="SpiceInputsChannel.html#spice-inputs-key-release" title="spice_inputs_key_release ()"><code class="function">spice_inputs_key_release()</code></a> using
+a modified variant of PC XT scancodes.</p>
+<p>Guest keyboard leds state can be manipulated with
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-set-key-locks" title="spice_inputs_set_key_locks ()"><code class="function">spice_inputs_set_key_locks()</code></a>. When key lock change, a notification
+is emitted with <a class="link" href="SpiceInputsChannel.html#SpiceInputsChannel-inputs-modifiers" title="The “inputs-modifiers” signal"><span class="type">“inputs-modifiers”</span></a> signal.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-inputs-motion"></a><h3>spice_inputs_motion ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_inputs_motion (<em class="parameter"><code><a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> dx</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> dy</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> button_state</code></em>);</pre>
+<p>Change mouse position (used in SPICE_MOUSE_MODE_CLIENT).</p>
+<div class="refsect3">
+<a name="spice-inputs-motion.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>dx</p></td>
+<td class="parameter_description"><p>delta X mouse coordinates</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>dy</p></td>
+<td class="parameter_description"><p>delta Y mouse coordinates</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>button_state</p></td>
+<td class="parameter_description"><p>SPICE_MOUSE_BUTTON_MASK flags</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-inputs-position"></a><h3>spice_inputs_position ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_inputs_position (<em class="parameter"><code><a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> x</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> y</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> display</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> button_state</code></em>);</pre>
+<p>Change mouse position (used in SPICE_MOUSE_MODE_CLIENT).</p>
+<div class="refsect3">
+<a name="spice-inputs-position.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>x</p></td>
+<td class="parameter_description"><p>X mouse coordinates</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>y</p></td>
+<td class="parameter_description"><p>Y mouse coordinates</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>display</p></td>
+<td class="parameter_description"><p>display channel id</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>button_state</p></td>
+<td class="parameter_description"><p>SPICE_MOUSE_BUTTON_MASK flags</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-inputs-button-press"></a><h3>spice_inputs_button_press ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_inputs_button_press (<em class="parameter"><code><a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> button</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> button_state</code></em>);</pre>
+<p>Press a mouse button.</p>
+<div class="refsect3">
+<a name="spice-inputs-button-press.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>button</p></td>
+<td class="parameter_description"><p>a SPICE_MOUSE_BUTTON</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>button_state</p></td>
+<td class="parameter_description"><p>SPICE_MOUSE_BUTTON_MASK flags</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-inputs-button-release"></a><h3>spice_inputs_button_release ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_inputs_button_release (<em class="parameter"><code><a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> button</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> button_state</code></em>);</pre>
+<p>Release a button.</p>
+<div class="refsect3">
+<a name="spice-inputs-button-release.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>button</p></td>
+<td class="parameter_description"><p>a SPICE_MOUSE_BUTTON</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>button_state</p></td>
+<td class="parameter_description"><p>SPICE_MOUSE_BUTTON_MASK flags</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-inputs-key-press"></a><h3>spice_inputs_key_press ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_inputs_key_press (<em class="parameter"><code><a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> scancode</code></em>);</pre>
+<p>Press a key.</p>
+<div class="refsect3">
+<a name="spice-inputs-key-press.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>scancode</p></td>
+<td class="parameter_description"><p>a PC XT (set 1) key scancode. For scancodes with an <code class="literal">0xe0</code>
+prefix, drop the prefix and OR the scancode with <code class="literal">0x100</code>.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-inputs-key-press-and-release"></a><h3>spice_inputs_key_press_and_release ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_inputs_key_press_and_release (<em class="parameter"><code><a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> scancode</code></em>);</pre>
+<p>Press and release a key event atomically (in the same message).</p>
+<div class="refsect3">
+<a name="spice-inputs-key-press-and-release.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>scancode</p></td>
+<td class="parameter_description"><p>a PC XT (set 1) key scancode. For scancodes with an <code class="literal">0xe0</code>
+prefix, drop the prefix and OR the scancode with <code class="literal">0x100</code>.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.13</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-inputs-key-release"></a><h3>spice_inputs_key_release ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_inputs_key_release (<em class="parameter"><code><a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> scancode</code></em>);</pre>
+<p>Release a key.</p>
+<div class="refsect3">
+<a name="spice-inputs-key-release.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>scancode</p></td>
+<td class="parameter_description"><p>a PC XT (set 1) key scancode. For scancodes with an <code class="literal">0xe0</code>
+prefix, drop the prefix and OR the scancode with <code class="literal">0x100</code>.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-inputs-set-key-locks"></a><h3>spice_inputs_set_key_locks ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_inputs_set_key_locks (<em class="parameter"><code><a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> locks</code></em>);</pre>
+<p>Set the keyboard locks on the guest (Caps, Num, Scroll..)</p>
+<div class="refsect3">
+<a name="spice-inputs-set-key-locks.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>locks</p></td>
+<td class="parameter_description"><p><a class="link" href="SpiceInputsChannel.html#SpiceInputsLock" title="enum SpiceInputsLock"><span class="type">SpiceInputsLock</span></a> modifiers flags</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceInputsChannel-struct"></a><h3>struct SpiceInputsChannel</h3>
+<pre class="programlisting">struct SpiceInputsChannel;</pre>
+<p>The <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceInputsChannelClass"></a><h3>struct SpiceInputsChannelClass</h3>
+<pre class="programlisting">struct SpiceInputsChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*inputs_modifiers)(SpiceChannel *channel);
+};
+</pre>
+<p>Class structure for <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceInputsChannelClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody><tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceInputsChannelClass.inputs-modifiers"></a>inputs_modifiers</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceInputsChannel.html#SpiceInputsChannel-inputs-modifiers" title="The “inputs-modifiers” signal"><span class="type">“inputs-modifiers”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceInputsLock"></a><h3>enum SpiceInputsLock</h3>
+<p>Constants used to synchronize modifiers between a client and a guest.</p>
+<div class="refsect3">
+<a name="SpiceInputsLock.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-INPUTS-SCROLL-LOCK:CAPS"></a>SPICE_INPUTS_SCROLL_LOCK</p></td>
+<td class="enum_member_description">
+<p>Scroll Lock</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-INPUTS-NUM-LOCK:CAPS"></a>SPICE_INPUTS_NUM_LOCK</p></td>
+<td class="enum_member_description">
+<p>Num Lock</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-INPUTS-CAPS-LOCK:CAPS"></a>SPICE_INPUTS_CAPS_LOCK</p></td>
+<td class="enum_member_description">
+<p>Caps Lock</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="SpiceInputsChannel--key-modifiers"></a><h3>The <code class="literal">“key-modifiers”</code> property</h3>
+<pre class="programlisting"> “key-modifiers” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>Guest keyboard lock/led state.</p>
+<p>Flags: Read</p>
+<p>Allowed values: >= 0</p>
+<p>Default value: 0</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.signal-details"></a><h2>Signal Details</h2>
+<div class="refsect2">
+<a name="SpiceInputsChannel-inputs-modifiers"></a><h3>The <code class="literal">“inputs-modifiers”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a> *display,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceInputsChannel.html#SpiceInputsChannel-inputs-modifiers" title="The “inputs-modifiers” signal"><span class="type">“inputs-modifiers”</span></a> signal is emitted when
+the guest keyboard locks are changed. You can read the current
+state from <a class="link" href="SpiceInputsChannel.html#SpiceInputsChannel--key-modifiers" title="The “key-modifiers” property"><span class="type">“key-modifiers”</span></a> property.</p>
+<div class="refsect3">
+<a name="SpiceInputsChannel-inputs-modifiers.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>display</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceInputsChannel.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a>, and the GTK widget <span class="type">SpiceDisplay</span></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Main Channel: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="prev" href="SpiceInputsChannel.html" title="Inputs Channel">
+<link rel="next" href="SpicePlaybackChannel.html" title="Playback Channel">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceMainChannel.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceMainChannel.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_properties"> <span class="dim">|</span>
+ <a href="#SpiceMainChannel.properties" class="shortcut">Properties</a></span><span id="nav_signals"> <span class="dim">|</span>
+ <a href="#SpiceMainChannel.signals" class="shortcut">Signals</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceInputsChannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpicePlaybackChannel.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceMainChannel"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceMainChannel.top_of_page"></a>Main Channel</span></h2>
+<p>Main Channel — the main Spice channel</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceMainChannel.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceMainChannel.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-set-display" title="spice_main_set_display ()">spice_main_set_display</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-set-display-enabled" title="spice_main_set_display_enabled ()">spice_main_set_display_enabled</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-update-display" title="spice_main_update_display ()">spice_main_update_display</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-update-display-enabled" title="spice_main_update_display_enabled ()">spice_main_update_display_enabled</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-send-monitor-config" title="spice_main_send_monitor_config ()">spice_main_send_monitor_config</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-agent-test-capability" title="spice_main_agent_test_capability ()">spice_main_agent_test_capability</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-request-mouse-mode" title="spice_main_request_mouse_mode ()">spice_main_request_mouse_mode</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-selection-grab" title="spice_main_clipboard_selection_grab ()">spice_main_clipboard_selection_grab</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-selection-notify" title="spice_main_clipboard_selection_notify ()">spice_main_clipboard_selection_notify</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-selection-release" title="spice_main_clipboard_selection_release ()">spice_main_clipboard_selection_release</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-selection-request" title="spice_main_clipboard_selection_request ()">spice_main_clipboard_selection_request</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-grab" title="spice_main_clipboard_grab ()">spice_main_clipboard_grab</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-release" title="spice_main_clipboard_release ()">spice_main_clipboard_release</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-notify" title="spice_main_clipboard_notify ()">spice_main_clipboard_notify</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-request" title="spice_main_clipboard_request ()">spice_main_clipboard_request</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-file-copy-async" title="spice_main_file_copy_async ()">spice_main_file_copy_async</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceMainChannel.html#spice-main-file-copy-finish" title="spice_main_file_copy_finish ()">spice_main_file_copy_finish</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceMainChannel.properties"></a><h2>Properties</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="properties_type">
+<col width="300px" class="properties_name">
+<col width="200px" class="properties_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel--agent-caps-0" title="The “agent-caps-0” property">agent-caps-0</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel--agent-connected" title="The “agent-connected” property">agent-connected</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel--color-depth" title="The “color-depth” property">color-depth</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel--disable-animation" title="The “disable-animation” property">disable-animation</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel--disable-display-align" title="The “disable-display-align” property">disable-display-align</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel--disable-display-position" title="The “disable-display-position” property">disable-display-position</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel--disable-font-smooth" title="The “disable-font-smooth” property">disable-font-smooth</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel--disable-wallpaper" title="The “disable-wallpaper” property">disable-wallpaper</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel--max-clipboard" title="The “max-clipboard” property">max-clipboard</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel--mouse-mode" title="The “mouse-mode” property">mouse-mode</a></td>
+<td class="property_flags">Read</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceMainChannel.signals"></a><h2>Signals</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="signals_return">
+<col width="300px" class="signals_name">
+<col width="200px" class="signals_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-agent-update" title="The “main-agent-update” signal">main-agent-update</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard" title="The “main-clipboard” signal">main-clipboard</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+<tr>
+<td class="signal_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a></td>
+<td class="signal_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-grab" title="The “main-clipboard-grab” signal">main-clipboard-grab</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-release" title="The “main-clipboard-release” signal">main-clipboard-release</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+<tr>
+<td class="signal_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a></td>
+<td class="signal_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-request" title="The “main-clipboard-request” signal">main-clipboard-request</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection" title="The “main-clipboard-selection” signal">main-clipboard-selection</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+<tr>
+<td class="signal_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a></td>
+<td class="signal_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection-grab" title="The “main-clipboard-selection-grab” signal">main-clipboard-selection-grab</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection-release" title="The “main-clipboard-selection-release” signal">main-clipboard-selection-release</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+<tr>
+<td class="signal_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a></td>
+<td class="signal_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection-request" title="The “main-clipboard-selection-request” signal">main-clipboard-selection-request</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-mouse-update" title="The “main-mouse-update” signal">main-mouse-update</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-migration-started" title="The “migration-started” signal">migration-started</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-new-file-transfer" title="The “new-file-transfer” signal">new-file-transfer</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceMainChannel.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannel-struct" title="struct SpiceMainChannel">SpiceMainChannel</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceMainChannel.html#SpiceMainChannelClass" title="struct SpiceMainChannelClass">SpiceMainChannelClass</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceMainChannel.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+ <span class="lineart">╰──</span> SpiceMainChannel
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceMainChannel.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceMainChannel.description"></a><h2>Description</h2>
+<p>The main channel is the Spice session control channel. It handles
+communication initialization (channels list), migrations, mouse
+modes, multimedia time, and agent communication.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceMainChannel.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-main-set-display"></a><h3>spice_main_set_display ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_set_display (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><span class="type">int</span> id</code></em>,
+ <em class="parameter"><code><span class="type">int</span> x</code></em>,
+ <em class="parameter"><code><span class="type">int</span> y</code></em>,
+ <em class="parameter"><code><span class="type">int</span> width</code></em>,
+ <em class="parameter"><code><span class="type">int</span> height</code></em>);</pre>
+<p>Notify the guest of screen resolution change. The notification is
+sent 1 second later, if no further changes happen.</p>
+<div class="refsect3">
+<a name="spice-main-set-display.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>id</p></td>
+<td class="parameter_description"><p>display ID</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>x</p></td>
+<td class="parameter_description"><p>x position</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>y</p></td>
+<td class="parameter_description"><p>y position</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>width</p></td>
+<td class="parameter_description"><p>display width</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>height</p></td>
+<td class="parameter_description"><p>display height</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-set-display-enabled"></a><h3>spice_main_set_display_enabled ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_set_display_enabled (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><span class="type">int</span> id</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a> enabled</code></em>);</pre>
+<p>When sending monitor configuration to agent guest, don't set
+display <em class="parameter"><code>id</code></em>
+, which the agent translates to disabling the display
+id. Note: this will take effect next time the monitor
+configuration is sent.</p>
+<div class="refsect3">
+<a name="spice-main-set-display-enabled.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>id</p></td>
+<td class="parameter_description"><p>display ID (if -1: set all displays)</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>enabled</p></td>
+<td class="parameter_description"><p>wether display <em class="parameter"><code>id</code></em>
+is enabled</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.6</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-update-display"></a><h3>spice_main_update_display ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_update_display (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><span class="type">int</span> id</code></em>,
+ <em class="parameter"><code><span class="type">int</span> x</code></em>,
+ <em class="parameter"><code><span class="type">int</span> y</code></em>,
+ <em class="parameter"><code><span class="type">int</span> width</code></em>,
+ <em class="parameter"><code><span class="type">int</span> height</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a> update</code></em>);</pre>
+<p>Update the display <em class="parameter"><code>id</code></em>
+ resolution.</p>
+<p>If <em class="parameter"><code>update</code></em>
+ is <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a>, the remote configuration will be updated too
+after 1 second without further changes. You can send when you want
+without delay the new configuration to the remote with
+<a class="link" href="SpiceMainChannel.html#spice-main-send-monitor-config" title="spice_main_send_monitor_config ()"><code class="function">spice_main_send_monitor_config()</code></a></p>
+<div class="refsect3">
+<a name="spice-main-update-display.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>id</p></td>
+<td class="parameter_description"><p>display ID</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>x</p></td>
+<td class="parameter_description"><p>x position</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>y</p></td>
+<td class="parameter_description"><p>y position</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>width</p></td>
+<td class="parameter_description"><p>display width</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>height</p></td>
+<td class="parameter_description"><p>display height</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>update</p></td>
+<td class="parameter_description"><p>if <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a>, update guest resolution after 1sec.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-update-display-enabled"></a><h3>spice_main_update_display_enabled ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_update_display_enabled (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><span class="type">int</span> id</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a> enabled</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a> update</code></em>);</pre>
+<p>When sending monitor configuration to agent guest, if <em class="parameter"><code>enabled</code></em>
+ is <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a>,
+don't set display <em class="parameter"><code>id</code></em>
+, which the agent translates to disabling the display
+id. If <em class="parameter"><code>enabled</code></em>
+ is <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a>, the monitor will be included in the next monitor
+update. Note: this will take effect next time the monitor configuration is
+sent.</p>
+<p>If <em class="parameter"><code>update</code></em>
+ is <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a>, no server update will be triggered by this call, but
+the value will be saved and used in the next configuration update.</p>
+<div class="refsect3">
+<a name="spice-main-update-display-enabled.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>id</p></td>
+<td class="parameter_description"><p>display ID (if -1: set all displays)</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>enabled</p></td>
+<td class="parameter_description"><p>wether display <em class="parameter"><code>id</code></em>
+is enabled</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>update</p></td>
+<td class="parameter_description"><p>if <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a>, update guest display state after 1sec.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.30</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-send-monitor-config"></a><h3>spice_main_send_monitor_config ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_main_send_monitor_config (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>);</pre>
+<p>Send monitors configuration previously set with
+<a class="link" href="SpiceMainChannel.html#spice-main-set-display" title="spice_main_set_display ()"><code class="function">spice_main_set_display()</code></a> and <a class="link" href="SpiceMainChannel.html#spice-main-set-display-enabled" title="spice_main_set_display_enabled ()"><code class="function">spice_main_set_display_enabled()</code></a></p>
+<div class="refsect3">
+<a name="spice-main-send-monitor-config.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-main-send-monitor-config.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> on success.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-agent-test-capability"></a><h3>spice_main_agent_test_capability ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_main_agent_test_capability (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> cap</code></em>);</pre>
+<p>Test capability of a remote agent.</p>
+<div class="refsect3">
+<a name="spice-main-agent-test-capability.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>cap</p></td>
+<td class="parameter_description"><p>an agent capability identifier</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-main-agent-test-capability.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if <em class="parameter"><code>cap</code></em>
+(channel kind capability) is available.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-request-mouse-mode"></a><h3>spice_main_request_mouse_mode ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_request_mouse_mode (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><span class="type">int</span> mode</code></em>);</pre>
+<p>Request a mouse mode to the server. The server may not be able to
+change the mouse mode, but spice-gtk will try to request it
+when possible.</p>
+<div class="refsect3">
+<a name="spice-main-request-mouse-mode.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><code class="literal">SpiceMainChannel</code></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>mode</p></td>
+<td class="parameter_description"><p>a SPICE_MOUSE_MODE</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.32</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-clipboard-selection-grab"></a><h3>spice_main_clipboard_selection_grab ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_clipboard_selection_grab (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> selection</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> *types</code></em>,
+ <em class="parameter"><code><span class="type">int</span> ntypes</code></em>);</pre>
+<p>Grab the guest clipboard, with <span class="type">VD_AGENT_CLIPBOARD</span> <em class="parameter"><code>types</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-main-clipboard-selection-grab.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>selection</p></td>
+<td class="parameter_description"><p>one of the clipboard <span class="type">VD_AGENT_CLIPBOARD_SELECTION_</span>*</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>types</p></td>
+<td class="parameter_description"><p>an array of <span class="type">VD_AGENT_CLIPBOARD</span> types available in the clipboard</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>ntypes</p></td>
+<td class="parameter_description"><p>the number of <em class="parameter"><code>types</code></em>
+</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.6</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-clipboard-selection-notify"></a><h3>spice_main_clipboard_selection_notify ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_clipboard_selection_notify (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> selection</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> type</code></em>,
+ <em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guchar"><span class="type">guchar</span></a> *data</code></em>,
+ <em class="parameter"><code><span class="type">size_t</span> size</code></em>);</pre>
+<p>Send the clipboard data to the guest.</p>
+<div class="refsect3">
+<a name="spice-main-clipboard-selection-notify.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>selection</p></td>
+<td class="parameter_description"><p>one of the clipboard <span class="type">VD_AGENT_CLIPBOARD_SELECTION_</span>*</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>type</p></td>
+<td class="parameter_description"><p>a <span class="type">VD_AGENT_CLIPBOARD</span> type</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>data</p></td>
+<td class="parameter_description"><p>clipboard data</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>size</p></td>
+<td class="parameter_description"><p>data length in bytes</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.6</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-clipboard-selection-release"></a><h3>spice_main_clipboard_selection_release ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_clipboard_selection_release
+ (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> selection</code></em>);</pre>
+<p>Release the clipboard (for example, when the client loses the
+clipboard grab): Inform the guest no clipboard data is available.</p>
+<div class="refsect3">
+<a name="spice-main-clipboard-selection-release.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>selection</p></td>
+<td class="parameter_description"><p>one of the clipboard <span class="type">VD_AGENT_CLIPBOARD_SELECTION_</span>*</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.6</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-clipboard-selection-request"></a><h3>spice_main_clipboard_selection_request ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_clipboard_selection_request
+ (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> selection</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> type</code></em>);</pre>
+<p>Request clipboard data of <em class="parameter"><code>type</code></em>
+ from the guest. The reply is sent
+through the <a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection" title="The “main-clipboard-selection” signal"><span class="type">“main-clipboard-selection”</span></a> signal.</p>
+<div class="refsect3">
+<a name="spice-main-clipboard-selection-request.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>selection</p></td>
+<td class="parameter_description"><p>one of the clipboard <span class="type">VD_AGENT_CLIPBOARD_SELECTION_</span>*</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>type</p></td>
+<td class="parameter_description"><p>a <span class="type">VD_AGENT_CLIPBOARD</span> type</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.6</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-clipboard-grab"></a><h3>spice_main_clipboard_grab ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_clipboard_grab (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> *types</code></em>,
+ <em class="parameter"><code><span class="type">int</span> ntypes</code></em>);</pre>
+<div class="warning">
+<p><code class="literal">spice_main_clipboard_grab</code> has been deprecated since version 0.6 and should not be used in newly-written code.</p>
+<p>use <a class="link" href="SpiceMainChannel.html#spice-main-clipboard-selection-grab" title="spice_main_clipboard_selection_grab ()"><code class="function">spice_main_clipboard_selection_grab()</code></a> instead.</p>
+</div>
+<p>Grab the guest clipboard, with <span class="type">VD_AGENT_CLIPBOARD</span> <em class="parameter"><code>types</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-main-clipboard-grab.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>types</p></td>
+<td class="parameter_description"><p>an array of <span class="type">VD_AGENT_CLIPBOARD</span> types available in the clipboard</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>ntypes</p></td>
+<td class="parameter_description"><p>the number of <em class="parameter"><code>types</code></em>
+</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-clipboard-release"></a><h3>spice_main_clipboard_release ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_clipboard_release (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>);</pre>
+<div class="warning">
+<p><code class="literal">spice_main_clipboard_release</code> has been deprecated since version 0.6 and should not be used in newly-written code.</p>
+<p>use <a class="link" href="SpiceMainChannel.html#spice-main-clipboard-selection-release" title="spice_main_clipboard_selection_release ()"><code class="function">spice_main_clipboard_selection_release()</code></a> instead.</p>
+</div>
+<p>Release the clipboard (for example, when the client loses the
+clipboard grab): Inform the guest no clipboard data is available.</p>
+<div class="refsect3">
+<a name="spice-main-clipboard-release.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-clipboard-notify"></a><h3>spice_main_clipboard_notify ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_clipboard_notify (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> type</code></em>,
+ <em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guchar"><span class="type">guchar</span></a> *data</code></em>,
+ <em class="parameter"><code><span class="type">size_t</span> size</code></em>);</pre>
+<div class="warning">
+<p><code class="literal">spice_main_clipboard_notify</code> has been deprecated since version 0.6 and should not be used in newly-written code.</p>
+<p>use <a class="link" href="SpiceMainChannel.html#spice-main-clipboard-selection-notify" title="spice_main_clipboard_selection_notify ()"><code class="function">spice_main_clipboard_selection_notify()</code></a> instead.</p>
+</div>
+<p>Send the clipboard data to the guest.</p>
+<div class="refsect3">
+<a name="spice-main-clipboard-notify.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>type</p></td>
+<td class="parameter_description"><p>a <span class="type">VD_AGENT_CLIPBOARD</span> type</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>data</p></td>
+<td class="parameter_description"><p>clipboard data</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>size</p></td>
+<td class="parameter_description"><p>data length in bytes</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-clipboard-request"></a><h3>spice_main_clipboard_request ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_clipboard_request (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> type</code></em>);</pre>
+<div class="warning">
+<p><code class="literal">spice_main_clipboard_request</code> has been deprecated since version 0.6 and should not be used in newly-written code.</p>
+<p>use <a class="link" href="SpiceMainChannel.html#spice-main-clipboard-selection-request" title="spice_main_clipboard_selection_request ()"><code class="function">spice_main_clipboard_selection_request()</code></a> instead.</p>
+</div>
+<p>Request clipboard data of <em class="parameter"><code>type</code></em>
+ from the guest. The reply is sent
+through the <a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard" title="The “main-clipboard” signal"><span class="type">“main-clipboard”</span></a> signal.</p>
+<div class="refsect3">
+<a name="spice-main-clipboard-request.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>type</p></td>
+<td class="parameter_description"><p>a <span class="type">VD_AGENT_CLIPBOARD</span> type</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-file-copy-async"></a><h3>spice_main_file_copy_async ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_main_file_copy_async (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGFile.html#GFile-struct"><span class="type">GFile</span></a> **sources</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGFile.html#GFileCopyFlags"><span class="type">GFileCopyFlags</span></a> flags</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGCancellable.html#GCancellable-struct"><span class="type">GCancellable</span></a> *cancellable</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGFile.html#GFileProgressCallback"><span class="type">GFileProgressCallback</span></a> progress_callback</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> progress_callback_data</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncReadyCallback"><span class="type">GAsyncReadyCallback</span></a> callback</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data</code></em>);</pre>
+<p>Copies the file <em class="parameter"><code>sources</code></em>
+ to guest</p>
+<p>If <em class="parameter"><code>cancellable</code></em>
+ is not <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>, then the operation can be cancelled by
+triggering the cancellable object from another thread. If the operation
+was cancelled, the error <a href="/usr/share/gtk-doc/html/giogio-GIOError.html#G-IO-ERROR-CANCELLED:CAPS"><code class="literal">G_IO_ERROR_CANCELLED</code></a> will be returned.</p>
+<p>If <em class="parameter"><code>progress_callback</code></em>
+ is not <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>, then the operation can be monitored by
+setting this to a <a href="/usr/share/gtk-doc/html/gioGFile.html#GFileProgressCallback"><span class="type">GFileProgressCallback</span></a> function. <em class="parameter"><code>progress_callback_data</code></em>
+
+will be passed to this function. It is guaranteed that this callback will
+be called after all data has been transferred with the total number of bytes
+copied during the operation. Note that before release 0.31, progress_callback
+was broken since it only provided status for a single file transfer, but did
+not provide a way to determine which file it referred to. In release 0.31,
+this behavior was changed so that progress_callback provides the status of
+all ongoing file transfers. If you need to monitor the status of individual
+files, please connect to the <a class="link" href="SpiceMainChannel.html#SpiceMainChannel-new-file-transfer" title="The “new-file-transfer” signal"><span class="type">“new-file-transfer”</span></a> signal.</p>
+<p>When the operation is finished, callback will be called. You can then call
+<a class="link" href="SpiceMainChannel.html#spice-main-file-copy-finish" title="spice_main_file_copy_finish ()"><code class="function">spice_main_file_copy_finish()</code></a> to get the result of the operation. Note that
+before release 0.33 the callback was called for each file in multiple file
+transfer. This behavior was changed for the same reason as the
+progress_callback (above). If you need to monitor the ending of individual
+files, you can connect to "finished" signal from each SpiceFileTransferTask.</p>
+<div class="refsect3">
+<a name="spice-main-file-copy-async.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>sources</p></td>
+<td class="parameter_description"><p> a <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated array of <a href="/usr/share/gtk-doc/html/gioGFile.html#GFile-struct"><span class="type">GFile</span></a> objects to be transferred. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> zero-terminated=1]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>flags</p></td>
+<td class="parameter_description"><p>set of <a href="/usr/share/gtk-doc/html/gioGFile.html#GFileCopyFlags"><span class="type">GFileCopyFlags</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>cancellable</p></td>
+<td class="parameter_description"><p> optional <a href="/usr/share/gtk-doc/html/gioGCancellable.html#GCancellable-struct"><span class="type">GCancellable</span></a> object, <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> to ignore. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>progress_callback</p></td>
+<td class="parameter_description"><p> function to callback with
+progress information, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if progress information is not needed. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>][<acronym title="The callback is valid only during the call to the method."><span class="acronym">scope call</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>progress_callback_data</p></td>
+<td class="parameter_description"><p> user data to pass to <em class="parameter"><code>progress_callback</code></em>
+. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="This parameter is a 'user_data', for callbacks; many bindings can pass NULL here."><span class="acronym">closure</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>callback</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncReadyCallback"><span class="type">GAsyncReadyCallback</span></a> to call when the request is satisfied</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>the data to pass to callback function</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-main-file-copy-finish"></a><h3>spice_main_file_copy_finish ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_main_file_copy_finish (<em class="parameter"><code><a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncResult-struct"><span class="type">GAsyncResult</span></a> *result</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> **error</code></em>);</pre>
+<p>Finishes copying the file started with
+<a class="link" href="SpiceMainChannel.html#spice-main-file-copy-async" title="spice_main_file_copy_async ()"><code class="function">spice_main_file_copy_async()</code></a>.</p>
+<div class="refsect3">
+<a name="spice-main-file-copy-finish.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>result</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncResult-struct"><span class="type">GAsyncResult</span></a>.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>error</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a>, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-main-file-copy-finish.returns"></a><h4>Returns</h4>
+<p> a <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> on success, <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> on error.</p>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceMainChannel.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceMainChannel-struct"></a><h3>struct SpiceMainChannel</h3>
+<pre class="programlisting">struct SpiceMainChannel;</pre>
+<p>The <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannelClass"></a><h3>struct SpiceMainChannelClass</h3>
+<pre class="programlisting">struct SpiceMainChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*mouse_update)(SpiceChannel *channel);
+ void (*agent_update)(SpiceChannel *channel);
+};
+</pre>
+<p>Class structure for <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceMainChannelClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceMainChannelClass.mouse-update"></a>mouse_update</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <span class="type">“mouse-update”</span> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceMainChannelClass.agent-update"></a>agent_update</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <span class="type">“agent-update”</span> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceMainChannel.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="SpiceMainChannel--agent-caps-0"></a><h3>The <code class="literal">“agent-caps-0”</code> property</h3>
+<pre class="programlisting"> “agent-caps-0” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>Agent capability bits 0 -> 31.</p>
+<p>Flags: Read</p>
+<p>Allowed values: >= 0</p>
+<p>Default value: 0</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel--agent-connected"></a><h3>The <code class="literal">“agent-connected”</code> property</h3>
+<pre class="programlisting"> “agent-connected” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Whether the agent is connected.</p>
+<p>Flags: Read</p>
+<p>Default value: FALSE</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel--color-depth"></a><h3>The <code class="literal">“color-depth”</code> property</h3>
+<pre class="programlisting"> “color-depth” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>Color depth.</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Allowed values: <= 32</p>
+<p>Default value: 0</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel--disable-animation"></a><h3>The <code class="literal">“disable-animation”</code> property</h3>
+<pre class="programlisting"> “disable-animation” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Disable guest animations.</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: FALSE</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel--disable-display-align"></a><h3>The <code class="literal">“disable-display-align”</code> property</h3>
+<pre class="programlisting"> “disable-display-align” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Disable automatic horizontal display position alignment.</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: FALSE</p>
+<p class="since">Since: 0.13</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel--disable-display-position"></a><h3>The <code class="literal">“disable-display-position”</code> property</h3>
+<pre class="programlisting"> “disable-display-position” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Disable using display position when setting monitor config.</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: TRUE</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel--disable-font-smooth"></a><h3>The <code class="literal">“disable-font-smooth”</code> property</h3>
+<pre class="programlisting"> “disable-font-smooth” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Disable guest font smoothing.</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: FALSE</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel--disable-wallpaper"></a><h3>The <code class="literal">“disable-wallpaper”</code> property</h3>
+<pre class="programlisting"> “disable-wallpaper” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Disable guest wallpaper.</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: FALSE</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel--max-clipboard"></a><h3>The <code class="literal">“max-clipboard”</code> property</h3>
+<pre class="programlisting"> “max-clipboard” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>Maximum size of clipboard operations in bytes (default 100MB,
+-1 for unlimited size);</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Allowed values: >= -1</p>
+<p>Default value: 104857600</p>
+<p class="since">Since: 0.22</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel--mouse-mode"></a><h3>The <code class="literal">“mouse-mode”</code> property</h3>
+<pre class="programlisting"> “mouse-mode” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>Spice protocol specifies two mouse modes, client mode and
+server mode. In client mode (<code class="literal">SPICE_MOUSE_MODE_CLIENT</code>), the
+affective mouse is the client side mouse: the client sends
+mouse position within the display and the server sends mouse
+shape messages. In server mode (<code class="literal">SPICE_MOUSE_MODE_SERVER</code>), the
+client sends relative mouse movements and the server sends
+position and shape commands.</p>
+<p>Flags: Read</p>
+<p>Allowed values: >= 0</p>
+<p>Default value: 0</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceMainChannel.signal-details"></a><h2>Signal Details</h2>
+<div class="refsect2">
+<a name="SpiceMainChannel-main-agent-update"></a><h3>The <code class="literal">“main-agent-update”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *main,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Notify when the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><code class="literal">SpiceMainChannel</code></a>:agent-connected or
+<a class="link" href="SpiceMainChannel.html" title="Main Channel"><code class="literal">SpiceMainChannel</code></a>:agent-caps-0 property change.</p>
+<div class="refsect3">
+<a name="SpiceMainChannel-main-agent-update.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>main</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel-main-clipboard"></a><h3>The <code class="literal">“main-clipboard”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *main,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> type,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> data,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> size,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Provides guest clipboard data requested by <a class="link" href="SpiceMainChannel.html#spice-main-clipboard-request" title="spice_main_clipboard_request ()"><code class="function">spice_main_clipboard_request()</code></a>.</p>
+<div class="warning">
+<p><code class="literal">SpiceMainChannel::main-clipboard</code> has been deprecated since version 0.6 and should not be used in newly-written code.</p>
+<p>use SpiceMainChannel::main-clipboard-selection instead.</p>
+</div>
+<div class="refsect3">
+<a name="SpiceMainChannel-main-clipboard.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>main</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>type</p></td>
+<td class="parameter_description"><p>the VD_AGENT_CLIPBOARD data type</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>data</p></td>
+<td class="parameter_description"><p>clipboard data</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>size</p></td>
+<td class="parameter_description"><p>size of <em class="parameter"><code>data</code></em>
+in bytes</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel-main-clipboard-grab"></a><h3>The <code class="literal">“main-clipboard-grab”</code> signal</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+user_function (<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *main,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> types,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> ntypes,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Inform when clipboard data is available from the guest, and for
+which <em class="parameter"><code>types</code></em>
+.</p>
+<div class="warning">
+<p><code class="literal">SpiceMainChannel::main-clipboard-grab</code> has been deprecated since version 0.6 and should not be used in newly-written code.</p>
+<p>use SpiceMainChannel::main-clipboard-selection-grab instead.</p>
+</div>
+<div class="refsect3">
+<a name="SpiceMainChannel-main-clipboard-grab.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>main</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>types</p></td>
+<td class="parameter_description"><p>the VD_AGENT_CLIPBOARD data types</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>ntypes</p></td>
+<td class="parameter_description"><p>the number of <em class="parameter"><code>types</code></em>
+</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel-main-clipboard-release"></a><h3>The <code class="literal">“main-clipboard-release”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *main,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Inform when the clipboard is released from the guest, when no
+clipboard data is available from the guest.</p>
+<div class="warning">
+<p><code class="literal">SpiceMainChannel::main-clipboard-release</code> has been deprecated since version 0.6 and should not be used in newly-written code.</p>
+<p>use SpiceMainChannel::main-clipboard-selection-release instead.</p>
+</div>
+<div class="refsect3">
+<a name="SpiceMainChannel-main-clipboard-release.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>main</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel-main-clipboard-request"></a><h3>The <code class="literal">“main-clipboard-request”</code> signal</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+user_function (<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *main,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> types,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Request clipboard data from the client.</p>
+<div class="warning">
+<p><code class="literal">SpiceMainChannel::main-clipboard-request</code> has been deprecated since version 0.6 and should not be used in newly-written code.</p>
+<p>use SpiceMainChannel::main-clipboard-selection-request instead.</p>
+</div>
+<div class="refsect3">
+<a name="SpiceMainChannel-main-clipboard-request.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>main</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>types</p></td>
+<td class="parameter_description"><p>the VD_AGENT_CLIPBOARD request type</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="SpiceMainChannel-main-clipboard-request.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if the request is successful</p>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel-main-clipboard-selection"></a><h3>The <code class="literal">“main-clipboard-selection”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *main,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> selection,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> type,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> data,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> size,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Informs that clipboard selection data are available.</p>
+<div class="refsect3">
+<a name="SpiceMainChannel-main-clipboard-selection.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>main</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>selection</p></td>
+<td class="parameter_description"><p>a VD_AGENT_CLIPBOARD_SELECTION clipboard</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>type</p></td>
+<td class="parameter_description"><p>the VD_AGENT_CLIPBOARD data type</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>data</p></td>
+<td class="parameter_description"><p>clipboard data</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>size</p></td>
+<td class="parameter_description"><p>size of <em class="parameter"><code>data</code></em>
+in bytes</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+<p class="since">Since: 0.6</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel-main-clipboard-selection-grab"></a><h3>The <code class="literal">“main-clipboard-selection-grab”</code> signal</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+user_function (<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *main,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> selection,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> types,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> ntypes,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Inform when clipboard data is available from the guest, and for
+which <em class="parameter"><code>types</code></em>
+.</p>
+<div class="refsect3">
+<a name="SpiceMainChannel-main-clipboard-selection-grab.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>main</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>selection</p></td>
+<td class="parameter_description"><p>a VD_AGENT_CLIPBOARD_SELECTION clipboard</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>types</p></td>
+<td class="parameter_description"><p>the VD_AGENT_CLIPBOARD data types</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>ntypes</p></td>
+<td class="parameter_description"><p>the number of <em class="parameter"><code>types</code></em>
+</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+<p class="since">Since: 0.6</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel-main-clipboard-selection-release"></a><h3>The <code class="literal">“main-clipboard-selection-release”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *main,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> selection,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Inform when the clipboard is released from the guest, when no
+clipboard data is available from the guest.</p>
+<div class="refsect3">
+<a name="SpiceMainChannel-main-clipboard-selection-release.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>main</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>selection</p></td>
+<td class="parameter_description"><p>a VD_AGENT_CLIPBOARD_SELECTION clipboard</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+<p class="since">Since: 0.6</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel-main-clipboard-selection-request"></a><h3>The <code class="literal">“main-clipboard-selection-request”</code> signal</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+user_function (<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *main,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> selection,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> types,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Request clipboard data from the client.</p>
+<div class="refsect3">
+<a name="SpiceMainChannel-main-clipboard-selection-request.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>main</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>selection</p></td>
+<td class="parameter_description"><p>a VD_AGENT_CLIPBOARD_SELECTION clipboard</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>types</p></td>
+<td class="parameter_description"><p>the VD_AGENT_CLIPBOARD request type</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="SpiceMainChannel-main-clipboard-selection-request.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if the request is successful</p>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+<p class="since">Since: 0.6</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel-main-mouse-update"></a><h3>The <code class="literal">“main-mouse-update”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *main,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Notify when the mouse mode has changed.</p>
+<div class="refsect3">
+<a name="SpiceMainChannel-main-mouse-update.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>main</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel-migration-started"></a><h3>The <code class="literal">“migration-started”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *main,
+ <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct"><span class="type">GObject</span></a> *session,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Inform when migration is starting. Application wishing to make
+connections themself can set the <a class="link" href="SpiceSession.html#SpiceSession--client-sockets" title="The “client-sockets” property"><span class="type">“client-sockets”</span></a>
+to <em class="parameter"><code>TRUE</code></em>
+, then follow <a class="link" href="SpiceSession.html#SpiceSession-channel-new" title="The “channel-new” signal"><span class="type">“channel-new”</span></a> creation, and
+use <a class="link" href="SpiceChannel.html#spice-channel-open-fd" title="spice_channel_open_fd ()"><code class="function">spice_channel_open_fd()</code></a> once the socket is created.</p>
+<div class="refsect3">
+<a name="SpiceMainChannel-migration-started.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>main</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>a migration <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceMainChannel-new-file-transfer"></a><h3>The <code class="literal">“new-file-transfer”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> *main,
+ <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct"><span class="type">GObject</span></a> *task,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>This signal is emitted when a new file transfer task has been initiated
+on this channel. Client applications may take a reference on the <em class="parameter"><code>task</code></em>
+
+object and use it to monitor the status of the file transfer task.</p>
+<div class="refsect3">
+<a name="SpiceMainChannel-new-file-transfer.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>main</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>task</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task"><span class="type">SpiceFileTransferTask</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+<p class="since">Since: 0.31</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceMainChannel.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a>, and the GTK widget <span class="type">SpiceDisplay</span></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Playback Channel: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="prev" href="SpiceMainChannel.html" title="Main Channel">
+<link rel="next" href="SpiceRecordChannel.html" title="Record Channel">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpicePlaybackChannel.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpicePlaybackChannel.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_properties"> <span class="dim">|</span>
+ <a href="#SpicePlaybackChannel.properties" class="shortcut">Properties</a></span><span id="nav_signals"> <span class="dim">|</span>
+ <a href="#SpicePlaybackChannel.signals" class="shortcut">Signals</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceMainChannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceRecordChannel.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpicePlaybackChannel"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpicePlaybackChannel.top_of_page"></a>Playback Channel</span></h2>
+<p>Playback Channel — audio stream for playback</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody><tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpicePlaybackChannel.html#spice-playback-channel-set-delay" title="spice_playback_channel_set_delay ()">spice_playback_channel_set_delay</a> <span class="c_punctuation">()</span>
+</td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.properties"></a><h2>Properties</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="properties_type">
+<col width="300px" class="properties_name">
+<col width="200px" class="properties_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel--min-latency" title="The “min-latency” property">min-latency</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel--mute" title="The “mute” property">mute</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel--nchannels" title="The “nchannels” property">nchannels</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a></td>
+<td class="property_name"><a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel--volume" title="The “volume” property">volume</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.signals"></a><h2>Signals</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="signals_return">
+<col width="300px" class="signals_name">
+<col width="200px" class="signals_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-data" title="The “playback-data” signal">playback-data</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-get-delay" title="The “playback-get-delay” signal">playback-get-delay</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-start" title="The “playback-start” signal">playback-start</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-stop" title="The “playback-stop” signal">playback-stop</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-struct" title="struct SpicePlaybackChannel">SpicePlaybackChannel</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannelClass" title="struct SpicePlaybackChannelClass">SpicePlaybackChannelClass</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+ <span class="lineart">╰──</span> SpicePlaybackChannel
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.description"></a><h2>Description</h2>
+<p><a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a> class handles an audio playback stream. The
+audio data is received via <a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-data" title="The “playback-data” signal"><span class="type">“playback-data”</span></a>
+signal, and is controlled by the guest with
+<a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-stop" title="The “playback-stop” signal"><span class="type">“playback-stop”</span></a> and
+<a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-start" title="The “playback-start” signal"><span class="type">“playback-start”</span></a> signal events.</p>
+<p>Note: You may be interested to let the <a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="type">SpiceAudio</span></a> class play and
+record audio channels for your application.</p>
+</div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-playback-channel-set-delay"></a><h3>spice_playback_channel_set_delay ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_playback_channel_set_delay (<em class="parameter"><code><a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> delay_ms</code></em>);</pre>
+<p>Adjust the multimedia time according to the delay.</p>
+<div class="refsect3">
+<a name="spice-playback-channel-set-delay.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>delay_ms</p></td>
+<td class="parameter_description"><p>the delay in ms</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpicePlaybackChannel-struct"></a><h3>struct SpicePlaybackChannel</h3>
+<pre class="programlisting">struct SpicePlaybackChannel;</pre>
+<p>The <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpicePlaybackChannelClass"></a><h3>struct SpicePlaybackChannelClass</h3>
+<pre class="programlisting">struct SpicePlaybackChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*playback_start)(SpicePlaybackChannel *channel,
+ gint format, gint channels, gint freq);
+ void (*playback_data)(SpicePlaybackChannel *channel, gpointer *data, gint size);
+ void (*playback_stop)(SpicePlaybackChannel *channel);
+};
+</pre>
+<p>Class structure for <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a>.</p>
+<div class="refsect3">
+<a name="SpicePlaybackChannelClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpicePlaybackChannelClass.playback-start"></a>playback_start</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-start" title="The “playback-start” signal"><span class="type">“playback-start”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpicePlaybackChannelClass.playback-data"></a>playback_data</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-data" title="The “playback-data” signal"><span class="type">“playback-data”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpicePlaybackChannelClass.playback-stop"></a>playback_stop</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-stop" title="The “playback-stop” signal"><span class="type">“playback-stop”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="SpicePlaybackChannel--min-latency"></a><h3>The <code class="literal">“min-latency”</code> property</h3>
+<pre class="programlisting"> “min-latency” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>Playback min buffer size (ms).</p>
+<p>Flags: Read / Write</p>
+<p>Default value: 200</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpicePlaybackChannel--mute"></a><h3>The <code class="literal">“mute”</code> property</h3>
+<pre class="programlisting"> “mute” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Mute.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: FALSE</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpicePlaybackChannel--nchannels"></a><h3>The <code class="literal">“nchannels”</code> property</h3>
+<pre class="programlisting"> “nchannels” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>Number of Channels.</p>
+<p>Flags: Read / Write</p>
+<p>Allowed values: <= 255</p>
+<p>Default value: 2</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpicePlaybackChannel--volume"></a><h3>The <code class="literal">“volume”</code> property</h3>
+<pre class="programlisting"> “volume” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a></pre>
+<p>Playback volume.</p>
+<p>Flags: Read / Write</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.signal-details"></a><h2>Signal Details</h2>
+<div class="refsect2">
+<a name="SpicePlaybackChannel-playback-data"></a><h3>The <code class="literal">“playback-data”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a> *channel,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> data,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> data_size,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Provide audio data to be played.</p>
+<div class="refsect3">
+<a name="SpicePlaybackChannel-playback-data.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>data</p></td>
+<td class="parameter_description"><p>pointer to audio data</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>data_size</p></td>
+<td class="parameter_description"><p>size in byte of <em class="parameter"><code>data</code></em>
+</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpicePlaybackChannel-playback-get-delay"></a><h3>The <code class="literal">“playback-get-delay”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a> *channel,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Notify when the current playback delay is requested</p>
+<div class="refsect3">
+<a name="SpicePlaybackChannel-playback-get-delay.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpicePlaybackChannel-playback-start"></a><h3>The <code class="literal">“playback-start”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a> *channel,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> format,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> channels,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> rate,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Notify when the playback should start, and provide audio format
+characteristics.</p>
+<div class="refsect3">
+<a name="SpicePlaybackChannel-playback-start.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>format</p></td>
+<td class="parameter_description"><p>a <span class="type">SPICE_AUDIO_FMT</span></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>channels</p></td>
+<td class="parameter_description"><p>number of channels</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>rate</p></td>
+<td class="parameter_description"><p>audio rate</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>latency</p></td>
+<td class="parameter_description"><p>minimum playback latency in ms</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpicePlaybackChannel-playback-stop"></a><h3>The <code class="literal">“playback-stop”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a> *channel,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Notify when the playback should stop.</p>
+<div class="refsect3">
+<a name="SpicePlaybackChannel-playback-stop.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel"><span class="type">SpicePlaybackChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpicePlaybackChannel.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a>, and <a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="type">SpiceAudio</span></a></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Port Channel: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="prev" href="SpiceUsbredirChannel.html" title="USB Redirection Channel">
+<link rel="next" href="SpiceWebdavChannel.html" title="WebDAV Channel">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpicePortChannel.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpicePortChannel.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_properties"> <span class="dim">|</span>
+ <a href="#SpicePortChannel.properties" class="shortcut">Properties</a></span><span id="nav_signals"> <span class="dim">|</span>
+ <a href="#SpicePortChannel.signals" class="shortcut">Signals</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceUsbredirChannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceWebdavChannel.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpicePortChannel"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpicePortChannel.top_of_page"></a>Port Channel</span></h2>
+<p>Port Channel — private communication channel</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpicePortChannel.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpicePortChannel.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpicePortChannel.html#spice-port-event" title="spice_port_event ()">spice_port_event</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpicePortChannel.html#spice-port-write-async" title="spice_port_write_async ()">spice_port_write_async</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gssize"><span class="returnvalue">gssize</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpicePortChannel.html#spice-port-write-finish" title="spice_port_write_finish ()">spice_port_write_finish</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpicePortChannel.properties"></a><h2>Properties</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="properties_type">
+<col width="300px" class="properties_name">
+<col width="200px" class="properties_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpicePortChannel.html#SpicePortChannel--port-name" title="The “port-name” property">port-name</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpicePortChannel.html#SpicePortChannel--port-opened" title="The “port-opened” property">port-opened</a></td>
+<td class="property_flags">Read</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpicePortChannel.signals"></a><h2>Signals</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="signals_return">
+<col width="300px" class="signals_name">
+<col width="200px" class="signals_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpicePortChannel.html#SpicePortChannel-port-data" title="The “port-data” signal">port-data</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpicePortChannel.html#SpicePortChannel-port-event" title="The “port-event” signal">port-event</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpicePortChannel.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpicePortChannel.html#SpicePortChannel-struct" title="struct SpicePortChannel">SpicePortChannel</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpicePortChannel.html#SpicePortChannelClass" title="struct SpicePortChannelClass">SpicePortChannelClass</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpicePortChannel.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+ <span class="lineart">╰──</span> SpicePortChannel
+ <span class="lineart">╰──</span> <a class="link" href="SpiceWebdavChannel.html" title="WebDAV Channel">SpiceWebdavChannel</a>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpicePortChannel.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpicePortChannel.description"></a><h2>Description</h2>
+<p>A Spice port channel carry arbitrary data between the Spice client
+and the Spice server. It may be used to provide additional
+services on top of a Spice connection. For example, a channel can
+be associated with the qemu monitor for the client to interact
+with it, just like any qemu chardev. Or it may be used with
+various protocols, such as the Spice Controller.</p>
+<p>A port kind is identified simply by a fqdn, such as
+org.qemu.monitor, org.spice.spicy.test or org.ovirt.controller...</p>
+<p>Once connected and initialized, the client may read the name of the
+port via SpicePortChannel:port-name.</p>
+<p>When the other end of the port is ready,
+SpicePortChannel:port-opened is set to <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> and you can start
+receiving data via the signal SpicePortChannel::port-data, or
+sending data via <a class="link" href="SpicePortChannel.html#spice-port-write-async" title="spice_port_write_async ()"><code class="function">spice_port_write_async()</code></a>.</p>
+</div>
+<div class="refsect1">
+<a name="SpicePortChannel.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-port-event"></a><h3>spice_port_event ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_port_event (<em class="parameter"><code><a class="link" href="SpicePortChannel.html" title="Port Channel"><span class="type">SpicePortChannel</span></a> *port</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint8"><span class="type">guint8</span></a> event</code></em>);</pre>
+<p>Send an event to the port.</p>
+<p>Note: The values SPICE_PORT_EVENT_CLOSED and
+SPICE_PORT_EVENT_OPENED are managed by the channel connection
+state.</p>
+<div class="refsect3">
+<a name="spice-port-event.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>port</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpicePortChannel.html" title="Port Channel"><span class="type">SpicePortChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>event</p></td>
+<td class="parameter_description"><p>a SPICE_PORT_EVENT value</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.15</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-port-write-async"></a><h3>spice_port_write_async ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_port_write_async (<em class="parameter"><code><a class="link" href="SpicePortChannel.html" title="Port Channel"><span class="type">SpicePortChannel</span></a> *port</code></em>,
+ <em class="parameter"><code>const <span class="type">void</span> *buffer</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gsize"><span class="type">gsize</span></a> count</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGCancellable.html#GCancellable-struct"><span class="type">GCancellable</span></a> *cancellable</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncReadyCallback"><span class="type">GAsyncReadyCallback</span></a> callback</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data</code></em>);</pre>
+<p>Request an asynchronous write of count bytes from <em class="parameter"><code>buffer</code></em>
+ into the
+<em class="parameter"><code>port</code></em>
+. When the operation is finished <em class="parameter"><code>callback</code></em>
+ will be called. You
+can then call <a class="link" href="SpicePortChannel.html#spice-port-write-finish" title="spice_port_write_finish ()"><code class="function">spice_port_write_finish()</code></a> to get the result of
+the operation.</p>
+<div class="refsect3">
+<a name="spice-port-write-async.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>port</p></td>
+<td class="parameter_description"><p>A <a class="link" href="SpicePortChannel.html" title="Port Channel"><span class="type">SpicePortChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>buffer</p></td>
+<td class="parameter_description"><p> the buffer
+containing the data to write. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=count][<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> guint8]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>count</p></td>
+<td class="parameter_description"><p>the number of bytes to write</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>cancellable</p></td>
+<td class="parameter_description"><p> optional GCancellable object, NULL to ignore. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>callback</p></td>
+<td class="parameter_description"><p> callback to call when the request is satisfied. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="The callback is valid until first called."><span class="acronym">scope async</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p> the data to pass to callback function. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="This parameter is a 'user_data', for callbacks; many bindings can pass NULL here."><span class="acronym">closure</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.15</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-port-write-finish"></a><h3>spice_port_write_finish ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gssize"><span class="returnvalue">gssize</span></a>
+spice_port_write_finish (<em class="parameter"><code><a class="link" href="SpicePortChannel.html" title="Port Channel"><span class="type">SpicePortChannel</span></a> *port</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncResult-struct"><span class="type">GAsyncResult</span></a> *result</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> **error</code></em>);</pre>
+<p>Finishes a port write operation.</p>
+<div class="refsect3">
+<a name="spice-port-write-finish.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>port</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpicePortChannel.html" title="Port Channel"><span class="type">SpicePortChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>result</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncResult-struct"><span class="type">GAsyncResult</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>error</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> location to store the error occurring, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>
+to ignore</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-port-write-finish.returns"></a><h4>Returns</h4>
+<p> a <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gssize"><span class="type">gssize</span></a> containing the number of bytes written to the stream.</p>
+</div>
+<p class="since">Since: 0.15</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpicePortChannel.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpicePortChannel-struct"></a><h3>struct SpicePortChannel</h3>
+<pre class="programlisting">struct SpicePortChannel;</pre>
+<p>The <a class="link" href="SpicePortChannel.html" title="Port Channel"><span class="type">SpicePortChannel</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpicePortChannelClass"></a><h3>struct SpicePortChannelClass</h3>
+<pre class="programlisting">struct SpicePortChannelClass {
+ SpiceChannelClass parent_class;
+};
+</pre>
+<p>Class structure for <a class="link" href="SpicePortChannel.html" title="Port Channel"><span class="type">SpicePortChannel</span></a>.</p>
+<div class="refsect3">
+<a name="SpicePortChannelClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody></tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpicePortChannel.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="SpicePortChannel--port-name"></a><h3>The <code class="literal">“port-name”</code> property</h3>
+<pre class="programlisting"> “port-name” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>Port name.</p>
+<p>Flags: Read</p>
+<p>Default value: NULL</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpicePortChannel--port-opened"></a><h3>The <code class="literal">“port-opened”</code> property</h3>
+<pre class="programlisting"> “port-opened” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Port opened.</p>
+<p>Flags: Read</p>
+<p>Default value: FALSE</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpicePortChannel.signal-details"></a><h2>Signal Details</h2>
+<div class="refsect2">
+<a name="SpicePortChannel-port-data"></a><h3>The <code class="literal">“port-data”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpicePortChannel.html" title="Port Channel"><span class="type">SpicePortChannel</span></a> *channel,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> data,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> size,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpicePortChannel.html#SpicePortChannel-port-data" title="The “port-data” signal"><span class="type">“port-data”</span></a> signal is emitted when new
+port data is received.</p>
+<div class="refsect3">
+<a name="SpicePortChannel-port-data.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>the channel that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>data</p></td>
+<td class="parameter_description"><p>the data received</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>size</p></td>
+<td class="parameter_description"><p>number of bytes read</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+<p class="since">Since: 0.15</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpicePortChannel-port-event"></a><h3>The <code class="literal">“port-event”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpicePortChannel.html" title="Port Channel"><span class="type">SpicePortChannel</span></a> *channel,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> event,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpicePortChannel.html#SpicePortChannel-port-event" title="The “port-event” signal"><span class="type">“port-event”</span></a> signal is emitted when new
+port event is received.</p>
+<div class="refsect3">
+<a name="SpicePortChannel-port-event.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>the channel that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>event</p></td>
+<td class="parameter_description"><p>the event received</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>size</p></td>
+<td class="parameter_description"><p>number of bytes read</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-LAST:CAPS">Run Last</a></p>
+<p class="since">Since: 0.15</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpicePortChannel.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Record Channel: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="prev" href="SpicePlaybackChannel.html" title="Playback Channel">
+<link rel="next" href="SpiceSmartcardChannel.html" title="Smartcard Channel">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceRecordChannel.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceRecordChannel.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_properties"> <span class="dim">|</span>
+ <a href="#SpiceRecordChannel.properties" class="shortcut">Properties</a></span><span id="nav_signals"> <span class="dim">|</span>
+ <a href="#SpiceRecordChannel.signals" class="shortcut">Signals</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpicePlaybackChannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceSmartcardChannel.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceRecordChannel"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceRecordChannel.top_of_page"></a>Record Channel</span></h2>
+<p>Record Channel — audio stream for recording</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody><tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceRecordChannel.html#spice-record-send-data" title="spice_record_send_data ()">spice_record_send_data</a> <span class="c_punctuation">()</span>
+</td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.properties"></a><h2>Properties</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="properties_type">
+<col width="300px" class="properties_name">
+<col width="200px" class="properties_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel--mute" title="The “mute” property">mute</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel--nchannels" title="The “nchannels” property">nchannels</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a></td>
+<td class="property_name"><a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel--volume" title="The “volume” property">volume</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.signals"></a><h2>Signals</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="signals_return">
+<col width="300px" class="signals_name">
+<col width="200px" class="signals_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel-record-start" title="The “record-start” signal">record-start</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel-record-stop" title="The “record-stop” signal">record-stop</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel-struct" title="struct SpiceRecordChannel">SpiceRecordChannel</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceRecordChannel.html#SpiceRecordChannelClass" title="struct SpiceRecordChannelClass">SpiceRecordChannelClass</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+ <span class="lineart">╰──</span> SpiceRecordChannel
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.description"></a><h2>Description</h2>
+<p><a class="link" href="SpiceRecordChannel.html" title="Record Channel"><span class="type">SpiceRecordChannel</span></a> class handles an audio recording stream. The
+audio stream should start when <a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel-record-start" title="The “record-start” signal"><span class="type">“record-start”</span></a> is
+emitted and should be stopped when <a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel-record-stop" title="The “record-stop” signal"><span class="type">“record-stop”</span></a>
+is received.</p>
+<p>The audio is sent to the guest by calling <a class="link" href="SpiceRecordChannel.html#spice-record-send-data" title="spice_record_send_data ()"><code class="function">spice_record_send_data()</code></a>
+with the recorded PCM data.</p>
+<p>Note: You may be interested to let the <a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="type">SpiceAudio</span></a> class play and
+record audio channels for your application.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-record-send-data"></a><h3>spice_record_send_data ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_record_send_data (<em class="parameter"><code><a class="link" href="SpiceRecordChannel.html" title="Record Channel"><span class="type">SpiceRecordChannel</span></a> *channel</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> data</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gsize"><span class="type">gsize</span></a> bytes</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint32"><span class="type">guint32</span></a> time</code></em>);</pre>
+<p>Send recorded PCM data to the guest.</p>
+<div class="refsect3">
+<a name="spice-record-send-data.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceRecordChannel.html" title="Record Channel"><span class="type">SpiceRecordChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>data</p></td>
+<td class="parameter_description"><p>PCM data</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>bytes</p></td>
+<td class="parameter_description"><p>size of <em class="parameter"><code>data</code></em>
+</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>time</p></td>
+<td class="parameter_description"><p>stream timestamp</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceRecordChannel-struct"></a><h3>struct SpiceRecordChannel</h3>
+<pre class="programlisting">struct SpiceRecordChannel;</pre>
+<p>The <a class="link" href="SpiceRecordChannel.html" title="Record Channel"><span class="type">SpiceRecordChannel</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceRecordChannelClass"></a><h3>struct SpiceRecordChannelClass</h3>
+<pre class="programlisting">struct SpiceRecordChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*record_start)(SpiceRecordChannel *channel,
+ gint format, gint channels, gint freq);
+ void (*record_data)(SpiceRecordChannel *channel, gpointer *data, gint size);
+ void (*record_stop)(SpiceRecordChannel *channel);
+};
+</pre>
+<p>Class structure for <a class="link" href="SpiceRecordChannel.html" title="Record Channel"><span class="type">SpiceRecordChannel</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceRecordChannelClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceRecordChannelClass.record-start"></a>record_start</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel-record-start" title="The “record-start” signal"><span class="type">“record-start”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceRecordChannelClass.record-data"></a>record_data</code></em> ()</p></td>
+<td class="struct_member_description"><p>Unused (deprecated).</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceRecordChannelClass.record-stop"></a>record_stop</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel-record-stop" title="The “record-stop” signal"><span class="type">“record-stop”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="SpiceRecordChannel--mute"></a><h3>The <code class="literal">“mute”</code> property</h3>
+<pre class="programlisting"> “mute” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Mute.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: FALSE</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceRecordChannel--nchannels"></a><h3>The <code class="literal">“nchannels”</code> property</h3>
+<pre class="programlisting"> “nchannels” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
+<p>Number of Channels.</p>
+<p>Flags: Read / Write</p>
+<p>Allowed values: <= 255</p>
+<p>Default value: 2</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceRecordChannel--volume"></a><h3>The <code class="literal">“volume”</code> property</h3>
+<pre class="programlisting"> “volume” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a></pre>
+<p>Record volume.</p>
+<p>Flags: Read / Write</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.signal-details"></a><h2>Signal Details</h2>
+<div class="refsect2">
+<a name="SpiceRecordChannel-record-start"></a><h3>The <code class="literal">“record-start”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceRecordChannel.html" title="Record Channel"><span class="type">SpiceRecordChannel</span></a> *channel,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> format,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> channels,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> rate,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Notify when the recording should start, and provide audio format
+characteristics.</p>
+<div class="refsect3">
+<a name="SpiceRecordChannel-record-start.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceRecordChannel.html" title="Record Channel"><span class="type">SpiceRecordChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>format</p></td>
+<td class="parameter_description"><p>a <span class="type">SPICE_AUDIO_FMT</span></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>channels</p></td>
+<td class="parameter_description"><p>number of channels</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>rate</p></td>
+<td class="parameter_description"><p>audio rate</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceRecordChannel-record-stop"></a><h3>The <code class="literal">“record-stop”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceRecordChannel.html" title="Record Channel"><span class="type">SpiceRecordChannel</span></a> *channel,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>Notify when the recording should stop.</p>
+<div class="refsect3">
+<a name="SpiceRecordChannel-record-stop.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceRecordChannel.html" title="Record Channel"><span class="type">SpiceRecordChannel</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceRecordChannel.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a>, and <a class="link" href="SpiceAudio.html" title="Spice Audio"><span class="type">SpiceAudio</span></a></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Spice Session: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="prev" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="next" href="SpiceChannel.html" title="Spice Channel">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceSession.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceSession.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_properties"> <span class="dim">|</span>
+ <a href="#SpiceSession.properties" class="shortcut">Properties</a></span><span id="nav_signals"> <span class="dim">|</span>
+ <a href="#SpiceSession.signals" class="shortcut">Signals</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="ch02.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceChannel.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceSession"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceSession.top_of_page"></a>Spice Session</span></h2>
+<p>Spice Session — handles connection details, and active channels</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceSession.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceSession.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<a class="link" href="SpiceSession.html" title="Spice Session"><span class="returnvalue">SpiceSession</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSession.html#spice-session-new" title="spice_session_new ()">spice_session_new</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSession.html#spice-session-connect" title="spice_session_connect ()">spice_session_connect</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSession.html#spice-session-open-fd" title="spice_session_open_fd ()">spice_session_open_fd</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSession.html#spice-session-disconnect" title="spice_session_disconnect ()">spice_session_disconnect</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Doubly-Linked-Lists.html#GList"><span class="returnvalue">GList</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSession.html#spice-session-get-channels" title="spice_session_get_channels ()">spice_session_get_channels</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSession.html#spice-session-get-read-only" title="spice_session_get_read_only ()">spice_session_get_read_only</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSession.html#spice-session-has-channel-type" title="spice_session_has_channel_type ()">spice_session_has_channel_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="returnvalue">SpiceURI</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSession.html#spice-session-get-proxy-uri" title="spice_session_get_proxy_uri ()">spice_session_get_proxy_uri</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSession.html#spice-session-is-for-migration" title="spice_session_is_for_migration ()">spice_session_is_for_migration</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Commandline-option-parser.html#GOptionGroup"><span class="returnvalue">GOptionGroup</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSession.html#spice-get-option-group" title="spice_get_option_group ()">spice_get_option_group</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSession.html#spice-set-session-option" title="spice_set_session_option ()">spice_set_session_option</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Quarks.html#GQuark"><span class="returnvalue">GQuark</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSession.html#spice-client-error-quark" title="spice_client_error_quark ()">spice_client_error_quark</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceSession.properties"></a><h2>Properties</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="properties_type">
+<col width="300px" class="properties_name">
+<col width="200px" class="properties_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Byte-Arrays.html#GByteArray"><span class="type">GByteArray</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--ca" title="The “ca” property">ca</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--ca-file" title="The “ca-file” property">ca-file</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--cache-size" title="The “cache-size” property">cache-size</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--cert-subject" title="The “cert-subject” property">cert-subject</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--ciphers" title="The “ciphers” property">ciphers</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--client-sockets" title="The “client-sockets” property">client-sockets</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--color-depth" title="The “color-depth” property">color-depth</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-String-Utility-Functions.html#GStrv"><span class="type">GStrv</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--disable-effects" title="The “disable-effects” property">disable-effects</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--enable-audio" title="The “enable-audio” property">enable-audio</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--enable-smartcard" title="The “enable-smartcard” property">enable-smartcard</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--enable-usbredir" title="The “enable-usbredir” property">enable-usbredir</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--glz-window-size" title="The “glz-window-size” property">glz-window-size</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--host" title="The “host” property">host</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--inhibit-keyboard-grab" title="The “inhibit-keyboard-grab” property">inhibit-keyboard-grab</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a class="link" href="SpiceSession.html#SpiceSessionMigration" title="enum SpiceSessionMigration"><span class="type">SpiceSessionMigration</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--migration-state" title="The “migration-state” property">migration-state</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--name" title="The “name” property">name</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--password" title="The “password” property">password</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--port" title="The “port” property">port</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><span class="type">SpiceImageCompress</span></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--preferred-compression" title="The “preferred-compression” property">preferred-compression</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--protocol" title="The “protocol” property">protocol</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--proxy" title="The “proxy” property">proxy</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Byte-Arrays.html#GByteArray"><span class="type">GByteArray</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--pubkey" title="The “pubkey” property">pubkey</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--read-only" title="The “read-only” property">read-only</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-String-Utility-Functions.html#GStrv"><span class="type">GStrv</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--secure-channels" title="The “secure-channels” property">secure-channels</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--share-dir-ro" title="The “share-dir-ro” property">share-dir-ro</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--shared-dir" title="The “shared-dir” property">shared-dir</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-String-Utility-Functions.html#GStrv"><span class="type">GStrv</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--smartcard-certificates" title="The “smartcard-certificates” property">smartcard-certificates</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--smartcard-db" title="The “smartcard-db” property">smartcard-db</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--tls-port" title="The “tls-port” property">tls-port</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--unix-path" title="The “unix-path” property">unix-path</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--uri" title="The “uri” property">uri</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--username" title="The “username” property">username</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--uuid" title="The “uuid” property">uuid</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type"><a class="link" href="SpiceSession.html#SpiceSessionVerify" title="enum SpiceSessionVerify"><span class="type">SpiceSessionVerify</span></a></td>
+<td class="property_name"><a class="link" href="SpiceSession.html#SpiceSession--verify" title="The “verify” property">verify</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceSession.signals"></a><h2>Signals</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="signals_return">
+<col width="300px" class="signals_name">
+<col width="200px" class="signals_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceSession.html#SpiceSession-channel-destroy" title="The “channel-destroy” signal">channel-destroy</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceSession.html#SpiceSession-channel-new" title="The “channel-new” signal">channel-new</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceSession.html#SpiceSession-mm-time-reset" title="The “mm-time-reset” signal">mm-time-reset</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceSession.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword"> </td>
+<td class="function_name"><a class="link" href="SpiceSession.html#SpiceSession-struct" title="SpiceSession">SpiceSession</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword"> </td>
+<td class="function_name"><a class="link" href="SpiceSession.html#SpiceSessionClass" title="SpiceSessionClass">SpiceSessionClass</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="SpiceSession.html#SpiceSessionMigration" title="enum SpiceSessionMigration">SpiceSessionMigration</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="SpiceSession.html#SpiceSessionVerify" title="enum SpiceSessionVerify">SpiceSessionVerify</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="SpiceSession.html#SpiceClientError" title="enum SpiceClientError">SpiceClientError</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="SpiceSession.html#SPICE-CLIENT-ERROR:CAPS" title="SPICE_CLIENT_ERROR">SPICE_CLIENT_ERROR</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceSession.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="https://developer.gnome.org/gobject/unstable/gobject-Enumeration-and-Flag-Types.html">GEnum</a>
+ <span class="lineart">╰──</span> SpiceSessionMigration
+ <a href="https://developer.gnome.org/gobject/unstable/gobject-Enumeration-and-Flag-Types.html">GFlags</a>
+ <span class="lineart">╰──</span> SpiceSessionVerify
+ <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> SpiceSession
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceSession.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceSession.description"></a><h2>Description</h2>
+<p>The <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> class handles all the <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> connections.
+It's also the class that contains connections informations, such as
+<a class="link" href="SpiceSession.html#SpiceSession--host" title="The “host” property"><span class="type">“host”</span></a> and <a class="link" href="SpiceSession.html#SpiceSession--port" title="The “port” property"><span class="type">“port”</span></a>.</p>
+<p>You can simply set the property <a class="link" href="SpiceSession.html#SpiceSession--uri" title="The “uri” property"><span class="type">“uri”</span></a> to something like
+"spice://127.0.0.1?port=5930" to configure your connection details.</p>
+<p>You may want to connect to <a class="link" href="SpiceSession.html#SpiceSession-channel-new" title="The “channel-new” signal"><span class="type">“channel-new”</span></a> signal, to be
+informed of the availability of channels and to interact with
+them.</p>
+<p>For example, when the <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel"><span class="type">SpiceInputsChannel</span></a> is available and get the
+event <a class="link" href="SpiceChannel.html#SPICE-CHANNEL-OPENED:CAPS"><span class="type">SPICE_CHANNEL_OPENED</span></a>, you can send key events with
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-key-press" title="spice_inputs_key_press ()"><code class="function">spice_inputs_key_press()</code></a>. When the <a class="link" href="SpiceMainChannel.html" title="Main Channel"><span class="type">SpiceMainChannel</span></a> is available,
+you can start sharing the clipboard... .</p>
+<p>Once <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> properties set, you can call
+<a class="link" href="SpiceSession.html#spice-session-connect" title="spice_session_connect ()"><code class="function">spice_session_connect()</code></a> to start connecting and communicating with
+a Spice server.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceSession.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-session-new"></a><h3>spice_session_new ()</h3>
+<pre class="programlisting"><a class="link" href="SpiceSession.html" title="Spice Session"><span class="returnvalue">SpiceSession</span></a> *
+spice_session_new (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p>Creates a new Spice session.</p>
+<div class="refsect3">
+<a name="spice-session-new.returns"></a><h4>Returns</h4>
+<p> a new <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-session-connect"></a><h3>spice_session_connect ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_session_connect (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>);</pre>
+<p>Open the session using the <a class="link" href="SpiceSession.html#SpiceSession--host" title="The “host” property"><span class="type">“host”</span></a> and
+<a class="link" href="SpiceSession.html#SpiceSession--port" title="The “port” property"><span class="type">“port”</span></a>.</p>
+<div class="refsect3">
+<a name="spice-session-connect.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-session-connect.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> if the session state is invalid for connection
+request. <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if the connection is initiated. To know whether the
+connection is established, you must watch for channels creation
+(<a class="link" href="SpiceSession.html#SpiceSession-channel-new" title="The “channel-new” signal"><span class="type">“channel-new”</span></a>) and the channels state
+(<a class="link" href="SpiceChannel.html#SpiceChannel-channel-event" title="The “channel-event” signal"><span class="type">“channel-event”</span></a>).</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-session-open-fd"></a><h3>spice_session_open_fd ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_session_open_fd (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>,
+ <em class="parameter"><code><span class="type">int</span> fd</code></em>);</pre>
+<p>Open the session using the provided <em class="parameter"><code>fd</code></em>
+ socket file
+descriptor. This is useful if you create the fd yourself, for
+example to setup a SSH tunnel.</p>
+<p>Note however that additional sockets will be needed by all the channels
+created for <em class="parameter"><code>session</code></em>
+ so users of this API should hook into
+SpiceChannel::open-fd signal for each channel they are interested in, and
+create and pass a new socket to the channel using <a class="link" href="SpiceChannel.html#spice-channel-open-fd" title="spice_channel_open_fd ()"><span class="type">spice_channel_open_fd</span></a>, in
+the signal callback.</p>
+<p>If <em class="parameter"><code>fd</code></em>
+ is -1, a valid fd will be requested later via the
+SpiceChannel::open-fd signal. Typically, you would want to just pass -1 as
+<em class="parameter"><code>fd</code></em>
+ this call since you will have to hook to SpiceChannel::open-fd signal
+anyway.</p>
+<div class="refsect3">
+<a name="spice-session-open-fd.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>fd</p></td>
+<td class="parameter_description"><p>a file descriptor (socket) or -1</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-session-open-fd.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> on success.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-session-disconnect"></a><h3>spice_session_disconnect ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_session_disconnect (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>);</pre>
+<p>Disconnect the <em class="parameter"><code>session</code></em>
+, and destroy all channels.</p>
+<div class="refsect3">
+<a name="spice-session-disconnect.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-session-get-channels"></a><h3>spice_session_get_channels ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Doubly-Linked-Lists.html#GList"><span class="returnvalue">GList</span></a> *
+spice_session_get_channels (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>);</pre>
+<p>Get the list of current channels associated with this <em class="parameter"><code>session</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-session-get-channels.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-session-get-channels.returns"></a><h4>Returns</h4>
+<p> a <a href="/usr/share/gtk-doc/html/glibglib-Doubly-Linked-Lists.html#GList"><span class="type">GList</span></a>
+of unowned <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> channels. </p>
+<p><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> SpiceChannel][<acronym title="Free data container after the code is done."><span class="acronym">transfer container</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-session-get-read-only"></a><h3>spice_session_get_read_only ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_session_get_read_only (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>);</pre>
+<p>Checks whether the <em class="parameter"><code>session</code></em>
+ is read-only.</p>
+<div class="refsect3">
+<a name="spice-session-get-read-only.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-session-get-read-only.returns"></a><h4>Returns</h4>
+<p> whether the <em class="parameter"><code>session</code></em>
+is in read-only mode.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-session-has-channel-type"></a><h3>spice_session_has_channel_type ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_session_has_channel_type (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> type</code></em>);</pre>
+<p>See if there is a <em class="parameter"><code>type</code></em>
+ channel in the channels associated with this
+<em class="parameter"><code>session</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-session-has-channel-type.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>type</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceChannel.html#SpiceChannel--channel-type" title="The “channel-type” property"><span class="type">“channel-type”</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-session-has-channel-type.returns"></a><h4>Returns</h4>
+<p> TRUE if a <em class="parameter"><code>type</code></em>
+channel is available otherwise FALSE.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-session-get-proxy-uri"></a><h3>spice_session_get_proxy_uri ()</h3>
+<pre class="programlisting"><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="returnvalue">SpiceURI</span></a> *
+spice_session_get_proxy_uri (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>);</pre>
+<p>Gets the <em class="parameter"><code>session</code></em>
+ proxy uri.</p>
+<div class="refsect3">
+<a name="spice-session-get-proxy-uri.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-session-get-proxy-uri.returns"></a><h4>Returns</h4>
+<p> the session proxy <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p>
+<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-session-is-for-migration"></a><h3>spice_session_is_for_migration ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_session_is_for_migration (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>);</pre>
+<p>During seamless migration, channels may be created to establish a
+connection with the target, but they are temporary and should only
+handle migration steps. In order to avoid other interactions with
+the client, channels should check this value.</p>
+<div class="refsect3">
+<a name="spice-session-is-for-migration.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>a Spice session</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-session-is-for-migration.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if the session is a copy created during migration</p>
+</div>
+<p class="since">Since: 0.27</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-get-option-group"></a><h3>spice_get_option_group ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Commandline-option-parser.html#GOptionGroup"><span class="returnvalue">GOptionGroup</span></a> *
+spice_get_option_group (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p>Gets commandline options.</p>
+<p>Bindings for other languages are available since 0.32</p>
+<div class="refsect3">
+<a name="spice-get-option-group.returns"></a><h4>Returns</h4>
+<p> a <a href="/usr/share/gtk-doc/html/glibglib-Commandline-option-parser.html#GOptionGroup"><span class="type">GOptionGroup</span></a> for the commandline
+arguments specific to Spice. You have to call
+<a class="link" href="SpiceSession.html#spice-set-session-option" title="spice_set_session_option ()"><code class="function">spice_set_session_option()</code></a> after to set the options on a
+<a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a>. </p>
+<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-set-session-option"></a><h3>spice_set_session_option ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_set_session_option (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>);</pre>
+<p>Set various properties on <em class="parameter"><code>session</code></em>
+, according to the commandline
+arguments given to <a class="link" href="SpiceSession.html#spice-get-option-group" title="spice_get_option_group ()"><code class="function">spice_get_option_group()</code></a> option group.</p>
+<div class="refsect3">
+<a name="spice-set-session-option.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> to set option upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-client-error-quark"></a><h3>spice_client_error_quark ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Quarks.html#GQuark"><span class="returnvalue">GQuark</span></a>
+spice_client_error_quark (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p>Gets a <a href="/usr/share/gtk-doc/html/glibglib-Quarks.html#GQuark"><span class="type">GQuark</span></a> representing the string "spice-client-error-quark"</p>
+<div class="refsect3">
+<a name="spice-client-error-quark.returns"></a><h4>Returns</h4>
+<p> the <a href="/usr/share/gtk-doc/html/glibglib-Quarks.html#GQuark"><span class="type">GQuark</span></a> representing the string.</p>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceSession.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceSession-struct"></a><h3>SpiceSession</h3>
+<pre class="programlisting">typedef struct _SpiceSession SpiceSession;</pre>
+<p>The <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSessionClass"></a><h3>SpiceSessionClass</h3>
+<pre class="programlisting">typedef struct {
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*channel_new)(SpiceSession *session, SpiceChannel *channel);
+ void (*channel_destroy)(SpiceSession *session, SpiceChannel *channel);
+} SpiceSessionClass;
+</pre>
+<p>Class structure for <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceSessionClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceSessionClass.channel-new"></a>channel_new</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceSession.html#SpiceSession-channel-new" title="The “channel-new” signal"><span class="type">“channel_new”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceSessionClass.channel-destroy"></a>channel_destroy</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceSession.html#SpiceSession-channel-destroy" title="The “channel-destroy” signal"><span class="type">“channel_destroy”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSessionMigration"></a><h3>enum SpiceSessionMigration</h3>
+<p>Session migration state.</p>
+<div class="refsect3">
+<a name="SpiceSessionMigration.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-SESSION-MIGRATION-NONE:CAPS"></a>SPICE_SESSION_MIGRATION_NONE</p></td>
+<td class="enum_member_description">
+<p>no migration going on</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-SESSION-MIGRATION-SWITCHING:CAPS"></a>SPICE_SESSION_MIGRATION_SWITCHING</p></td>
+<td class="enum_member_description">
+<p>the session is switching host (destroy and reconnect)</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-SESSION-MIGRATION-MIGRATING:CAPS"></a>SPICE_SESSION_MIGRATION_MIGRATING</p></td>
+<td class="enum_member_description">
+<p>the session is migrating seamlessly (reconnect)</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-SESSION-MIGRATION-CONNECTING:CAPS"></a>SPICE_SESSION_MIGRATION_CONNECTING</p></td>
+<td class="enum_member_description">
+<p>the migration is connecting to destination (Since: 0.27)</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSessionVerify"></a><h3>enum SpiceSessionVerify</h3>
+<p>Peer certificate verification parameters flags.</p>
+<div class="refsect3">
+<a name="SpiceSessionVerify.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-SESSION-VERIFY-PUBKEY:CAPS"></a>SPICE_SESSION_VERIFY_PUBKEY</p></td>
+<td class="enum_member_description">
+<p>verify certificate public key matching</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-SESSION-VERIFY-HOSTNAME:CAPS"></a>SPICE_SESSION_VERIFY_HOSTNAME</p></td>
+<td class="enum_member_description">
+<p>verify certificate hostname matching</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-SESSION-VERIFY-SUBJECT:CAPS"></a>SPICE_SESSION_VERIFY_SUBJECT</p></td>
+<td class="enum_member_description">
+<p>verify certificate subject matching</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceClientError"></a><h3>enum SpiceClientError</h3>
+<p>Error codes returned by spice-client API.</p>
+<div class="refsect3">
+<a name="SpiceClientError.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CLIENT-ERROR-FAILED:CAPS"></a>SPICE_CLIENT_ERROR_FAILED</p></td>
+<td class="enum_member_description">
+<p>generic error code</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CLIENT-ERROR-USB-DEVICE-REJECTED:CAPS"></a>SPICE_CLIENT_ERROR_USB_DEVICE_REJECTED</p></td>
+<td class="enum_member_description">
+<p>device redirection rejected by host</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CLIENT-ERROR-USB-DEVICE-LOST:CAPS"></a>SPICE_CLIENT_ERROR_USB_DEVICE_LOST</p></td>
+<td class="enum_member_description">
+<p>device disconnected (fatal IO error)</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CLIENT-ERROR-AUTH-NEEDS-PASSWORD:CAPS"></a>SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD</p></td>
+<td class="enum_member_description">
+<p>password is required</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CLIENT-ERROR-AUTH-NEEDS-USERNAME:CAPS"></a>SPICE_CLIENT_ERROR_AUTH_NEEDS_USERNAME</p></td>
+<td class="enum_member_description">
+<p>username is required</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CLIENT-ERROR-AUTH-NEEDS-PASSWORD-AND-USERNAME:CAPS"></a>SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD_AND_USERNAME</p></td>
+<td class="enum_member_description">
+<p>password and username are required</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-CLIENT-ERROR-USB-SERVICE:CAPS"></a>SPICE_CLIENT_ERROR_USB_SERVICE</p></td>
+<td class="enum_member_description">
+<p>USB service error</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SPICE-CLIENT-ERROR:CAPS"></a><h3>SPICE_CLIENT_ERROR</h3>
+<pre class="programlisting">#define SPICE_CLIENT_ERROR spice_client_error_quark()
+</pre>
+<p>Error domain for spice client errors.</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceSession.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="SpiceSession--ca"></a><h3>The <code class="literal">“ca”</code> property</h3>
+<pre class="programlisting"> “ca” <a href="/usr/share/gtk-doc/html/glibglib-Byte-Arrays.html#GByteArray"><span class="type">GByteArray</span></a> *</pre>
+<p>CA certificates in PEM format. The text data can contain
+several CA certificates identified by:</p>
+<p> -----BEGIN CERTIFICATE-----
+ ... (CA certificate in base64 encoding) ...
+ -----END CERTIFICATE-----</p>
+<p>Flags: Read / Write</p>
+<p class="since">Since: 0.15</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--ca-file"></a><h3>The <code class="literal">“ca-file”</code> property</h3>
+<pre class="programlisting"> “ca-file” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>File holding the CA certificates for the host the client is
+connecting to</p>
+<p>Flags: Read / Write</p>
+<p>Default value: NULL</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--cache-size"></a><h3>The <code class="literal">“cache-size”</code> property</h3>
+<pre class="programlisting"> “cache-size” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>Images cache size. If 0, don't set.</p>
+<p>Flags: Read / Write</p>
+<p>Allowed values: >= 0</p>
+<p>Default value: 0</p>
+<p class="since">Since: 0.9</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--cert-subject"></a><h3>The <code class="literal">“cert-subject”</code> property</h3>
+<pre class="programlisting"> “cert-subject” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>Certificate subject to check.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: NULL</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--ciphers"></a><h3>The <code class="literal">“ciphers”</code> property</h3>
+<pre class="programlisting"> “ciphers” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>SSL cipher list.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: NULL</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--client-sockets"></a><h3>The <code class="literal">“client-sockets”</code> property</h3>
+<pre class="programlisting"> “client-sockets” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Sockets are provided by the client.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: FALSE</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--color-depth"></a><h3>The <code class="literal">“color-depth”</code> property</h3>
+<pre class="programlisting"> “color-depth” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>Display color depth to set on new display channels. If 0, don't set.</p>
+<p>Flags: Read / Write</p>
+<p>Allowed values: [0,32]</p>
+<p>Default value: 0</p>
+<p class="since">Since: 0.7</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--disable-effects"></a><h3>The <code class="literal">“disable-effects”</code> property</h3>
+<pre class="programlisting"> “disable-effects” <a href="/usr/share/gtk-doc/html/glibglib-String-Utility-Functions.html#GStrv"><span class="type">GStrv</span></a></pre>
+<p>A string array of effects to disable. The settings will
+be applied on new display channels. The following effets can be
+disabled "wallpaper", "font-smooth", "animation", and "all",
+which will disable all the effects. If NULL, don't apply changes.</p>
+<p>Flags: Read / Write</p>
+<p class="since">Since: 0.7</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--enable-audio"></a><h3>The <code class="literal">“enable-audio”</code> property</h3>
+<pre class="programlisting"> “enable-audio” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>If set to TRUE, the audio channels will be enabled for
+playback and recording.</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: TRUE</p>
+<p class="since">Since: 0.8</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--enable-smartcard"></a><h3>The <code class="literal">“enable-smartcard”</code> property</h3>
+<pre class="programlisting"> “enable-smartcard” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>If set to TRUE, the smartcard channel will be enabled and smartcard
+events will be forwarded to the guest</p>
+<p>Flags: Read / Write</p>
+<p>Default value: FALSE</p>
+<p class="since">Since: 0.7</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--enable-usbredir"></a><h3>The <code class="literal">“enable-usbredir”</code> property</h3>
+<pre class="programlisting"> “enable-usbredir” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>If set to TRUE, the usbredir channel will be enabled and USB devices
+can be redirected to the guest</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: TRUE</p>
+<p class="since">Since: 0.8</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--glz-window-size"></a><h3>The <code class="literal">“glz-window-size”</code> property</h3>
+<pre class="programlisting"> “glz-window-size” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>Glz window size. If 0, don't set.</p>
+<p>Flags: Read / Write</p>
+<p>Allowed values: [0,134217728]</p>
+<p>Default value: 0</p>
+<p class="since">Since: 0.9</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--host"></a><h3>The <code class="literal">“host”</code> property</h3>
+<pre class="programlisting"> “host” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>URL of the SPICE host to connect to</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: "localhost"</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--inhibit-keyboard-grab"></a><h3>The <code class="literal">“inhibit-keyboard-grab”</code> property</h3>
+<pre class="programlisting"> “inhibit-keyboard-grab” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Request that SpiceDisplays don't grab the keyboard.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: FALSE</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--migration-state"></a><h3>The <code class="literal">“migration-state”</code> property</h3>
+<pre class="programlisting"> “migration-state” <a class="link" href="SpiceSession.html#SpiceSessionMigration" title="enum SpiceSessionMigration"><span class="type">SpiceSessionMigration</span></a></pre>
+<p><a class="link" href="SpiceSession.html#SpiceSessionMigration" title="enum SpiceSessionMigration"><span class="type">SpiceSessionMigration</span></a> bit field indicating if a migration is in
+progress</p>
+<p>Flags: Read</p>
+<p>Default value: SPICE_SESSION_MIGRATION_NONE</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--name"></a><h3>The <code class="literal">“name”</code> property</h3>
+<pre class="programlisting"> “name” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>Spice server name.</p>
+<p>Flags: Read</p>
+<p>Default value: NULL</p>
+<p class="since">Since: 0.11</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--password"></a><h3>The <code class="literal">“password”</code> property</h3>
+<pre class="programlisting"> “password” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>TLS password to use</p>
+<p>Flags: Read / Write</p>
+<p>Default value: NULL</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--port"></a><h3>The <code class="literal">“port”</code> property</h3>
+<pre class="programlisting"> “port” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>Port to connect to for unencrypted sessions</p>
+<p>Flags: Read / Write</p>
+<p>Default value: NULL</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--preferred-compression"></a><h3>The <code class="literal">“preferred-compression”</code> property</h3>
+<pre class="programlisting"> “preferred-compression” <span class="type">SpiceImageCompress</span></pre>
+<p>The image compression algorithm the client prefers to use. It is
+reported to the server.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: SPICE_IMAGE_COMPRESSION_INVALID</p>
+<p class="since">Since: 0.29</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--protocol"></a><h3>The <code class="literal">“protocol”</code> property</h3>
+<pre class="programlisting"> “protocol” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>Version of the SPICE protocol to use</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Allowed values: [1,2]</p>
+<p>Default value: 2</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--proxy"></a><h3>The <code class="literal">“proxy”</code> property</h3>
+<pre class="programlisting"> “proxy” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>URI to the proxy server to use when doing network connection.
+of the form [protocol://]<host>[:port] </p>
+<p>Flags: Read / Write</p>
+<p>Default value: NULL</p>
+<p class="since">Since: 0.17</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--pubkey"></a><h3>The <code class="literal">“pubkey”</code> property</h3>
+<pre class="programlisting"> “pubkey” <a href="/usr/share/gtk-doc/html/glibglib-Byte-Arrays.html#GByteArray"><span class="type">GByteArray</span></a> *</pre>
+<p>Public key to check.</p>
+<p>Flags: Read / Write</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--read-only"></a><h3>The <code class="literal">“read-only”</code> property</h3>
+<pre class="programlisting"> “read-only” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Whether this connection is read-only mode.</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: FALSE</p>
+<p class="since">Since: 0.8</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--secure-channels"></a><h3>The <code class="literal">“secure-channels”</code> property</h3>
+<pre class="programlisting"> “secure-channels” <a href="/usr/share/gtk-doc/html/glibglib-String-Utility-Functions.html#GStrv"><span class="type">GStrv</span></a></pre>
+<p>A string array of channel types to be secured.</p>
+<p>Flags: Read / Write</p>
+<p class="since">Since: 0.20</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--share-dir-ro"></a><h3>The <code class="literal">“share-dir-ro”</code> property</h3>
+<pre class="programlisting"> “share-dir-ro” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Whether to share the directory read-only.</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: FALSE</p>
+<p class="since">Since: 0.28</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--shared-dir"></a><h3>The <code class="literal">“shared-dir”</code> property</h3>
+<pre class="programlisting"> “shared-dir” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>Location of the shared directory</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: "/home/elmarco/Public"</p>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--smartcard-certificates"></a><h3>The <code class="literal">“smartcard-certificates”</code> property</h3>
+<pre class="programlisting"> “smartcard-certificates” <a href="/usr/share/gtk-doc/html/glibglib-String-Utility-Functions.html#GStrv"><span class="type">GStrv</span></a></pre>
+<p>This property is used when one wants to simulate a smartcard with no
+hardware smartcard reader. If it's set to a NULL-terminated string
+array containing the names of 3 valid certificates, these will be
+used to simulate a smartcard in the guest
+See also <a class="link" href="SpiceSmartcardManager.html#spice-smartcard-manager-insert-card" title="spice_smartcard_manager_insert_card ()"><code class="function">spice_smartcard_manager_insert_card()</code></a></p>
+<p>Flags: Read / Write</p>
+<p class="since">Since: 0.7</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--smartcard-db"></a><h3>The <code class="literal">“smartcard-db”</code> property</h3>
+<pre class="programlisting"> “smartcard-db” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>Path to the NSS certificate database containing the certificates to
+use to simulate a software smartcard</p>
+<p>Flags: Read / Write</p>
+<p>Default value: NULL</p>
+<p class="since">Since: 0.7</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--tls-port"></a><h3>The <code class="literal">“tls-port”</code> property</h3>
+<pre class="programlisting"> “tls-port” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>Port to connect to for TLS sessions</p>
+<p>Flags: Read / Write</p>
+<p>Default value: NULL</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--unix-path"></a><h3>The <code class="literal">“unix-path”</code> property</h3>
+<pre class="programlisting"> “unix-path” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>Path of the Unix socket to connect to</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: NULL</p>
+<p class="since">Since: 0.28</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--uri"></a><h3>The <code class="literal">“uri”</code> property</h3>
+<pre class="programlisting"> “uri” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>URI of the SPICE host to connect to. The URI is of the form
+spice://hostname?port=XXX or spice://hostname?tls_port=XXX</p>
+<p>Flags: Read / Write</p>
+<p>Default value: NULL</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--username"></a><h3>The <code class="literal">“username”</code> property</h3>
+<pre class="programlisting"> “username” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>Username to use</p>
+<p>Flags: Read / Write</p>
+<p>Default value: NULL</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--uuid"></a><h3>The <code class="literal">“uuid”</code> property</h3>
+<pre class="programlisting"> “uuid” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a></pre>
+<p>Spice server uuid.</p>
+<p>Flags: Read</p>
+<p class="since">Since: 0.11</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession--verify"></a><h3>The <code class="literal">“verify”</code> property</h3>
+<pre class="programlisting"> “verify” <a class="link" href="SpiceSession.html#SpiceSessionVerify" title="enum SpiceSessionVerify"><span class="type">SpiceSessionVerify</span></a></pre>
+<p><a class="link" href="SpiceSession.html#SpiceSessionVerify" title="enum SpiceSessionVerify"><span class="type">SpiceSessionVerify</span></a> bit field indicating which parts of the peer
+certificate should be checked</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: SPICE_SESSION_VERIFY_HOSTNAME</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceSession.signal-details"></a><h2>Signal Details</h2>
+<div class="refsect2">
+<a name="SpiceSession-channel-destroy"></a><h3>The <code class="literal">“channel-destroy”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session,
+ <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceSession.html#SpiceSession-channel-destroy" title="The “channel-destroy” signal"><span class="type">“channel-destroy”</span></a> signal is emitted each time a <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> is destroyed.</p>
+<div class="refsect3">
+<a name="SpiceSession-channel-destroy.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>the session that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>the destroyed <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession-channel-new"></a><h3>The <code class="literal">“channel-new”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session,
+ <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> *channel,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceSession.html#SpiceSession-channel-new" title="The “channel-new” signal"><span class="type">“channel-new”</span></a> signal is emitted each time a <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a> is created.</p>
+<div class="refsect3">
+<a name="SpiceSession-channel-new.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>the session that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>channel</p></td>
+<td class="parameter_description"><p>the new <a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSession-mm-time-reset"></a><h3>The <code class="literal">“mm-time-reset”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceSession.html#SpiceSession-mm-time-reset" title="The “mm-time-reset” signal"><span class="type">“mm-time-reset”</span></a> is emitted when we identify discontinuity in mm-time</p>
+<p>Since 0.20</p>
+<div class="refsect3">
+<a name="SpiceSession-mm-time-reset.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>the session that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceSession.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a>, and the GTK widget <span class="type">SpiceDisplay</span></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Smartcard Channel: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="prev" href="SpiceRecordChannel.html" title="Record Channel">
+<link rel="next" href="SpiceUsbredirChannel.html" title="USB Redirection Channel">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceSmartcardChannel.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceSmartcardChannel.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceRecordChannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceUsbredirChannel.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceSmartcardChannel"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceSmartcardChannel.top_of_page"></a>Smartcard Channel</span></h2>
+<p>Smartcard Channel — smartcard authentication</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceSmartcardChannel.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardChannel.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceSmartcardChannel.html#SpiceSmartcardChannel-struct" title="struct SpiceSmartcardChannel">SpiceSmartcardChannel</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceSmartcardChannel.html#SpiceSmartcardChannelClass" title="struct SpiceSmartcardChannelClass">SpiceSmartcardChannelClass</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardChannel.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+ <span class="lineart">╰──</span> SpiceSmartcardChannel
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardChannel.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardChannel.description"></a><h2>Description</h2>
+<p>The Spice protocol defines a set of messages to forward smartcard
+information from the Spice client to the VM. This channel handles
+these messages. While it's mainly focus on smartcard readers and
+smartcards, it's also possible to use it with a software smartcard
+(ie a set of 3 certificates from the client machine).
+This class doesn't provide useful methods, see <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> properties
+for a way to enable/disable this channel, and <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a>
+if you want to detect smartcard reader hotplug/unplug, and smartcard
+insertion/removal.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardChannel.functions_details"></a><h2>Functions</h2>
+<p></p>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardChannel.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceSmartcardChannel-struct"></a><h3>struct SpiceSmartcardChannel</h3>
+<pre class="programlisting">struct SpiceSmartcardChannel;</pre>
+<p>The <a class="link" href="SpiceSmartcardChannel.html" title="Smartcard Channel"><span class="type">SpiceSmartcardChannel</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSmartcardChannelClass"></a><h3>struct SpiceSmartcardChannelClass</h3>
+<pre class="programlisting">struct SpiceSmartcardChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+};
+</pre>
+<p>Class structure for <a class="link" href="SpiceSmartcardChannel.html" title="Smartcard Channel"><span class="type">SpiceSmartcardChannel</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceSmartcardChannelClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody></tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardChannel.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a>, <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Spice Smartcard Manager: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="application-support.html" title="Application Support, from spice-client-glib">
+<link rel="prev" href="SpiceAudio.html" title="Spice Audio">
+<link rel="next" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceSmartcardManager.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceSmartcardManager.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_signals"> <span class="dim">|</span>
+ <a href="#SpiceSmartcardManager.signals" class="shortcut">Signals</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="application-support.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceAudio.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceUsbDeviceManager.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceSmartcardManager"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceSmartcardManager.top_of_page"></a>Spice Smartcard Manager</span></h2>
+<p>Spice Smartcard Manager — smartcard management</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceSmartcardManager.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardManager.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="returnvalue">SpiceSmartcardManager</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-manager-get" title="spice_smartcard_manager_get ()">spice_smartcard_manager_get</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Doubly-Linked-Lists.html#GList"><span class="returnvalue">GList</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-manager-get-readers" title="spice_smartcard_manager_get_readers ()">spice_smartcard_manager_get_readers</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-manager-insert-card" title="spice_smartcard_manager_insert_card ()">spice_smartcard_manager_insert_card</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-manager-remove-card" title="spice_smartcard_manager_remove_card ()">spice_smartcard_manager_remove_card</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-reader-is-software" title="spice_smartcard_reader_is_software ()">spice_smartcard_reader_is_software</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-reader-insert-card" title="spice_smartcard_reader_insert_card ()">spice_smartcard_reader_insert_card</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-reader-remove-card" title="spice_smartcard_reader_remove_card ()">spice_smartcard_reader_remove_card</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardManager.signals"></a><h2>Signals</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="signals_return">
+<col width="300px" class="signals_name">
+<col width="200px" class="signals_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-card-inserted" title="The “card-inserted” signal">card-inserted</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-card-removed" title="The “card-removed” signal">card-removed</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-reader-added" title="The “reader-added” signal">reader-added</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-reader-removed" title="The “reader-removed” signal">reader-removed</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardManager.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-struct" title="struct SpiceSmartcardManager">SpiceSmartcardManager</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManagerClass" title="struct SpiceSmartcardManagerClass">SpiceSmartcardManagerClass</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword"> </td>
+<td class="function_name"><a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardReader" title="SpiceSmartcardReader">SpiceSmartcardReader</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardManager.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> SpiceSmartcardManager
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardManager.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardManager.description"></a><h2>Description</h2>
+<p><a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> monitors smartcard reader plugging/unplugging,
+and smartcard insertions/removals. It also provides methods to handle
+software smartcards (to emulate a smartcard reader/smartcard on the
+guest using 3 certificates available to the client).</p>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardManager.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-smartcard-manager-get"></a><h3>spice_smartcard_manager_get ()</h3>
+<pre class="programlisting"><a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="returnvalue">SpiceSmartcardManager</span></a> *
+spice_smartcard_manager_get (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p><a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> is a singleton, use this function to get a pointer
+to it. A new SpiceSmartcardManager instance will be created the first
+time this function is called</p>
+<div class="refsect3">
+<a name="spice-smartcard-manager-get.returns"></a><h4>Returns</h4>
+<p> a weak reference to the <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a>. </p>
+<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-smartcard-manager-get-readers"></a><h3>spice_smartcard_manager_get_readers ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Doubly-Linked-Lists.html#GList"><span class="returnvalue">GList</span></a> *
+spice_smartcard_manager_get_readers (<em class="parameter"><code><a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> *manager</code></em>);</pre>
+<p>Gets the list of smartcard readers that are currently available, they
+can be either software (emulated) readers, or hardware ones.</p>
+<div class="refsect3">
+<a name="spice-smartcard-manager-get-readers.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-smartcard-manager-get-readers.returns"></a><h4>Returns</h4>
+<p> a newly
+allocated list of SpiceSmartcardReader instances, or NULL if none were
+found. When no longer needed, the list must be freed after unreferencing
+its elements with <a href="/usr/share/gtk-doc/html/gobjectgobject-Boxed-Types.html#g-boxed-free"><code class="function">g_boxed_free()</code></a>. </p>
+<p><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> SpiceSmartcardReader][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
+</div>
+<p class="since">Since: 0.20</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-smartcard-manager-insert-card"></a><h3>spice_smartcard_manager_insert_card ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_smartcard_manager_insert_card (<em class="parameter"><code><a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> *manager</code></em>);</pre>
+<p>Simulates the insertion of a smartcard in the guest. Valid certificates
+must have been set in <a class="link" href="SpiceSession.html#SpiceSession--smartcard-certificates" title="The “smartcard-certificates” property"><span class="type">“smartcard-certificates”</span></a> for software
+smartcard support to work. At the moment, only one software smartcard
+reader is supported, that's why there is no parameter to indicate which
+reader to insert the card in.</p>
+<div class="refsect3">
+<a name="spice-smartcard-manager-insert-card.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-smartcard-manager-insert-card.returns"></a><h4>Returns</h4>
+<p> TRUE if smartcard insertion was successfully simulated, FALSE
+if this failed, or if software smartcard support isn't enabled.</p>
+</div>
+<p class="since">Since: 0.20</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-smartcard-manager-remove-card"></a><h3>spice_smartcard_manager_remove_card ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_smartcard_manager_remove_card (<em class="parameter"><code><a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> *manager</code></em>);</pre>
+<p>Simulates the removal of a smartcard in the guest. At the moment, only
+one software smartcard reader is supported, that's why there is no
+parameter to indicate which reader to insert the card in.</p>
+<div class="refsect3">
+<a name="spice-smartcard-manager-remove-card.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-smartcard-manager-remove-card.returns"></a><h4>Returns</h4>
+<p> TRUE if smartcard removal was successfully simulated, FALSE
+if this failed, or if software smartcard support isn't enabled.</p>
+</div>
+<p class="since">Since: 0.20</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-smartcard-reader-is-software"></a><h3>spice_smartcard_reader_is_software ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_smartcard_reader_is_software (<em class="parameter"><code><a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardReader" title="SpiceSmartcardReader"><span class="type">SpiceSmartcardReader</span></a> *reader</code></em>);</pre>
+<p>Tests if <em class="parameter"><code>reader</code></em>
+ is a software (emulated) smartcard reader.</p>
+<div class="refsect3">
+<a name="spice-smartcard-reader-is-software.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>reader</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardReader" title="SpiceSmartcardReader"><span class="type">SpiceSmartcardReader</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-smartcard-reader-is-software.returns"></a><h4>Returns</h4>
+<p> TRUE if <em class="parameter"><code>reader</code></em>
+is a software (emulated) smartcard reader,
+FALSE otherwise</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-smartcard-reader-insert-card"></a><h3>spice_smartcard_reader_insert_card ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_smartcard_reader_insert_card (<em class="parameter"><code><a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardReader" title="SpiceSmartcardReader"><span class="type">SpiceSmartcardReader</span></a> *reader</code></em>);</pre>
+<p>Simulates insertion of a smartcard in the software smartcard reader
+<em class="parameter"><code>reader</code></em>
+. If <em class="parameter"><code>reader</code></em>
+ is not a software smartcard reader, FALSE will be
+returned.</p>
+<div class="refsect3">
+<a name="spice-smartcard-reader-insert-card.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>reader</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardReader" title="SpiceSmartcardReader"><span class="type">SpiceSmartcardReader</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-smartcard-reader-insert-card.returns"></a><h4>Returns</h4>
+<p> TRUE if insertion of a card was successfully simulated, FALSE
+otherwise</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-smartcard-reader-remove-card"></a><h3>spice_smartcard_reader_remove_card ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_smartcard_reader_remove_card (<em class="parameter"><code><a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardReader" title="SpiceSmartcardReader"><span class="type">SpiceSmartcardReader</span></a> *reader</code></em>);</pre>
+<p>Simulates removal of a smartcard from the software smartcard reader
+<em class="parameter"><code>reader</code></em>
+. If <em class="parameter"><code>reader</code></em>
+ is not a software smartcard reader, FALSE will be
+returned.</p>
+<div class="refsect3">
+<a name="spice-smartcard-reader-remove-card.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>reader</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardReader" title="SpiceSmartcardReader"><span class="type">SpiceSmartcardReader</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-smartcard-reader-remove-card.returns"></a><h4>Returns</h4>
+<p> TRUE if removal of a card was successfully simulated, FALSE
+otherwise</p>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardManager.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceSmartcardManager-struct"></a><h3>struct SpiceSmartcardManager</h3>
+<pre class="programlisting">struct SpiceSmartcardManager;</pre>
+<p>The <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSmartcardManagerClass"></a><h3>struct SpiceSmartcardManagerClass</h3>
+<pre class="programlisting">struct SpiceSmartcardManagerClass {
+ GObjectClass parent_class;
+ /* signals */
+ void (*reader_added)(SpiceSmartcardManager *manager, SpiceSmartcardReader *reader);
+ void (*reader_removed)(SpiceSmartcardManager *manager, SpiceSmartcardReader *reader);
+ void (*card_inserted)(SpiceSmartcardManager *manager, SpiceSmartcardReader *reader);
+ void (*card_removed)(SpiceSmartcardManager *manager, SpiceSmartcardReader *reader );
+};
+</pre>
+<p>Class structure for <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceSmartcardManagerClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceSmartcardManagerClass.reader-added"></a>reader_added</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-reader-added" title="The “reader-added” signal"><span class="type">“reader_added”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceSmartcardManagerClass.reader-removed"></a>reader_removed</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-reader-removed" title="The “reader-removed” signal"><span class="type">“reader_removed”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceSmartcardManagerClass.card-inserted"></a>card_inserted</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-card-inserted" title="The “card-inserted” signal"><span class="type">“card_inserted”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceSmartcardManagerClass.card-removed"></a>card_removed</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-card-removed" title="The “card-removed” signal"><span class="type">“card_removed”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSmartcardReader"></a><h3>SpiceSmartcardReader</h3>
+<pre class="programlisting">typedef struct _SpiceSmartcardReader SpiceSmartcardReader;</pre>
+<p>The <a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardReader" title="SpiceSmartcardReader"><span class="type">SpiceSmartcardReader</span></a> struct is opaque and cannot be accessed directly.</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceSmartcardManager.signal-details"></a><h2>Signal Details</h2>
+<div class="refsect2">
+<a name="SpiceSmartcardManager-card-inserted"></a><h3>The <code class="literal">“card-inserted”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> *manager,
+ <span class="type">VReader</span> *vreader,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-card-inserted" title="The “card-inserted” signal"><span class="type">“card-inserted”</span></a> signal is emitted whenever
+a smartcard is inserted in a reader</p>
+<div class="refsect3">
+<a name="SpiceSmartcardManager-card-inserted.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>vreader</p></td>
+<td class="parameter_description"><p><span class="type">VReader</span> boxed object corresponding to the reader a new
+card was inserted in</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSmartcardManager-card-removed"></a><h3>The <code class="literal">“card-removed”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> *manager,
+ <span class="type">VReader</span> *vreader,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-card-removed" title="The “card-removed” signal"><span class="type">“card-removed”</span></a> signal is emitted whenever
+a smartcard was removed from a reader.</p>
+<div class="refsect3">
+<a name="SpiceSmartcardManager-card-removed.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>vreader</p></td>
+<td class="parameter_description"><p><span class="type">VReader</span> boxed object corresponding to the reader a card
+was removed from</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSmartcardManager-reader-added"></a><h3>The <code class="literal">“reader-added”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> *manager,
+ <span class="type">VReader</span> *vreader,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-reader-added" title="The “reader-added” signal"><span class="type">“reader-added”</span></a> signal is emitted whenever
+a new smartcard reader (software or hardware) has been plugged in.</p>
+<div class="refsect3">
+<a name="SpiceSmartcardManager-reader-added.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>vreader</p></td>
+<td class="parameter_description"><p><span class="type">VReader</span> boxed object corresponding to the added reader</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceSmartcardManager-reader-removed"></a><h3>The <code class="literal">“reader-removed”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> *manager,
+ <span class="type">VReader</span> *vreader,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-reader-removed" title="The “reader-removed” signal"><span class="type">“reader-removed”</span></a> signal is emitted whenever
+a smartcard reader (software or hardware) has been removed.</p>
+<div class="refsect3">
+<a name="SpiceSmartcardManager-reader-removed.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager"><span class="type">SpiceSmartcardManager</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>vreader</p></td>
+<td class="parameter_description"><p><span class="type">VReader</span> boxed object corresponding to the removed reader</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Spice USB Manager: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="application-support.html" title="Application Support, from spice-client-glib">
+<link rel="prev" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">
+<link rel="next" href="spice-gtk-Utilities.html" title="Utilities">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceUsbDeviceManager.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceUsbDeviceManager.object-hierarchy" class="shortcut">Object Hierarchy</a></span><span id="nav_interfaces"> <span class="dim">|</span>
+ <a href="#SpiceUsbDeviceManager.implemented-interfaces" class="shortcut">Implemented Interfaces</a></span><span id="nav_properties"> <span class="dim">|</span>
+ <a href="#SpiceUsbDeviceManager.properties" class="shortcut">Properties</a></span><span id="nav_signals"> <span class="dim">|</span>
+ <a href="#SpiceUsbDeviceManager.signals" class="shortcut">Signals</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="application-support.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceSmartcardManager.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="spice-gtk-Utilities.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceUsbDeviceManager"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceUsbDeviceManager.top_of_page"></a>Spice USB Manager</span></h2>
+<p>Spice USB Manager — USB device management</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceUsbDeviceManager.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceUsbDeviceManager.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="returnvalue">SpiceUsbDeviceManager</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-get" title="spice_usb_device_manager_get ()">spice_usb_device_manager_get</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Pointer-Arrays.html#GPtrArray"><span class="returnvalue">GPtrArray</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-get-devices" title="spice_usb_device_manager_get_devices ()">spice_usb_device_manager_get_devices</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Pointer-Arrays.html#GPtrArray"><span class="returnvalue">GPtrArray</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-get-devices-with-filter" title="spice_usb_device_manager_get_devices_with_filter ()">spice_usb_device_manager_get_devices_with_filter</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-is-device-connected" title="spice_usb_device_manager_is_device_connected ()">spice_usb_device_manager_is_device_connected</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-is-redirecting" title="spice_usb_device_manager_is_redirecting ()">spice_usb_device_manager_is_redirecting</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-can-redirect-device" title="spice_usb_device_manager_can_redirect_device ()">spice_usb_device_manager_can_redirect_device</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-connect-device-async" title="spice_usb_device_manager_connect_device_async ()">spice_usb_device_manager_connect_device_async</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-connect-device-finish" title="spice_usb_device_manager_connect_device_finish ()">spice_usb_device_manager_connect_device_finish</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-disconnect-device" title="spice_usb_device_manager_disconnect_device ()">spice_usb_device_manager_disconnect_device</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-disconnect-device-async" title="spice_usb_device_manager_disconnect_device_async ()">spice_usb_device_manager_disconnect_device_async</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-disconnect-device-finish" title="spice_usb_device_manager_disconnect_device_finish ()">spice_usb_device_manager_disconnect_device_finish</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-get-description" title="spice_usb_device_get_description ()">spice_usb_device_get_description</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gconstpointer"><span class="returnvalue">gconstpointer</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-get-libusb-device" title="spice_usb_device_get_libusb_device ()">spice_usb_device_get_libusb_device</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbDeviceManager.properties"></a><h2>Properties</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="properties_type">
+<col width="300px" class="properties_name">
+<col width="200px" class="properties_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></td>
+<td class="property_name"><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--auto-connect" title="The “auto-connect” property">auto-connect</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--auto-connect-filter" title="The “auto-connect-filter” property">auto-connect-filter</a></td>
+<td class="property_flags">Read / Write / Construct</td>
+</tr>
+<tr>
+<td class="property_type"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></td>
+<td class="property_name"><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--free-channels" title="The “free-channels” property">free-channels</a></td>
+<td class="property_flags">Read</td>
+</tr>
+<tr>
+<td class="property_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--redirect-on-connect" title="The “redirect-on-connect” property">redirect-on-connect</a></td>
+<td class="property_flags">Read / Write</td>
+</tr>
+<tr>
+<td class="property_type">
+<a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *</td>
+<td class="property_name"><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--session" title="The “session” property">session</a></td>
+<td class="property_flags">Read / Write / Construct Only</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbDeviceManager.signals"></a><h2>Signals</h2>
+<div class="informaltable"><table border="0">
+<colgroup>
+<col width="150px" class="signals_return">
+<col width="300px" class="signals_name">
+<col width="200px" class="signals_flags">
+</colgroup>
+<tbody>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-auto-connect-failed" title="The “auto-connect-failed” signal">auto-connect-failed</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-added" title="The “device-added” signal">device-added</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-error" title="The “device-error” signal">device-error</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+<tr>
+<td class="signal_type"><span class="returnvalue">void</span></td>
+<td class="signal_name"><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-removed" title="The “device-removed” signal">device-removed</a></td>
+<td class="signal_flags"><a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<a name="SpiceUsbDevice"></a><div class="refsect1">
+<a name="SpiceUsbDeviceManager.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-struct" title="struct SpiceUsbDeviceManager">SpiceUsbDeviceManager</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManagerClass" title="struct SpiceUsbDeviceManagerClass">SpiceUsbDeviceManagerClass</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword"> </td>
+<td class="function_name"><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice-struct" title="SpiceUsbDevice">SpiceUsbDevice</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbDeviceManager.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="https://developer.gnome.org/gobject/unstable/gobject-Boxed-Types.html">GBoxed</a>
+ <span class="lineart">╰──</span> SpiceUsbDevice
+ <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> SpiceUsbDeviceManager
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbDeviceManager.implemented-interfaces"></a><h2>Implemented Interfaces</h2>
+<p>
+SpiceUsbDeviceManager implements
+ <a href="/usr/share/gtk-doc/html/gioGInitable.html#GInitable-struct">GInitable</a>.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbDeviceManager.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbDeviceManager.description"></a><h2>Description</h2>
+<p><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> monitors USB redirection channels and USB
+devices plugging/unplugging. If <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--auto-connect" title="The “auto-connect” property"><span class="type">“auto-connect”</span></a>
+is set to <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a>, it will automatically connect newly plugged USB
+devices to available channels.</p>
+<p>There should always be a 1:1 relation between <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> objects
+and <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> objects. Therefor there is no
+spice_usb_device_manager_new, instead there is
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-get" title="spice_usb_device_manager_get ()"><code class="function">spice_usb_device_manager_get()</code></a> which ensures this 1:1 relation.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbDeviceManager.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-usb-device-manager-get"></a><h3>spice_usb_device_manager_get ()</h3>
+<pre class="programlisting"><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="returnvalue">SpiceUsbDeviceManager</span></a> *
+spice_usb_device_manager_get (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> **err</code></em>);</pre>
+<p>Gets the <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> associated with the passed in <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a>.
+A new <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> instance will be created the first time this
+function is called for a certain <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a>.</p>
+<p>Note that this function returns a weak reference, which should not be used
+after the <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> itself has been unref-ed by the caller.</p>
+<div class="refsect3">
+<a name="spice-usb-device-manager-get.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> for which to get the <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>err</p></td>
+<td class="parameter_description"><p> a return location for <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a>, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-usb-device-manager-get.returns"></a><h4>Returns</h4>
+<p> a weak reference to the <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> associated with the passed in <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a>. </p>
+<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-usb-device-manager-get-devices"></a><h3>spice_usb_device_manager_get_devices ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Pointer-Arrays.html#GPtrArray"><span class="returnvalue">GPtrArray</span></a> *
+spice_usb_device_manager_get_devices (<em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *manager</code></em>);</pre>
+<p>Finds devices associated with the <em class="parameter"><code>manager</code></em>
+</p>
+<div class="refsect3">
+<a name="spice-usb-device-manager-get-devices.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> manager</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-usb-device-manager-get-devices.returns"></a><h4>Returns</h4>
+<p> a <a href="/usr/share/gtk-doc/html/glibglib-Pointer-Arrays.html#GPtrArray"><code class="literal">GPtrArray</code></a> array of <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><code class="literal">SpiceUsbDevice</code></a>. </p>
+<p><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> SpiceUsbDevice][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-usb-device-manager-get-devices-with-filter"></a><h3>spice_usb_device_manager_get_devices_with_filter ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Pointer-Arrays.html#GPtrArray"><span class="returnvalue">GPtrArray</span></a> *
+spice_usb_device_manager_get_devices_with_filter
+ (<em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *manager</code></em>,
+ <em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *filter</code></em>);</pre>
+<p>Finds devices associated with the <em class="parameter"><code>manager</code></em>
+ complying with the <em class="parameter"><code>filter</code></em>
+</p>
+<div class="refsect3">
+<a name="spice-usb-device-manager-get-devices-with-filter.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> manager</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>filter</p></td>
+<td class="parameter_description"><p> filter string for selecting which devices to return,
+see <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--auto-connect-filter" title="The “auto-connect-filter” property"><span class="type">“auto-connect-filter”</span></a> for the filter
+string format. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-usb-device-manager-get-devices-with-filter.returns"></a><h4>Returns</h4>
+<p> a
+<a href="/usr/share/gtk-doc/html/glibglib-Pointer-Arrays.html#GPtrArray"><code class="literal">GPtrArray</code></a> array of <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><code class="literal">SpiceUsbDevice</code></a>. </p>
+<p><span class="annotation">[<acronym title="Generics and defining elements of containers and arrays."><span class="acronym">element-type</span></acronym> SpiceUsbDevice][<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
+</div>
+<p class="since">Since: 0.20</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-usb-device-manager-is-device-connected"></a><h3>spice_usb_device_manager_is_device_connected ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_usb_device_manager_is_device_connected
+ (<em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *manager</code></em>,
+ <em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> *device</code></em>);</pre>
+<p>Finds if the <em class="parameter"><code>device</code></em>
+ is connected.</p>
+<div class="refsect3">
+<a name="spice-usb-device-manager-is-device-connected.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> manager</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>device</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-usb-device-manager-is-device-connected.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if <em class="parameter"><code>device</code></em>
+has an associated USB redirection channel</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-usb-device-manager-is-redirecting"></a><h3>spice_usb_device_manager_is_redirecting ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_usb_device_manager_is_redirecting
+ (<em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *self</code></em>);</pre>
+<p>Checks whether a device is being redirected</p>
+<div class="refsect3">
+<a name="spice-usb-device-manager-is-redirecting.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> manager</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-usb-device-manager-is-redirecting.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if device redirection negotiation flow is in progress</p>
+</div>
+<p class="since">Since: 0.32</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-usb-device-manager-can-redirect-device"></a><h3>spice_usb_device_manager_can_redirect_device ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_usb_device_manager_can_redirect_device
+ (<em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *self</code></em>,
+ <em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> *device</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> **err</code></em>);</pre>
+<p>Checks whether it is possible to redirect the <em class="parameter"><code>device</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-usb-device-manager-can-redirect-device.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> manager</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>device</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> to disconnect</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>err</p></td>
+<td class="parameter_description"><p> a return location for a <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a>, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-usb-device-manager-can-redirect-device.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if <em class="parameter"><code>device</code></em>
+can be redirected</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-usb-device-manager-connect-device-async"></a><h3>spice_usb_device_manager_connect_device_async ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_usb_device_manager_connect_device_async
+ (<em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *self</code></em>,
+ <em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> *device</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGCancellable.html#GCancellable-struct"><span class="type">GCancellable</span></a> *cancellable</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncReadyCallback"><span class="type">GAsyncReadyCallback</span></a> callback</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data</code></em>);</pre>
+<p>Asynchronously connects the <em class="parameter"><code>device</code></em>
+. When completed, <em class="parameter"><code>callback</code></em>
+ will be called.
+Then it is possible to call <a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-connect-device-finish" title="spice_usb_device_manager_connect_device_finish ()"><code class="function">spice_usb_device_manager_connect_device_finish()</code></a>
+to get the result of the operation.</p>
+<div class="refsect3">
+<a name="spice-usb-device-manager-connect-device-async.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a>.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>device</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> to redirect</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>cancellable</p></td>
+<td class="parameter_description"><p> optional <a href="/usr/share/gtk-doc/html/gioGCancellable.html#GCancellable-struct"><span class="type">GCancellable</span></a> object, <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> to ignore. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>callback</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncReadyCallback"><span class="type">GAsyncReadyCallback</span></a> to call when the request is satisfied</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>the data to pass to callback function</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-usb-device-manager-connect-device-finish"></a><h3>spice_usb_device_manager_connect_device_finish ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_usb_device_manager_connect_device_finish
+ (<em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *self</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncResult-struct"><span class="type">GAsyncResult</span></a> *res</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> **err</code></em>);</pre>
+<p>Finishes an async operation. See <a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-connect-device-async" title="spice_usb_device_manager_connect_device_async ()"><code class="function">spice_usb_device_manager_connect_device_async()</code></a>.</p>
+<div class="refsect3">
+<a name="spice-usb-device-manager-connect-device-finish.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a>.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>res</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncResult-struct"><span class="type">GAsyncResult</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>err</p></td>
+<td class="parameter_description"><p> a return location for a <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a>, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-usb-device-manager-connect-device-finish.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if connection is successful</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-usb-device-manager-disconnect-device"></a><h3>spice_usb_device_manager_disconnect_device ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_usb_device_manager_disconnect_device
+ (<em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *manager</code></em>,
+ <em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> *device</code></em>);</pre>
+<div class="warning"><p><code class="literal">spice_usb_device_manager_disconnect_device</code> is deprecated and should not be used in newly-written code.</p></div>
+<p>Disconnects the <em class="parameter"><code>device</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-usb-device-manager-disconnect-device.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> manager</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>device</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> to disconnect</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-usb-device-manager-disconnect-device-async"></a><h3>spice_usb_device_manager_disconnect_device_async ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_usb_device_manager_disconnect_device_async
+ (<em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *manager</code></em>,
+ <em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> *device</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGCancellable.html#GCancellable-struct"><span class="type">GCancellable</span></a> *cancellable</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncReadyCallback"><span class="type">GAsyncReadyCallback</span></a> callback</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data</code></em>);</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-usb-device-manager-disconnect-device-finish"></a><h3>spice_usb_device_manager_disconnect_device_finish ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="returnvalue">gboolean</span></a>
+spice_usb_device_manager_disconnect_device_finish
+ (<em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *self</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncResult-struct"><span class="type">GAsyncResult</span></a> *res</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> **err</code></em>);</pre>
+<p>Finishes an async operation. See <a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-disconnect-device-async" title="spice_usb_device_manager_disconnect_device_async ()"><code class="function">spice_usb_device_manager_disconnect_device_async()</code></a>.</p>
+<div class="refsect3">
+<a name="spice-usb-device-manager-disconnect-device-finish.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a>.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>res</p></td>
+<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/gioGAsyncResult.html#GAsyncResult-struct"><span class="type">GAsyncResult</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>err</p></td>
+<td class="parameter_description"><p> a return location for a <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a>, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-usb-device-manager-disconnect-device-finish.returns"></a><h4>Returns</h4>
+<p> <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if disconnection is successful</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-usb-device-get-description"></a><h3>spice_usb_device_get_description ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+spice_usb_device_get_description (<em class="parameter"><code><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> *device</code></em>,
+ <em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *format</code></em>);</pre>
+<p>Get a string describing the device which is suitable as a description of
+the device for the end user. The returned string should be freed with
+<a href="/usr/share/gtk-doc/html/glibglib-Memory-Allocation.html#g-free"><code class="function">g_free()</code></a> when no longer needed.</p>
+<p>The <em class="parameter"><code>format</code></em>
+ positional parameters are the following:</p>
+<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
+<li class="listitem"><p>'%<code class="literal">1</code>$s' manufacturer</p></li>
+<li class="listitem"><p>'%<code class="literal">2</code>$s' product</p></li>
+<li class="listitem"><p>'%<code class="literal">3</code>$s' descriptor (a [vendor_id:product_id] string)</p></li>
+<li class="listitem"><p>'%<code class="literal">4</code>$d' bus</p></li>
+<li class="listitem"><p>'%<code class="literal">5</code>$d' address</p></li>
+</ul></div>
+<p>(the default format string is "%<code class="literal">s</code> %<code class="literal">s</code> %<code class="literal">s</code> at %<code class="literal">d</code>-%<code class="literal">d</code>")</p>
+<div class="refsect3">
+<a name="spice-usb-device-get-description.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>device</p></td>
+<td class="parameter_description"><p><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> to get the description of</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>format</p></td>
+<td class="parameter_description"><p> an optional <code class="function">printf()</code> format string with
+positional parameters. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-usb-device-get-description.returns"></a><h4>Returns</h4>
+<p> a newly-allocated string holding the description, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if failed</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-usb-device-get-libusb-device"></a><h3>spice_usb_device_get_libusb_device ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gconstpointer"><span class="returnvalue">gconstpointer</span></a>
+spice_usb_device_get_libusb_device (<em class="parameter"><code>const <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> *device</code></em>);</pre>
+<p>Finds the <code class="literal">libusb_device</code> associated with the <em class="parameter"><code>device</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-usb-device-get-libusb-device.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>device</p></td>
+<td class="parameter_description"><p><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> to get the descriptor information of</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-usb-device-get-libusb-device.returns"></a><h4>Returns</h4>
+<p> the <code class="literal">libusb_device</code> associated to <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><code class="literal">SpiceUsbDevice</code></a>. </p>
+<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p>
+</div>
+<p class="since">Since: 0.27</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbDeviceManager.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceUsbDeviceManager-struct"></a><h3>struct SpiceUsbDeviceManager</h3>
+<pre class="programlisting">struct SpiceUsbDeviceManager;</pre>
+<p>The <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceUsbDeviceManagerClass"></a><h3>struct SpiceUsbDeviceManagerClass</h3>
+<pre class="programlisting">struct SpiceUsbDeviceManagerClass {
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*device_added) (SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device);
+ void (*device_removed) (SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device);
+ void (*auto_connect_failed) (SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device, GError *error);
+ void (*device_error) (SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device, GError *error);
+};
+</pre>
+<p>Class structure for <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceUsbDeviceManagerClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceUsbDeviceManagerClass.device-added"></a>device_added</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-added" title="The “device-added” signal"><span class="type">“device-added”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceUsbDeviceManagerClass.device-removed"></a>device_removed</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-removed" title="The “device-removed” signal"><span class="type">“device-removed”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceUsbDeviceManagerClass.auto-connect-failed"></a>auto_connect_failed</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-auto-connect-failed" title="The “auto-connect-failed” signal"><span class="type">“auto-connect-failed”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><em class="structfield"><code><a name="SpiceUsbDeviceManagerClass.device-error"></a>device_error</code></em> ()</p></td>
+<td class="struct_member_description"><p>Signal class handler for the <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-error" title="The “device-error” signal"><span class="type">“device_error”</span></a> signal.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceUsbDevice-struct"></a><h3>SpiceUsbDevice</h3>
+<pre class="programlisting">typedef struct _SpiceUsbDevice SpiceUsbDevice;</pre>
+<p>The <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> struct is opaque and cannot be accessed directly.</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbDeviceManager.property-details"></a><h2>Property Details</h2>
+<div class="refsect2">
+<a name="SpiceUsbDeviceManager--auto-connect"></a><h3>The <code class="literal">“auto-connect”</code> property</h3>
+<pre class="programlisting"> “auto-connect” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a></pre>
+<p>Set this to TRUE to automatically redirect newly plugged in device.</p>
+<p>Note when <span class="type">SpiceGtkSession</span>'s auto-usbredir property is TRUE, this
+property is controlled by <span class="type">SpiceGtkSession</span>.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: FALSE</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceUsbDeviceManager--auto-connect-filter"></a><h3>The <code class="literal">“auto-connect-filter”</code> property</h3>
+<pre class="programlisting"> “auto-connect-filter” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>Set a string specifying a filter to use to determine which USB devices
+to autoconnect when plugged in, a filter consists of one or more rules.
+Where each rule has the form of:</p>
+<p><em class="parameter"><code>class</code></em>
+,<em class="parameter"><code>vendor</code></em>
+,<em class="parameter"><code>product</code></em>
+,<em class="parameter"><code>version</code></em>
+,<em class="parameter"><code>allow</code></em>
+</p>
+<p>Use -1 for <em class="parameter"><code>class</code></em>
+/<em class="parameter"><code>vendor</code></em>
+/<em class="parameter"><code>product</code></em>
+/<em class="parameter"><code>version</code></em>
+ to accept any value.</p>
+<p>And the rules themselves are concatenated like this:</p>
+<p><em class="parameter"><code>rule1</code></em>
+|<em class="parameter"><code>rule2</code></em>
+|<em class="parameter"><code>rule3</code></em>
+</p>
+<p>The default setting filters out HID (class 0x03) USB devices from auto
+connect and auto connects anything else. Note the explicit allow rule at
+the end, this is necessary since by default all devices without a
+matching filter rule will not auto-connect.</p>
+<p>Filter strings in this format can be easily created with the RHEV-M
+USB filter editor tool.</p>
+<p>Flags: Read / Write / Construct</p>
+<p>Default value: "0x03,-1,-1,-1,0|-1,-1,-1,-1,1"</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceUsbDeviceManager--free-channels"></a><h3>The <code class="literal">“free-channels”</code> property</h3>
+<pre class="programlisting"> “free-channels” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a></pre>
+<p>The number of available channels for redirecting USB devices.</p>
+<p>Flags: Read</p>
+<p>Allowed values: >= 0</p>
+<p>Default value: 0</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceUsbDeviceManager--redirect-on-connect"></a><h3>The <code class="literal">“redirect-on-connect”</code> property</h3>
+<pre class="programlisting"> “redirect-on-connect” <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *</pre>
+<p>Set a string specifying a filter selecting USB devices to automatically
+redirect after a Spice connection has been established.</p>
+<p>See <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--auto-connect-filter" title="The “auto-connect-filter” property"><span class="type">“auto-connect-filter”</span></a> for the filter string
+format.</p>
+<p>Flags: Read / Write</p>
+<p>Default value: NULL</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceUsbDeviceManager--session"></a><h3>The <code class="literal">“session”</code> property</h3>
+<pre class="programlisting"> “session” <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *</pre>
+<p><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> this <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> is associated with</p>
+<p>Flags: Read / Write / Construct Only</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbDeviceManager.signal-details"></a><h2>Signal Details</h2>
+<div class="refsect2">
+<a name="SpiceUsbDeviceManager-auto-connect-failed"></a><h3>The <code class="literal">“auto-connect-failed”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *manager,
+ <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> *device,
+ <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> *error,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-auto-connect-failed" title="The “auto-connect-failed” signal"><span class="type">“auto-connect-failed”</span></a> signal is emitted
+whenever the auto-connect property is true, and a newly plugged in
+device could not be auto-connected.</p>
+<div class="refsect3">
+<a name="SpiceUsbDeviceManager-auto-connect-failed.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>device</p></td>
+<td class="parameter_description"><p><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> boxed object corresponding to the device which failed to auto connect</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>error</p></td>
+<td class="parameter_description"><p><a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> describing the reason why the autoconnect failed</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceUsbDeviceManager-device-added"></a><h3>The <code class="literal">“device-added”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *manager,
+ <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> *device,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-added" title="The “device-added” signal"><span class="type">“device-added”</span></a> signal is emitted whenever
+a new USB device has been plugged in.</p>
+<div class="refsect3">
+<a name="SpiceUsbDeviceManager-device-added.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>device</p></td>
+<td class="parameter_description"><p><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> boxed object corresponding to the added device</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceUsbDeviceManager-device-error"></a><h3>The <code class="literal">“device-error”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *manager,
+ <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> *device,
+ <a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> *error,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-error" title="The “device-error” signal"><span class="type">“device-error”</span></a> signal is emitted whenever an
+error happens which causes a device to no longer be available to the
+guest.</p>
+<div class="refsect3">
+<a name="SpiceUsbDeviceManager-device-error.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p><a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>device</p></td>
+<td class="parameter_description"><p><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> boxed object corresponding to the device which has an error</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>error</p></td>
+<td class="parameter_description"><p><a href="/usr/share/gtk-doc/html/glibglib-Error-Reporting.html#GError"><span class="type">GError</span></a> describing the error</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceUsbDeviceManager-device-removed"></a><h3>The <code class="literal">“device-removed”</code> signal</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+user_function (<a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> *manager,
+ <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> *device,
+ <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gpointer"><span class="type">gpointer</span></a> user_data)</pre>
+<p>The <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-removed" title="The “device-removed” signal"><span class="type">“device-removed”</span></a> signal is emitted whenever
+an USB device has been removed.</p>
+<div class="refsect3">
+<a name="SpiceUsbDeviceManager-device-removed.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>manager</p></td>
+<td class="parameter_description"><p>the <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager"><span class="type">SpiceUsbDeviceManager</span></a> that emitted the signal</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>device</p></td>
+<td class="parameter_description"><p><a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice"><span class="type">SpiceUsbDevice</span></a> boxed object corresponding to the removed device</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user_data</p></td>
+<td class="parameter_description"><p>user data set when the signal handler was connected.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p>Flags: <a href="/usr/share/gtk-doc/html/gobjectgobject-Signals.html#G-SIGNAL-RUN-FIRST:CAPS">Run First</a></p>
+</div>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>USB Redirection Channel: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="prev" href="SpiceSmartcardChannel.html" title="Smartcard Channel">
+<link rel="next" href="SpicePortChannel.html" title="Port Channel">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceUsbredirChannel.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceUsbredirChannel.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceSmartcardChannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpicePortChannel.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceUsbredirChannel"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceUsbredirChannel.top_of_page"></a>USB Redirection Channel</span></h2>
+<p>USB Redirection Channel — usb redirection</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceUsbredirChannel.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceUsbredirChannel.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceUsbredirChannel.html#SpiceUsbredirChannel-struct" title="struct SpiceUsbredirChannel">SpiceUsbredirChannel</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceUsbredirChannel.html#SpiceUsbredirChannelClass" title="struct SpiceUsbredirChannelClass">SpiceUsbredirChannelClass</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbredirChannel.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+ <span class="lineart">╰──</span> SpiceUsbredirChannel
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbredirChannel.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbredirChannel.description"></a><h2>Description</h2>
+<p>The Spice protocol defines a set of messages to redirect USB devices
+from the Spice client to the VM. This channel handles these messages.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbredirChannel.functions_details"></a><h2>Functions</h2>
+<p></p>
+</div>
+<div class="refsect1">
+<a name="SpiceUsbredirChannel.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceUsbredirChannel-struct"></a><h3>struct SpiceUsbredirChannel</h3>
+<pre class="programlisting">struct SpiceUsbredirChannel;</pre>
+<p>The <a class="link" href="SpiceUsbredirChannel.html" title="USB Redirection Channel"><span class="type">SpiceUsbredirChannel</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceUsbredirChannelClass"></a><h3>struct SpiceUsbredirChannelClass</h3>
+<pre class="programlisting">struct SpiceUsbredirChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+};
+</pre>
+<p>Class structure for <a class="link" href="SpiceUsbredirChannel.html" title="USB Redirection Channel"><span class="type">SpiceUsbredirChannel</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceUsbredirChannelClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody></tbody>
+</table></div>
+</div>
+</div>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>WebDAV Channel: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<link rel="prev" href="SpicePortChannel.html" title="Port Channel">
+<link rel="next" href="ch03.html" title="GTK Widget, from spice-client-gtk">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#SpiceWebdavChannel.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#SpiceWebdavChannel.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpicePortChannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="ch03.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="SpiceWebdavChannel"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="SpiceWebdavChannel.top_of_page"></a>WebDAV Channel</span></h2>
+<p>WebDAV Channel — exports a directory</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="SpiceWebdavChannel.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="SpiceWebdavChannel.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceWebdavChannel.html#SpiceWebdavChannel-struct" title="struct SpiceWebdavChannel">SpiceWebdavChannel</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">struct</td>
+<td class="function_name"><a class="link" href="SpiceWebdavChannel.html#SpiceWebdavChannelClass" title="struct SpiceWebdavChannelClass">SpiceWebdavChannelClass</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="SpiceWebdavChannel.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+ <span class="lineart">╰──</span> SpiceWebdavChannel
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceWebdavChannel.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="SpiceWebdavChannel.description"></a><h2>Description</h2>
+<p>The "webdav" channel exports a directory to the guest for file
+manipulation (read/write/copy etc). The underlying protocol is
+implemented using WebDAV (RFC 4918).</p>
+<p>By default, the shared directory is the one associated with GLib
+<a href="/usr/share/gtk-doc/html/glibglib-Miscellaneous-Utility-Functions.html#G-USER-DIRECTORY-PUBLIC-SHARE:CAPS"><code class="literal">G_USER_DIRECTORY_PUBLIC_SHARE</code></a>. You can specify a different
+directory with <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> <a class="link" href="SpiceSession.html#SpiceSession--shared-dir" title="The “shared-dir” property"><span class="type">“shared-dir”</span></a> property.</p>
+</div>
+<div class="refsect1">
+<a name="SpiceWebdavChannel.functions_details"></a><h2>Functions</h2>
+<p></p>
+</div>
+<div class="refsect1">
+<a name="SpiceWebdavChannel.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceWebdavChannel-struct"></a><h3>struct SpiceWebdavChannel</h3>
+<pre class="programlisting">struct SpiceWebdavChannel;</pre>
+<p>The <a class="link" href="SpiceWebdavChannel.html" title="WebDAV Channel"><span class="type">SpiceWebdavChannel</span></a> struct is opaque and should not be accessed directly.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceWebdavChannelClass"></a><h3>struct SpiceWebdavChannelClass</h3>
+<pre class="programlisting">struct SpiceWebdavChannelClass {
+ SpicePortChannelClass parent_class;
+};
+</pre>
+<p>Class structure for <a class="link" href="SpiceWebdavChannel.html" title="WebDAV Channel"><span class="type">SpiceWebdavChannel</span></a>.</p>
+<div class="refsect3">
+<a name="SpiceWebdavChannelClass.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody></tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="SpiceWebdavChannel.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceChannel.html" title="Spice Channel"><span class="type">SpiceChannel</span></a></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Annotation Glossary: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="prev" href="api-index-deprecated.html" title="Index of deprecated symbols">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"><span id="nav_glossary"><a class="shortcut" href="#glsA">A</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#glsC">C</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#glsE">E</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#glsS">S</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#glsT">T</a></span></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><img src="up-insensitive.png" width="16" height="16" border="0"></td>
+<td><a accesskey="p" href="api-index-deprecated.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><img src="right-insensitive.png" width="16" height="16" border="0"></td>
+</tr></table>
+<div class="glossary">
+<div class="titlepage"><div><div><h1 class="title">
+<a name="annotation-glossary"></a>Annotation Glossary</h1></div></div></div>
+<a name="glsA"></a><h3 class="title">A</h3>
+<dt><span class="glossterm"><a name="annotation-glossterm-allow-none"></a>allow-none</span></dt>
+<dd class="glossdef"><p>NULL is OK, both for passing and for returning.</p></dd>
+<dt><span class="glossterm"><a name="annotation-glossterm-array"></a>array</span></dt>
+<dd class="glossdef"><p>Parameter points to an array of items.</p></dd>
+<a name="glsC"></a><h3 class="title">C</h3>
+<dt><span class="glossterm"><a name="annotation-glossterm-closure"></a>closure</span></dt>
+<dd class="glossdef"><p>This parameter is a 'user_data', for callbacks; many bindings can pass NULL here.</p></dd>
+<a name="glsE"></a><h3 class="title">E</h3>
+<dt><span class="glossterm"><a name="annotation-glossterm-element-type"></a>element-type</span></dt>
+<dd class="glossdef"><p>Generics and defining elements of containers and arrays.</p></dd>
+<a name="glsS"></a><h3 class="title">S</h3>
+<dt><span class="glossterm"><a name="annotation-glossterm-scope%20async"></a>scope async</span></dt>
+<dd class="glossdef"><p>The callback is valid until first called.</p></dd>
+<dt><span class="glossterm"><a name="annotation-glossterm-scope%20call"></a>scope call</span></dt>
+<dd class="glossdef"><p>The callback is valid only during the call to the method.</p></dd>
+<dt><span class="glossterm"><a name="annotation-glossterm-Stable"></a>Stable</span></dt>
+<dd class="glossdef"><p>The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+</p></dd>
+<a name="glsT"></a><h3 class="title">T</h3>
+<dt><span class="glossterm"><a name="annotation-glossterm-transfer%20container"></a>transfer container</span></dt>
+<dd class="glossdef"><p>Free data container after the code is done.</p></dd>
+<dt><span class="glossterm"><a name="annotation-glossterm-transfer%20full"></a>transfer full</span></dt>
+<dd class="glossdef"><p>Free data after the code is done.</p></dd>
+<dt><span class="glossterm"><a name="annotation-glossterm-transfer%20none"></a>transfer none</span></dt>
+<dd class="glossdef"><p>Don't free data after the code is done.</p></dd>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Index of deprecated symbols: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="prev" href="api-index-full.html" title="API Index">
+<link rel="next" href="annotation-glossary.html" title="Annotation Glossary">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"><span id="nav_index"><a class="shortcut" href="#idxA">A</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxC">C</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxM">M</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxU">U</a></span></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><img src="up-insensitive.png" width="16" height="16" border="0"></td>
+<td><a accesskey="p" href="api-index-full.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="annotation-glossary.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="index">
+<div class="titlepage"><div><div><h1 class="title">
+<a name="api-index-deprecated"></a>Index of deprecated symbols</h1></div></div></div>
+<a name="idx"></a><a name="idxA"></a><h3 class="title">A</h3>
+<dt>
+<a class="link" href="SpiceAudio.html#spice-audio-new" title="spice_audio_new ()">spice_audio_new</a>, function in <a class="link" href="SpiceAudio.html" title="Spice Audio">SpiceAudio</a>
+</dt>
+<dd></dd>
+<a name="idxC"></a><h3 class="title">C</h3>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-destroy" title="spice_channel_destroy ()">spice_channel_destroy</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-set-capability" title="spice_channel_set_capability ()">spice_channel_set_capability</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<a name="idxM"></a><h3 class="title">M</h3>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard" title="The “main-clipboard” signal">SpiceMainChannel::main-clipboard</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-grab" title="The “main-clipboard-grab” signal">SpiceMainChannel::main-clipboard-grab</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-release" title="The “main-clipboard-release” signal">SpiceMainChannel::main-clipboard-release</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-request" title="The “main-clipboard-request” signal">SpiceMainChannel::main-clipboard-request</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-grab" title="spice_main_clipboard_grab ()">spice_main_clipboard_grab</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-notify" title="spice_main_clipboard_notify ()">spice_main_clipboard_notify</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-release" title="spice_main_clipboard_release ()">spice_main_clipboard_release</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-request" title="spice_main_clipboard_request ()">spice_main_clipboard_request</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<a name="idxU"></a><h3 class="title">U</h3>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-disconnect-device" title="spice_usb_device_manager_disconnect_device ()">spice_usb_device_manager_disconnect_device</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>API Index: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="prev" href="object-tree.html" title="Object Hierarchy">
+<link rel="next" href="api-index-deprecated.html" title="Index of deprecated symbols">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"><span id="nav_index"><a class="shortcut" href="#idxA">A</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxC">C</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxD">D</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxF">F</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxG">G</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxI">I</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxM">M</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxP">P</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxR">R</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxS">S</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxU">U</a>
+ <span class="dim">|</span>
+ <a class="shortcut" href="#idxW">W</a></span></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><img src="up-insensitive.png" width="16" height="16" border="0"></td>
+<td><a accesskey="p" href="object-tree.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="api-index-deprecated.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="index">
+<div class="titlepage"><div><div><h1 class="title">
+<a name="api-index-full"></a>API Index</h1></div></div></div>
+<a name="idx"></a><a name="idxA"></a><h3 class="title">A</h3>
+<dt>
+<a class="link" href="SpiceAudio.html#SpiceAudio-struct" title="struct SpiceAudio">SpiceAudio</a>, struct in <a class="link" href="SpiceAudio.html" title="Spice Audio">SpiceAudio</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceAudio.html#SpiceAudio--main-context" title="The “main-context” property">SpiceAudio:main-context</a>, object property in <a class="link" href="SpiceAudio.html" title="Spice Audio">SpiceAudio</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceAudio.html#SpiceAudio--session" title="The “session” property">SpiceAudio:session</a>, object property in <a class="link" href="SpiceAudio.html" title="Spice Audio">SpiceAudio</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceAudio.html#SpiceAudioClass" title="struct SpiceAudioClass">SpiceAudioClass</a>, struct in <a class="link" href="SpiceAudio.html" title="Spice Audio">SpiceAudio</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceAudio.html#spice-audio-get" title="spice_audio_get ()">spice_audio_get</a>, function in <a class="link" href="SpiceAudio.html" title="Spice Audio">SpiceAudio</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceAudio.html#spice-audio-new" title="spice_audio_new ()">spice_audio_new</a>, function in <a class="link" href="SpiceAudio.html" title="Spice Audio">SpiceAudio</a>
+</dt>
+<dd></dd>
+<a name="idxC"></a><h3 class="title">C</h3>
+<dt>
+<a class="link" href="SpiceChannel.html#SpiceChannel-struct" title="SpiceChannel">SpiceChannel</a>, struct in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#SpiceChannel-channel-event" title="The “channel-event” signal">SpiceChannel::channel-event</a>, object signal in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#SpiceChannel-open-fd" title="The “open-fd” signal">SpiceChannel::open-fd</a>, object signal in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#SpiceChannel--channel-id" title="The “channel-id” property">SpiceChannel:channel-id</a>, object property in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#SpiceChannel--channel-type" title="The “channel-type” property">SpiceChannel:channel-type</a>, object property in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#SpiceChannel--socket" title="The “socket” property">SpiceChannel:socket</a>, object property in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#SpiceChannel--spice-session" title="The “spice-session” property">SpiceChannel:spice-session</a>, object property in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#SpiceChannel--total-read-bytes" title="The “total-read-bytes” property">SpiceChannel:total-read-bytes</a>, object property in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#SpiceChannelClass" title="SpiceChannelClass">SpiceChannelClass</a>, struct in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#SpiceChannelEvent" title="enum SpiceChannelEvent">SpiceChannelEvent</a>, enum in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-connect" title="spice_channel_connect ()">spice_channel_connect</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-destroy" title="spice_channel_destroy ()">spice_channel_destroy</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-disconnect" title="spice_channel_disconnect ()">spice_channel_disconnect</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-flush-async" title="spice_channel_flush_async ()">spice_channel_flush_async</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-flush-finish" title="spice_channel_flush_finish ()">spice_channel_flush_finish</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-get-error" title="spice_channel_get_error ()">spice_channel_get_error</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-new" title="spice_channel_new ()">spice_channel_new</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-open-fd" title="spice_channel_open_fd ()">spice_channel_open_fd</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-set-capability" title="spice_channel_set_capability ()">spice_channel_set_capability</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-string-to-type" title="spice_channel_string_to_type ()">spice_channel_string_to_type</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-test-capability" title="spice_channel_test_capability ()">spice_channel_test_capability</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-test-common-capability" title="spice_channel_test_common_capability ()">spice_channel_test_common_capability</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceChannel.html#spice-channel-type-to-string" title="spice_channel_type_to_string ()">spice_channel_type_to_string</a>, function in <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceClientError" title="enum SpiceClientError">SpiceClientError</a>, enum in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SPICE-CLIENT-ERROR:CAPS" title="SPICE_CLIENT_ERROR">SPICE_CLIENT_ERROR</a>, macro in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#spice-client-error-quark" title="spice_client_error_quark ()">spice_client_error_quark</a>, function in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-struct" title="struct SpiceCursorChannel">SpiceCursorChannel</a>, struct in <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel">SpiceCursorChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-hide" title="The “cursor-hide” signal">SpiceCursorChannel::cursor-hide</a>, object signal in <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel">SpiceCursorChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-move" title="The “cursor-move” signal">SpiceCursorChannel::cursor-move</a>, object signal in <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel">SpiceCursorChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-reset" title="The “cursor-reset” signal">SpiceCursorChannel::cursor-reset</a>, object signal in <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel">SpiceCursorChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceCursorChannel.html#SpiceCursorChannel-cursor-set" title="The “cursor-set” signal">SpiceCursorChannel::cursor-set</a>, object signal in <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel">SpiceCursorChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceCursorChannel.html#SpiceCursorChannelClass" title="struct SpiceCursorChannelClass">SpiceCursorChannelClass</a>, struct in <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel">SpiceCursorChannel</a>
+</dt>
+<dd></dd>
+<a name="idxD"></a><h3 class="title">D</h3>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-struct" title="struct SpiceDisplayChannel">SpiceDisplayChannel</a>, struct in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-invalidate" title="The “display-invalidate” signal">SpiceDisplayChannel::display-invalidate</a>, object signal in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-mark" title="The “display-mark” signal">SpiceDisplayChannel::display-mark</a>, object signal in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-primary-create" title="The “display-primary-create” signal">SpiceDisplayChannel::display-primary-create</a>, object signal in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-display-primary-destroy" title="The “display-primary-destroy” signal">SpiceDisplayChannel::display-primary-destroy</a>, object signal in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel-gl-draw" title="The “gl-draw” signal">SpiceDisplayChannel::gl-draw</a>, object signal in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel--gl-scanout" title="The “gl-scanout” property">SpiceDisplayChannel:gl-scanout</a>, object property in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel--height" title="The “height” property">SpiceDisplayChannel:height</a>, object property in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel--monitors" title="The “monitors” property">SpiceDisplayChannel:monitors</a>, object property in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel--monitors-max" title="The “monitors-max” property">SpiceDisplayChannel:monitors-max</a>, object property in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannel--width" title="The “width” property">SpiceDisplayChannel:width</a>, object property in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayChannelClass" title="struct SpiceDisplayChannelClass">SpiceDisplayChannelClass</a>, struct in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#SpiceDisplayKeyEvent" title="enum SpiceDisplayKeyEvent">SpiceDisplayKeyEvent</a>, enum in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayMonitorConfig" title="struct SpiceDisplayMonitorConfig">SpiceDisplayMonitorConfig</a>, struct in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceDisplayPrimary" title="struct SpiceDisplayPrimary">SpiceDisplayPrimary</a>, struct in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#spice-display-change-preferred-compression" title="spice_display_change_preferred_compression ()">spice_display_change_preferred_compression</a>, function in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#spice-display-get-gl-scanout" title="spice_display_get_gl_scanout ()">spice_display_get_gl_scanout</a>, function in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-get-grab-keys" title="spice_display_get_grab_keys ()">spice_display_get_grab_keys</a>, function in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-get-pixbuf" title="spice_display_get_pixbuf ()">spice_display_get_pixbuf</a>, function in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#spice-display-get-primary" title="spice_display_get_primary ()">spice_display_get_primary</a>, function in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#spice-display-gl-draw-done" title="spice_display_gl_draw_done ()">spice_display_gl_draw_done</a>, function in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-mouse-ungrab" title="spice_display_mouse_ungrab ()">spice_display_mouse_ungrab</a>, function in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-new" title="spice_display_new ()">spice_display_new</a>, function in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-new-with-monitor" title="spice_display_new_with_monitor ()">spice_display_new_with_monitor</a>, function in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-send-keys" title="spice_display_send_keys ()">spice_display_send_keys</a>, function in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-set-grab-keys" title="spice_display_set_grab_keys ()">spice_display_set_grab_keys</a>, function in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<a name="idxF"></a><h3 class="title">F</h3>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask-finished" title="The “finished” signal">SpiceFileTransferTask::finished</a>, object signal in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--cancellable" title="The “cancellable” property">SpiceFileTransferTask:cancellable</a>, object property in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--channel" title="The “channel” property">SpiceFileTransferTask:channel</a>, object property in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--file" title="The “file” property">SpiceFileTransferTask:file</a>, object property in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--id" title="The “id” property">SpiceFileTransferTask:id</a>, object property in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--progress" title="The “progress” property">SpiceFileTransferTask:progress</a>, object property in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--total-bytes" title="The “total-bytes” property">SpiceFileTransferTask:total-bytes</a>, object property in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#SpiceFileTransferTask--transferred-bytes" title="The “transferred-bytes” property">SpiceFileTransferTask:transferred-bytes</a>, object property in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#spice-file-transfer-task-cancel" title="spice_file_transfer_task_cancel ()">spice_file_transfer_task_cancel</a>, function in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#spice-file-transfer-task-get-filename" title="spice_file_transfer_task_get_filename ()">spice_file_transfer_task_get_filename</a>, function in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#spice-file-transfer-task-get-progress" title="spice_file_transfer_task_get_progress ()">spice_file_transfer_task_get_progress</a>, function in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#spice-file-transfer-task-get-total-bytes" title="spice_file_transfer_task_get_total_bytes ()">spice_file_transfer_task_get_total_bytes</a>, function in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceFileTransferTask.html#spice-file-transfer-task-get-transferred-bytes" title="spice_file_transfer_task_get_transferred_bytes ()">spice_file_transfer_task_get_transferred_bytes</a>, function in <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+</dt>
+<dd></dd>
+<a name="idxG"></a><h3 class="title">G</h3>
+<dt>
+<a class="link" href="SpiceSession.html#spice-get-option-group" title="spice_get_option_group ()">spice_get_option_group</a>, function in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#SpiceGlScanout-struct" title="struct SpiceGlScanout">SpiceGlScanout</a>, struct in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceDisplayChannel.html#spice-gl-scanout-free" title="spice_gl_scanout_free ()">spice_gl_scanout_free</a>, function in <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence-struct" title="SpiceGrabSequence">SpiceGrabSequence</a>, struct in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-grab-sequence-as-string" title="spice_grab_sequence_as_string ()">spice_grab_sequence_as_string</a>, function in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-grab-sequence-copy" title="spice_grab_sequence_copy ()">spice_grab_sequence_copy</a>, function in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-grab-sequence-free" title="spice_grab_sequence_free ()">spice_grab_sequence_free</a>, function in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-grab-sequence-new" title="spice_grab_sequence_new ()">spice_grab_sequence_new</a>, function in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-grab-sequence-new-from-string" title="spice_grab_sequence_new_from_string ()">spice_grab_sequence_new_from_string</a>, function in <a class="link" href="spice-gtk-SpiceDisplay.html" title="Spice Display">SpiceDisplay</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-Version-Information.html#SPICE-GTK-CHECK-VERSION:CAPS" title="SPICE_GTK_CHECK_VERSION()">SPICE_GTK_CHECK_VERSION</a>, macro in <a class="link" href="spice-gtk-Version-Information.html" title="Version Information">Version Information</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-Version-Information.html#SPICE-GTK-MAJOR-VERSION:CAPS" title="SPICE_GTK_MAJOR_VERSION">SPICE_GTK_MAJOR_VERSION</a>, macro in <a class="link" href="spice-gtk-Version-Information.html" title="Version Information">Version Information</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-Version-Information.html#SPICE-GTK-MICRO-VERSION:CAPS" title="SPICE_GTK_MICRO_VERSION">SPICE_GTK_MICRO_VERSION</a>, macro in <a class="link" href="spice-gtk-Version-Information.html" title="Version Information">Version Information</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-Version-Information.html#SPICE-GTK-MINOR-VERSION:CAPS" title="SPICE_GTK_MINOR_VERSION">SPICE_GTK_MINOR_VERSION</a>, macro in <a class="link" href="spice-gtk-Version-Information.html" title="Version Information">Version Information</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceGtkSession.html#spice-gtk-session-copy-to-guest" title="spice_gtk_session_copy_to_guest ()">spice_gtk_session_copy_to_guest</a>, function in <a class="link" href="spice-gtk-SpiceGtkSession.html" title="Spice GTK Session">SpiceGtkSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceGtkSession.html#spice-gtk-session-get" title="spice_gtk_session_get ()">spice_gtk_session_get</a>, function in <a class="link" href="spice-gtk-SpiceGtkSession.html" title="Spice GTK Session">SpiceGtkSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceGtkSession.html#spice-gtk-session-paste-from-guest" title="spice_gtk_session_paste_from_guest ()">spice_gtk_session_paste_from_guest</a>, function in <a class="link" href="spice-gtk-SpiceGtkSession.html" title="Spice GTK Session">SpiceGtkSession</a>
+</dt>
+<dd></dd>
+<a name="idxI"></a><h3 class="title">I</h3>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#SpiceInputsChannel-struct" title="struct SpiceInputsChannel">SpiceInputsChannel</a>, struct in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#SpiceInputsChannel-inputs-modifiers" title="The “inputs-modifiers” signal">SpiceInputsChannel::inputs-modifiers</a>, object signal in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#SpiceInputsChannel--key-modifiers" title="The “key-modifiers” property">SpiceInputsChannel:key-modifiers</a>, object property in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#SpiceInputsChannelClass" title="struct SpiceInputsChannelClass">SpiceInputsChannelClass</a>, struct in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#SpiceInputsLock" title="enum SpiceInputsLock">SpiceInputsLock</a>, enum in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-button-press" title="spice_inputs_button_press ()">spice_inputs_button_press</a>, function in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-button-release" title="spice_inputs_button_release ()">spice_inputs_button_release</a>, function in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-key-press" title="spice_inputs_key_press ()">spice_inputs_key_press</a>, function in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-key-press-and-release" title="spice_inputs_key_press_and_release ()">spice_inputs_key_press_and_release</a>, function in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-key-release" title="spice_inputs_key_release ()">spice_inputs_key_release</a>, function in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-motion" title="spice_inputs_motion ()">spice_inputs_motion</a>, function in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-position" title="spice_inputs_position ()">spice_inputs_position</a>, function in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceInputsChannel.html#spice-inputs-set-key-locks" title="spice_inputs_set_key_locks ()">spice_inputs_set_key_locks</a>, function in <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+</dt>
+<dd></dd>
+<a name="idxM"></a><h3 class="title">M</h3>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-struct" title="struct SpiceMainChannel">SpiceMainChannel</a>, struct in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-agent-update" title="The “main-agent-update” signal">SpiceMainChannel::main-agent-update</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard" title="The “main-clipboard” signal">SpiceMainChannel::main-clipboard</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-grab" title="The “main-clipboard-grab” signal">SpiceMainChannel::main-clipboard-grab</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-release" title="The “main-clipboard-release” signal">SpiceMainChannel::main-clipboard-release</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-request" title="The “main-clipboard-request” signal">SpiceMainChannel::main-clipboard-request</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection" title="The “main-clipboard-selection” signal">SpiceMainChannel::main-clipboard-selection</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection-grab" title="The “main-clipboard-selection-grab” signal">SpiceMainChannel::main-clipboard-selection-grab</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection-release" title="The “main-clipboard-selection-release” signal">SpiceMainChannel::main-clipboard-selection-release</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection-request" title="The “main-clipboard-selection-request” signal">SpiceMainChannel::main-clipboard-selection-request</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-main-mouse-update" title="The “main-mouse-update” signal">SpiceMainChannel::main-mouse-update</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-migration-started" title="The “migration-started” signal">SpiceMainChannel::migration-started</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel-new-file-transfer" title="The “new-file-transfer” signal">SpiceMainChannel::new-file-transfer</a>, object signal in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel--agent-caps-0" title="The “agent-caps-0” property">SpiceMainChannel:agent-caps-0</a>, object property in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel--agent-connected" title="The “agent-connected” property">SpiceMainChannel:agent-connected</a>, object property in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel--color-depth" title="The “color-depth” property">SpiceMainChannel:color-depth</a>, object property in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel--disable-animation" title="The “disable-animation” property">SpiceMainChannel:disable-animation</a>, object property in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel--disable-display-align" title="The “disable-display-align” property">SpiceMainChannel:disable-display-align</a>, object property in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel--disable-display-position" title="The “disable-display-position” property">SpiceMainChannel:disable-display-position</a>, object property in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel--disable-font-smooth" title="The “disable-font-smooth” property">SpiceMainChannel:disable-font-smooth</a>, object property in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel--disable-wallpaper" title="The “disable-wallpaper” property">SpiceMainChannel:disable-wallpaper</a>, object property in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel--max-clipboard" title="The “max-clipboard” property">SpiceMainChannel:max-clipboard</a>, object property in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannel--mouse-mode" title="The “mouse-mode” property">SpiceMainChannel:mouse-mode</a>, object property in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#SpiceMainChannelClass" title="struct SpiceMainChannelClass">SpiceMainChannelClass</a>, struct in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-agent-test-capability" title="spice_main_agent_test_capability ()">spice_main_agent_test_capability</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-grab" title="spice_main_clipboard_grab ()">spice_main_clipboard_grab</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-notify" title="spice_main_clipboard_notify ()">spice_main_clipboard_notify</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-release" title="spice_main_clipboard_release ()">spice_main_clipboard_release</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-request" title="spice_main_clipboard_request ()">spice_main_clipboard_request</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-selection-grab" title="spice_main_clipboard_selection_grab ()">spice_main_clipboard_selection_grab</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-selection-notify" title="spice_main_clipboard_selection_notify ()">spice_main_clipboard_selection_notify</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-selection-release" title="spice_main_clipboard_selection_release ()">spice_main_clipboard_selection_release</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-clipboard-selection-request" title="spice_main_clipboard_selection_request ()">spice_main_clipboard_selection_request</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-file-copy-async" title="spice_main_file_copy_async ()">spice_main_file_copy_async</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-file-copy-finish" title="spice_main_file_copy_finish ()">spice_main_file_copy_finish</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-request-mouse-mode" title="spice_main_request_mouse_mode ()">spice_main_request_mouse_mode</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-send-monitor-config" title="spice_main_send_monitor_config ()">spice_main_send_monitor_config</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-set-display" title="spice_main_set_display ()">spice_main_set_display</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-set-display-enabled" title="spice_main_set_display_enabled ()">spice_main_set_display_enabled</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-update-display" title="spice_main_update_display ()">spice_main_update_display</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceMainChannel.html#spice-main-update-display-enabled" title="spice_main_update_display_enabled ()">spice_main_update_display_enabled</a>, function in <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+</dt>
+<dd></dd>
+<a name="idxP"></a><h3 class="title">P</h3>
+<dt>
+<a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-struct" title="struct SpicePlaybackChannel">SpicePlaybackChannel</a>, struct in <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-data" title="The “playback-data” signal">SpicePlaybackChannel::playback-data</a>, object signal in <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-get-delay" title="The “playback-get-delay” signal">SpicePlaybackChannel::playback-get-delay</a>, object signal in <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-start" title="The “playback-start” signal">SpicePlaybackChannel::playback-start</a>, object signal in <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-stop" title="The “playback-stop” signal">SpicePlaybackChannel::playback-stop</a>, object signal in <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel--min-latency" title="The “min-latency” property">SpicePlaybackChannel:min-latency</a>, object property in <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel--mute" title="The “mute” property">SpicePlaybackChannel:mute</a>, object property in <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel--nchannels" title="The “nchannels” property">SpicePlaybackChannel:nchannels</a>, object property in <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannel--volume" title="The “volume” property">SpicePlaybackChannel:volume</a>, object property in <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePlaybackChannel.html#SpicePlaybackChannelClass" title="struct SpicePlaybackChannelClass">SpicePlaybackChannelClass</a>, struct in <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePlaybackChannel.html#spice-playback-channel-set-delay" title="spice_playback_channel_set_delay ()">spice_playback_channel_set_delay</a>, function in <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePortChannel.html#SpicePortChannel-struct" title="struct SpicePortChannel">SpicePortChannel</a>, struct in <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePortChannel.html#SpicePortChannel-port-data" title="The “port-data” signal">SpicePortChannel::port-data</a>, object signal in <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePortChannel.html#SpicePortChannel-port-event" title="The “port-event” signal">SpicePortChannel::port-event</a>, object signal in <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePortChannel.html#SpicePortChannel--port-name" title="The “port-name” property">SpicePortChannel:port-name</a>, object property in <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePortChannel.html#SpicePortChannel--port-opened" title="The “port-opened” property">SpicePortChannel:port-opened</a>, object property in <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePortChannel.html#SpicePortChannelClass" title="struct SpicePortChannelClass">SpicePortChannelClass</a>, struct in <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePortChannel.html#spice-port-event" title="spice_port_event ()">spice_port_event</a>, function in <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePortChannel.html#spice-port-write-async" title="spice_port_write_async ()">spice_port_write_async</a>, function in <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpicePortChannel.html#spice-port-write-finish" title="spice_port_write_finish ()">spice_port_write_finish</a>, function in <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+</dt>
+<dd></dd>
+<a name="idxR"></a><h3 class="title">R</h3>
+<dt>
+<a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel-struct" title="struct SpiceRecordChannel">SpiceRecordChannel</a>, struct in <a class="link" href="SpiceRecordChannel.html" title="Record Channel">SpiceRecordChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel-record-start" title="The “record-start” signal">SpiceRecordChannel::record-start</a>, object signal in <a class="link" href="SpiceRecordChannel.html" title="Record Channel">SpiceRecordChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel-record-stop" title="The “record-stop” signal">SpiceRecordChannel::record-stop</a>, object signal in <a class="link" href="SpiceRecordChannel.html" title="Record Channel">SpiceRecordChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel--mute" title="The “mute” property">SpiceRecordChannel:mute</a>, object property in <a class="link" href="SpiceRecordChannel.html" title="Record Channel">SpiceRecordChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel--nchannels" title="The “nchannels” property">SpiceRecordChannel:nchannels</a>, object property in <a class="link" href="SpiceRecordChannel.html" title="Record Channel">SpiceRecordChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceRecordChannel.html#SpiceRecordChannel--volume" title="The “volume” property">SpiceRecordChannel:volume</a>, object property in <a class="link" href="SpiceRecordChannel.html" title="Record Channel">SpiceRecordChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceRecordChannel.html#SpiceRecordChannelClass" title="struct SpiceRecordChannelClass">SpiceRecordChannelClass</a>, struct in <a class="link" href="SpiceRecordChannel.html" title="Record Channel">SpiceRecordChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceRecordChannel.html#spice-record-send-data" title="spice_record_send_data ()">spice_record_send_data</a>, function in <a class="link" href="SpiceRecordChannel.html" title="Record Channel">SpiceRecordChannel</a>
+</dt>
+<dd></dd>
+<a name="idxS"></a><h3 class="title">S</h3>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession-struct" title="SpiceSession">SpiceSession</a>, struct in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession-channel-destroy" title="The “channel-destroy” signal">SpiceSession::channel-destroy</a>, object signal in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession-channel-new" title="The “channel-new” signal">SpiceSession::channel-new</a>, object signal in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession-mm-time-reset" title="The “mm-time-reset” signal">SpiceSession::mm-time-reset</a>, object signal in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--ca" title="The “ca” property">SpiceSession:ca</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--ca-file" title="The “ca-file” property">SpiceSession:ca-file</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--cache-size" title="The “cache-size” property">SpiceSession:cache-size</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--cert-subject" title="The “cert-subject” property">SpiceSession:cert-subject</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--ciphers" title="The “ciphers” property">SpiceSession:ciphers</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--client-sockets" title="The “client-sockets” property">SpiceSession:client-sockets</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--color-depth" title="The “color-depth” property">SpiceSession:color-depth</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--disable-effects" title="The “disable-effects” property">SpiceSession:disable-effects</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--enable-audio" title="The “enable-audio” property">SpiceSession:enable-audio</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--enable-smartcard" title="The “enable-smartcard” property">SpiceSession:enable-smartcard</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--enable-usbredir" title="The “enable-usbredir” property">SpiceSession:enable-usbredir</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--glz-window-size" title="The “glz-window-size” property">SpiceSession:glz-window-size</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--host" title="The “host” property">SpiceSession:host</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--inhibit-keyboard-grab" title="The “inhibit-keyboard-grab” property">SpiceSession:inhibit-keyboard-grab</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--migration-state" title="The “migration-state” property">SpiceSession:migration-state</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--name" title="The “name” property">SpiceSession:name</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--password" title="The “password” property">SpiceSession:password</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--port" title="The “port” property">SpiceSession:port</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--preferred-compression" title="The “preferred-compression” property">SpiceSession:preferred-compression</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--protocol" title="The “protocol” property">SpiceSession:protocol</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--proxy" title="The “proxy” property">SpiceSession:proxy</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--pubkey" title="The “pubkey” property">SpiceSession:pubkey</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--read-only" title="The “read-only” property">SpiceSession:read-only</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--secure-channels" title="The “secure-channels” property">SpiceSession:secure-channels</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--share-dir-ro" title="The “share-dir-ro” property">SpiceSession:share-dir-ro</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--shared-dir" title="The “shared-dir” property">SpiceSession:shared-dir</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--smartcard-certificates" title="The “smartcard-certificates” property">SpiceSession:smartcard-certificates</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--smartcard-db" title="The “smartcard-db” property">SpiceSession:smartcard-db</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--tls-port" title="The “tls-port” property">SpiceSession:tls-port</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--unix-path" title="The “unix-path” property">SpiceSession:unix-path</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--uri" title="The “uri” property">SpiceSession:uri</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--username" title="The “username” property">SpiceSession:username</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--uuid" title="The “uuid” property">SpiceSession:uuid</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSession--verify" title="The “verify” property">SpiceSession:verify</a>, object property in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSessionClass" title="SpiceSessionClass">SpiceSessionClass</a>, struct in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSessionMigration" title="enum SpiceSessionMigration">SpiceSessionMigration</a>, enum in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#SpiceSessionVerify" title="enum SpiceSessionVerify">SpiceSessionVerify</a>, enum in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#spice-session-connect" title="spice_session_connect ()">spice_session_connect</a>, function in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#spice-session-disconnect" title="spice_session_disconnect ()">spice_session_disconnect</a>, function in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#spice-session-get-channels" title="spice_session_get_channels ()">spice_session_get_channels</a>, function in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#spice-session-get-proxy-uri" title="spice_session_get_proxy_uri ()">spice_session_get_proxy_uri</a>, function in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#spice-session-get-read-only" title="spice_session_get_read_only ()">spice_session_get_read_only</a>, function in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#spice-session-has-channel-type" title="spice_session_has_channel_type ()">spice_session_has_channel_type</a>, function in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#spice-session-is-for-migration" title="spice_session_is_for_migration ()">spice_session_is_for_migration</a>, function in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#spice-session-new" title="spice_session_new ()">spice_session_new</a>, function in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#spice-session-open-fd" title="spice_session_open_fd ()">spice_session_open_fd</a>, function in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSession.html#spice-set-session-option" title="spice_set_session_option ()">spice_set_session_option</a>, function in <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardChannel.html#SpiceSmartcardChannel-struct" title="struct SpiceSmartcardChannel">SpiceSmartcardChannel</a>, struct in <a class="link" href="SpiceSmartcardChannel.html" title="Smartcard Channel">SpiceSmartcardChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardChannel.html#SpiceSmartcardChannelClass" title="struct SpiceSmartcardChannelClass">SpiceSmartcardChannelClass</a>, struct in <a class="link" href="SpiceSmartcardChannel.html" title="Smartcard Channel">SpiceSmartcardChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-struct" title="struct SpiceSmartcardManager">SpiceSmartcardManager</a>, struct in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-card-inserted" title="The “card-inserted” signal">SpiceSmartcardManager::card-inserted</a>, object signal in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-card-removed" title="The “card-removed” signal">SpiceSmartcardManager::card-removed</a>, object signal in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-reader-added" title="The “reader-added” signal">SpiceSmartcardManager::reader-added</a>, object signal in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManager-reader-removed" title="The “reader-removed” signal">SpiceSmartcardManager::reader-removed</a>, object signal in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardManagerClass" title="struct SpiceSmartcardManagerClass">SpiceSmartcardManagerClass</a>, struct in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#SpiceSmartcardReader" title="SpiceSmartcardReader">SpiceSmartcardReader</a>, struct in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-manager-get" title="spice_smartcard_manager_get ()">spice_smartcard_manager_get</a>, function in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-manager-get-readers" title="spice_smartcard_manager_get_readers ()">spice_smartcard_manager_get_readers</a>, function in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-manager-insert-card" title="spice_smartcard_manager_insert_card ()">spice_smartcard_manager_insert_card</a>, function in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-manager-remove-card" title="spice_smartcard_manager_remove_card ()">spice_smartcard_manager_remove_card</a>, function in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-reader-insert-card" title="spice_smartcard_reader_insert_card ()">spice_smartcard_reader_insert_card</a>, function in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-reader-is-software" title="spice_smartcard_reader_is_software ()">spice_smartcard_reader_is_software</a>, function in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceSmartcardManager.html#spice-smartcard-reader-remove-card" title="spice_smartcard_reader_remove_card ()">spice_smartcard_reader_remove_card</a>, function in <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+</dt>
+<dd></dd>
+<a name="idxU"></a><h3 class="title">U</h3>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI">SpiceURI</a>, struct in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#SpiceURIClass" title="SpiceURIClass">SpiceURIClass</a>, struct in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-get-hostname" title="spice_uri_get_hostname ()">spice_uri_get_hostname</a>, function in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-get-password" title="spice_uri_get_password ()">spice_uri_get_password</a>, function in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-get-port" title="spice_uri_get_port ()">spice_uri_get_port</a>, function in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-get-scheme" title="spice_uri_get_scheme ()">spice_uri_get_scheme</a>, function in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-get-user" title="spice_uri_get_user ()">spice_uri_get_user</a>, function in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-set-hostname" title="spice_uri_set_hostname ()">spice_uri_set_hostname</a>, function in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-set-password" title="spice_uri_set_password ()">spice_uri_set_password</a>, function in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-set-port" title="spice_uri_set_port ()">spice_uri_set_port</a>, function in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-set-scheme" title="spice_uri_set_scheme ()">spice_uri_set_scheme</a>, function in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-set-user" title="spice_uri_set_user ()">spice_uri_set_user</a>, function in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-to-string" title="spice_uri_to_string ()">spice_uri_to_string</a>, function in <a class="link" href="spice-gtk-SpiceURI.html" title="SpiceURI">SpiceURI</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice-struct" title="SpiceUsbDevice">SpiceUsbDevice</a>, struct in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-struct" title="struct SpiceUsbDeviceManager">SpiceUsbDeviceManager</a>, struct in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-auto-connect-failed" title="The “auto-connect-failed” signal">SpiceUsbDeviceManager::auto-connect-failed</a>, object signal in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-added" title="The “device-added” signal">SpiceUsbDeviceManager::device-added</a>, object signal in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-error" title="The “device-error” signal">SpiceUsbDeviceManager::device-error</a>, object signal in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-removed" title="The “device-removed” signal">SpiceUsbDeviceManager::device-removed</a>, object signal in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--auto-connect" title="The “auto-connect” property">SpiceUsbDeviceManager:auto-connect</a>, object property in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--auto-connect-filter" title="The “auto-connect-filter” property">SpiceUsbDeviceManager:auto-connect-filter</a>, object property in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--free-channels" title="The “free-channels” property">SpiceUsbDeviceManager:free-channels</a>, object property in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--redirect-on-connect" title="The “redirect-on-connect” property">SpiceUsbDeviceManager:redirect-on-connect</a>, object property in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--session" title="The “session” property">SpiceUsbDeviceManager:session</a>, object property in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDeviceManagerClass" title="struct SpiceUsbDeviceManagerClass">SpiceUsbDeviceManagerClass</a>, struct in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbredirChannel.html#SpiceUsbredirChannel-struct" title="struct SpiceUsbredirChannel">SpiceUsbredirChannel</a>, struct in <a class="link" href="SpiceUsbredirChannel.html" title="USB Redirection Channel">SpiceUsbredirChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbredirChannel.html#SpiceUsbredirChannelClass" title="struct SpiceUsbredirChannelClass">SpiceUsbredirChannelClass</a>, struct in <a class="link" href="SpiceUsbredirChannel.html" title="USB Redirection Channel">SpiceUsbredirChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-get-description" title="spice_usb_device_get_description ()">spice_usb_device_get_description</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-get-libusb-device" title="spice_usb_device_get_libusb_device ()">spice_usb_device_get_libusb_device</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-can-redirect-device" title="spice_usb_device_manager_can_redirect_device ()">spice_usb_device_manager_can_redirect_device</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-connect-device-async" title="spice_usb_device_manager_connect_device_async ()">spice_usb_device_manager_connect_device_async</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-connect-device-finish" title="spice_usb_device_manager_connect_device_finish ()">spice_usb_device_manager_connect_device_finish</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-disconnect-device" title="spice_usb_device_manager_disconnect_device ()">spice_usb_device_manager_disconnect_device</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-disconnect-device-async" title="spice_usb_device_manager_disconnect_device_async ()">spice_usb_device_manager_disconnect_device_async</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-disconnect-device-finish" title="spice_usb_device_manager_disconnect_device_finish ()">spice_usb_device_manager_disconnect_device_finish</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-get" title="spice_usb_device_manager_get ()">spice_usb_device_manager_get</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-get-devices" title="spice_usb_device_manager_get_devices ()">spice_usb_device_manager_get_devices</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-get-devices-with-filter" title="spice_usb_device_manager_get_devices_with_filter ()">spice_usb_device_manager_get_devices_with_filter</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-is-device-connected" title="spice_usb_device_manager_is_device_connected ()">spice_usb_device_manager_is_device_connected</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-manager-is-redirecting" title="spice_usb_device_manager_is_redirecting ()">spice_usb_device_manager_is_redirecting</a>, function in <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-SpiceUsbDeviceWidget.html#spice-usb-device-widget-new" title="spice_usb_device_widget_new ()">spice_usb_device_widget_new</a>, function in <a class="link" href="spice-gtk-SpiceUsbDeviceWidget.html" title="Spice USB device selection widget">SpiceUsbDeviceWidget</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-Utilities.html#spice-util-get-version-string" title="spice_util_get_version_string ()">spice_util_get_version_string</a>, function in <a class="link" href="spice-gtk-Utilities.html" title="Utilities">Utilities</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-Utilities.html#spice-util-set-debug" title="spice_util_set_debug ()">spice_util_set_debug</a>, function in <a class="link" href="spice-gtk-Utilities.html" title="Utilities">Utilities</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="spice-gtk-Utilities.html#spice-uuid-to-string" title="spice_uuid_to_string ()">spice_uuid_to_string</a>, function in <a class="link" href="spice-gtk-Utilities.html" title="Utilities">Utilities</a>
+</dt>
+<dd></dd>
+<a name="idxW"></a><h3 class="title">W</h3>
+<dt>
+<a class="link" href="SpiceWebdavChannel.html#SpiceWebdavChannel-struct" title="struct SpiceWebdavChannel">SpiceWebdavChannel</a>, struct in <a class="link" href="SpiceWebdavChannel.html" title="WebDAV Channel">SpiceWebdavChannel</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="SpiceWebdavChannel.html#SpiceWebdavChannelClass" title="struct SpiceWebdavChannelClass">SpiceWebdavChannelClass</a>, struct in <a class="link" href="SpiceWebdavChannel.html" title="WebDAV Channel">SpiceWebdavChannel</a>
+</dt>
+<dd></dd>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Part I. API Reference: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="prev" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="next" href="ch01.html" title="Object Hierarchy">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><img src="up-insensitive.png" width="16" height="16" border="0"></td>
+<td><a accesskey="p" href="index.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="ch01.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="part">
+<div class="titlepage"><div><div><h1 class="title">
+<a name="api-reference"></a>Part I. API Reference</h1></div></div></div>
+<div class="toc">
+<p><b>Table of Contents</b></p>
+<dl class="toc">
+<dt><span class="chapter"><a href="ch01.html">Object Hierarchy</a></span></dt>
+<dt><span class="chapter"><a href="ch02.html">Session and Channels Objects, from spice-client-glib</a></span></dt>
+<dd><dl>
+<dt>
+<span class="refentrytitle"><a href="SpiceSession.html">Spice Session</a></span><span class="refpurpose"> — handles connection details, and active channels</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceChannel.html">Spice Channel</a></span><span class="refpurpose"> — the base channel class</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceCursorChannel.html">Cursor Channel</a></span><span class="refpurpose"> — update cursor shape and position</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceDisplayChannel.html">Display Channel</a></span><span class="refpurpose"> — remote display area</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceInputsChannel.html">Inputs Channel</a></span><span class="refpurpose"> — control the server mouse and keyboard</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceMainChannel.html">Main Channel</a></span><span class="refpurpose"> — the main Spice channel</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpicePlaybackChannel.html">Playback Channel</a></span><span class="refpurpose"> — audio stream for playback</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceRecordChannel.html">Record Channel</a></span><span class="refpurpose"> — audio stream for recording</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceSmartcardChannel.html">Smartcard Channel</a></span><span class="refpurpose"> — smartcard authentication</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceUsbredirChannel.html">USB Redirection Channel</a></span><span class="refpurpose"> — usb redirection</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpicePortChannel.html">Port Channel</a></span><span class="refpurpose"> — private communication channel</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceWebdavChannel.html">WebDAV Channel</a></span><span class="refpurpose"> — exports a directory</span>
+</dt>
+</dl></dd>
+<dt><span class="chapter"><a href="ch03.html">GTK Widget, from spice-client-gtk</a></span></dt>
+<dd><dl>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-SpiceGtkSession.html">Spice GTK Session</a></span><span class="refpurpose"> — handles GTK connection details</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-SpiceDisplay.html">Spice Display</a></span><span class="refpurpose"> — a GTK display widget</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-SpiceUsbDeviceWidget.html">Spice USB device selection widget</a></span><span class="refpurpose"> — USB device selection widget</span>
+</dt>
+</dl></dd>
+<dt><span class="chapter"><a href="application-support.html">Application Support, from spice-client-glib</a></span></dt>
+<dd><dl>
+<dt>
+<span class="refentrytitle"><a href="SpiceAudio.html">Spice Audio</a></span><span class="refpurpose"> — a helper to play and to record audio channels</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceSmartcardManager.html">Spice Smartcard Manager</a></span><span class="refpurpose"> — smartcard management</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceUsbDeviceManager.html">Spice USB Manager</a></span><span class="refpurpose"> — USB device management</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-Utilities.html">Utilities</a></span><span class="refpurpose"> — version and debugging functions</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-Version-Information.html">Version Information</a></span><span class="refpurpose"> — Spice-Gtk version checking</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-SpiceURI.html">SpiceURI</a></span><span class="refpurpose"> — URIs handling</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceFileTransferTask.html">File Transfer Task</a></span><span class="refpurpose"> — Monitoring file transfers</span>
+</dt>
+</dl></dd>
+</dl>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Application Support, from spice-client-glib: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="api-reference.html" title="Part I. API Reference">
+<link rel="prev" href="spice-gtk-SpiceUsbDeviceWidget.html" title="Spice USB device selection widget">
+<link rel="next" href="SpiceAudio.html" title="Spice Audio">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="api-reference.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="spice-gtk-SpiceUsbDeviceWidget.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceAudio.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="chapter">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="application-support"></a>Application Support, from spice-client-glib</h2></div></div></div>
+<div class="toc"><dl class="toc">
+<dt>
+<span class="refentrytitle"><a href="SpiceAudio.html">Spice Audio</a></span><span class="refpurpose"> — a helper to play and to record audio channels</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceSmartcardManager.html">Spice Smartcard Manager</a></span><span class="refpurpose"> — smartcard management</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceUsbDeviceManager.html">Spice USB Manager</a></span><span class="refpurpose"> — USB device management</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-Utilities.html">Utilities</a></span><span class="refpurpose"> — version and debugging functions</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-Version-Information.html">Version Information</a></span><span class="refpurpose"> — Spice-Gtk version checking</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-SpiceURI.html">SpiceURI</a></span><span class="refpurpose"> — URIs handling</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceFileTransferTask.html">File Transfer Task</a></span><span class="refpurpose"> — Monitoring file transfers</span>
+</dt>
+</dl></div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Object Hierarchy: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="api-reference.html" title="Part I. API Reference">
+<link rel="prev" href="api-reference.html" title="Part I. API Reference">
+<link rel="next" href="ch02.html" title="Session and Channels Objects, from spice-client-glib">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="api-reference.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="api-reference.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="ch02.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="chapter">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="id-1.2.2"></a>Object Hierarchy</h2></div></div></div>
+<pre class="screen">
+ <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceAudio.html" title="Spice Audio">SpiceAudio</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel">SpiceCursorChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceRecordChannel.html" title="Record Channel">SpiceRecordChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceSmartcardChannel.html" title="Smartcard Channel">SpiceSmartcardChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceUsbredirChannel.html" title="USB Redirection Channel">SpiceUsbredirChannel</a>
+ <span class="lineart">│</span> <span class="lineart">╰──</span> <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+ <span class="lineart">│</span> <span class="lineart">╰──</span> <a class="link" href="SpiceWebdavChannel.html" title="WebDAV Channel">SpiceWebdavChannel</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+ <a href="https://developer.gnome.org/gobject/unstable/gobject-Enumeration-and-Flag-Types.html">GEnum</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceChannel.html#SpiceChannelEvent" title="enum SpiceChannelEvent">SpiceChannelEvent</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceSession.html#SpiceSessionMigration" title="enum SpiceSessionMigration">SpiceSessionMigration</a>
+ <a href="https://developer.gnome.org/gobject/unstable/gobject-Boxed-Types.html">GBoxed</a>
+ <span class="lineart">├──</span> <a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence">SpiceGrabSequence</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice">SpiceUsbDevice</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceDisplayChannel.html#SpiceGlScanout">SpiceGlScanout</a>
+ <a href="https://developer.gnome.org/gobject/unstable/gobject-Enumeration-and-Flag-Types.html">GFlags</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceInputsChannel.html#SpiceInputsLock" title="enum SpiceInputsLock">SpiceInputsLock</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceSession.html#SpiceSessionVerify" title="enum SpiceSessionVerify">SpiceSessionVerify</a>
+</pre>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Session and Channels Objects, from spice-client-glib: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="api-reference.html" title="Part I. API Reference">
+<link rel="prev" href="ch01.html" title="Object Hierarchy">
+<link rel="next" href="SpiceSession.html" title="Spice Session">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="api-reference.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="ch01.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceSession.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="chapter">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="id-1.2.3"></a>Session and Channels Objects, from spice-client-glib</h2></div></div></div>
+<div class="toc"><dl class="toc">
+<dt>
+<span class="refentrytitle"><a href="SpiceSession.html">Spice Session</a></span><span class="refpurpose"> — handles connection details, and active channels</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceChannel.html">Spice Channel</a></span><span class="refpurpose"> — the base channel class</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceCursorChannel.html">Cursor Channel</a></span><span class="refpurpose"> — update cursor shape and position</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceDisplayChannel.html">Display Channel</a></span><span class="refpurpose"> — remote display area</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceInputsChannel.html">Inputs Channel</a></span><span class="refpurpose"> — control the server mouse and keyboard</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceMainChannel.html">Main Channel</a></span><span class="refpurpose"> — the main Spice channel</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpicePlaybackChannel.html">Playback Channel</a></span><span class="refpurpose"> — audio stream for playback</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceRecordChannel.html">Record Channel</a></span><span class="refpurpose"> — audio stream for recording</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceSmartcardChannel.html">Smartcard Channel</a></span><span class="refpurpose"> — smartcard authentication</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceUsbredirChannel.html">USB Redirection Channel</a></span><span class="refpurpose"> — usb redirection</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpicePortChannel.html">Port Channel</a></span><span class="refpurpose"> — private communication channel</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceWebdavChannel.html">WebDAV Channel</a></span><span class="refpurpose"> — exports a directory</span>
+</dt>
+</dl></div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>GTK Widget, from spice-client-gtk: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="api-reference.html" title="Part I. API Reference">
+<link rel="prev" href="SpiceWebdavChannel.html" title="WebDAV Channel">
+<link rel="next" href="spice-gtk-SpiceGtkSession.html" title="Spice GTK Session">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="api-reference.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceWebdavChannel.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="spice-gtk-SpiceGtkSession.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="chapter">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="id-1.2.4"></a>GTK Widget, from spice-client-gtk</h2></div></div></div>
+<div class="toc"><dl class="toc">
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-SpiceGtkSession.html">Spice GTK Session</a></span><span class="refpurpose"> — handles GTK connection details</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-SpiceDisplay.html">Spice Display</a></span><span class="refpurpose"> — a GTK display widget</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-SpiceUsbDeviceWidget.html">Spice USB device selection widget</a></span><span class="refpurpose"> — USB device selection widget</span>
+</dt>
+</dl></div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Spice-GTK Reference Manual: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="next" href="api-reference.html" title="Part I. API Reference">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<div class="book">
+<div class="titlepage">
+<div><div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">Spice-GTK Reference Manual</p></th></tr></table></div></div>
+<hr>
+</div>
+<div class="toc"><dl class="toc">
+<dt><span class="part"><a href="api-reference.html">I. API Reference</a></span></dt>
+<dd><dl>
+<dt><span class="chapter"><a href="ch01.html">Object Hierarchy</a></span></dt>
+<dt><span class="chapter"><a href="ch02.html">Session and Channels Objects, from spice-client-glib</a></span></dt>
+<dd><dl>
+<dt>
+<span class="refentrytitle"><a href="SpiceSession.html">Spice Session</a></span><span class="refpurpose"> — handles connection details, and active channels</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceChannel.html">Spice Channel</a></span><span class="refpurpose"> — the base channel class</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceCursorChannel.html">Cursor Channel</a></span><span class="refpurpose"> — update cursor shape and position</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceDisplayChannel.html">Display Channel</a></span><span class="refpurpose"> — remote display area</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceInputsChannel.html">Inputs Channel</a></span><span class="refpurpose"> — control the server mouse and keyboard</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceMainChannel.html">Main Channel</a></span><span class="refpurpose"> — the main Spice channel</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpicePlaybackChannel.html">Playback Channel</a></span><span class="refpurpose"> — audio stream for playback</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceRecordChannel.html">Record Channel</a></span><span class="refpurpose"> — audio stream for recording</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceSmartcardChannel.html">Smartcard Channel</a></span><span class="refpurpose"> — smartcard authentication</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceUsbredirChannel.html">USB Redirection Channel</a></span><span class="refpurpose"> — usb redirection</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpicePortChannel.html">Port Channel</a></span><span class="refpurpose"> — private communication channel</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceWebdavChannel.html">WebDAV Channel</a></span><span class="refpurpose"> — exports a directory</span>
+</dt>
+</dl></dd>
+<dt><span class="chapter"><a href="ch03.html">GTK Widget, from spice-client-gtk</a></span></dt>
+<dd><dl>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-SpiceGtkSession.html">Spice GTK Session</a></span><span class="refpurpose"> — handles GTK connection details</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-SpiceDisplay.html">Spice Display</a></span><span class="refpurpose"> — a GTK display widget</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-SpiceUsbDeviceWidget.html">Spice USB device selection widget</a></span><span class="refpurpose"> — USB device selection widget</span>
+</dt>
+</dl></dd>
+<dt><span class="chapter"><a href="application-support.html">Application Support, from spice-client-glib</a></span></dt>
+<dd><dl>
+<dt>
+<span class="refentrytitle"><a href="SpiceAudio.html">Spice Audio</a></span><span class="refpurpose"> — a helper to play and to record audio channels</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceSmartcardManager.html">Spice Smartcard Manager</a></span><span class="refpurpose"> — smartcard management</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceUsbDeviceManager.html">Spice USB Manager</a></span><span class="refpurpose"> — USB device management</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-Utilities.html">Utilities</a></span><span class="refpurpose"> — version and debugging functions</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-Version-Information.html">Version Information</a></span><span class="refpurpose"> — Spice-Gtk version checking</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="spice-gtk-SpiceURI.html">SpiceURI</a></span><span class="refpurpose"> — URIs handling</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="SpiceFileTransferTask.html">File Transfer Task</a></span><span class="refpurpose"> — Monitoring file transfers</span>
+</dt>
+</dl></dd>
+</dl></dd>
+<dt><span class="chapter"><a href="object-tree.html">Object Hierarchy</a></span></dt>
+<dt><span class="index"><a href="api-index-full.html">API Index</a></span></dt>
+<dt><span class="index"><a href="api-index-deprecated.html">Index of deprecated symbols</a></span></dt>
+<dt><span class="glossary"><a href="annotation-glossary.html">Annotation Glossary</a></span></dt>
+</dl></div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Object Hierarchy: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="prev" href="SpiceFileTransferTask.html" title="File Transfer Task">
+<link rel="next" href="api-index-full.html" title="API Index">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><img src="up-insensitive.png" width="16" height="16" border="0"></td>
+<td><a accesskey="p" href="SpiceFileTransferTask.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="api-index-full.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="chapter">
+<div class="titlepage"><div><div><h1 class="title">
+<a name="object-tree"></a>Object Hierarchy</h1></div></div></div>
+<pre class="screen">
+ <a href="/usr/share/gtk-doc/html/gobjectgobject-The-Base-Object-Type.html#GObject-struct">GObject</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceAudio.html" title="Spice Audio">SpiceAudio</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceChannel.html" title="Spice Channel">SpiceChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceCursorChannel.html" title="Cursor Channel">SpiceCursorChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceDisplayChannel.html" title="Display Channel">SpiceDisplayChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceInputsChannel.html" title="Inputs Channel">SpiceInputsChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceMainChannel.html" title="Main Channel">SpiceMainChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpicePlaybackChannel.html" title="Playback Channel">SpicePlaybackChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceRecordChannel.html" title="Record Channel">SpiceRecordChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceSmartcardChannel.html" title="Smartcard Channel">SpiceSmartcardChannel</a>
+ <span class="lineart">│</span> <span class="lineart">├──</span> <a class="link" href="SpiceUsbredirChannel.html" title="USB Redirection Channel">SpiceUsbredirChannel</a>
+ <span class="lineart">│</span> <span class="lineart">╰──</span> <a class="link" href="SpicePortChannel.html" title="Port Channel">SpicePortChannel</a>
+ <span class="lineart">│</span> <span class="lineart">╰──</span> <a class="link" href="SpiceWebdavChannel.html" title="WebDAV Channel">SpiceWebdavChannel</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceSession.html" title="Spice Session">SpiceSession</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceSmartcardManager.html" title="Spice Smartcard Manager">SpiceSmartcardManager</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">SpiceUsbDeviceManager</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceFileTransferTask.html" title="File Transfer Task">SpiceFileTransferTask</a>
+ <a href="https://developer.gnome.org/gobject/unstable/gobject-Enumeration-and-Flag-Types.html">GEnum</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceChannel.html#SpiceChannelEvent" title="enum SpiceChannelEvent">SpiceChannelEvent</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceSession.html#SpiceSessionMigration" title="enum SpiceSessionMigration">SpiceSessionMigration</a>
+ <a href="https://developer.gnome.org/gobject/unstable/gobject-Boxed-Types.html">GBoxed</a>
+ <span class="lineart">├──</span> <a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence">SpiceGrabSequence</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceUsbDeviceManager.html#SpiceUsbDevice">SpiceUsbDevice</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceDisplayChannel.html#SpiceGlScanout">SpiceGlScanout</a>
+ <a href="https://developer.gnome.org/gobject/unstable/gobject-Enumeration-and-Flag-Types.html">GFlags</a>
+ <span class="lineart">├──</span> <a class="link" href="SpiceInputsChannel.html#SpiceInputsLock" title="enum SpiceInputsLock">SpiceInputsLock</a>
+ <span class="lineart">╰──</span> <a class="link" href="SpiceSession.html#SpiceSessionVerify" title="enum SpiceSessionVerify">SpiceSessionVerify</a>
+</pre>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Spice Display: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch03.html" title="GTK Widget, from spice-client-gtk">
+<link rel="prev" href="spice-gtk-SpiceGtkSession.html" title="Spice GTK Session">
+<link rel="next" href="spice-gtk-SpiceUsbDeviceWidget.html" title="Spice USB device selection widget">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#spice-gtk-SpiceDisplay.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span>
+ <a href="#spice-gtk-SpiceDisplay.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch03.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="spice-gtk-SpiceGtkSession.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="spice-gtk-SpiceUsbDeviceWidget.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="spice-gtk-SpiceDisplay"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="spice-gtk-SpiceDisplay.top_of_page"></a>Spice Display</span></h2>
+<p>Spice Display — a GTK display widget</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceDisplay.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceDisplay.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<span class="returnvalue">SpiceDisplay</span> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-new" title="spice_display_new ()">spice_display_new</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">SpiceDisplay</span> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-new-with-monitor" title="spice_display_new_with_monitor ()">spice_display_new_with_monitor</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-mouse-ungrab" title="spice_display_mouse_ungrab ()">spice_display_mouse_ungrab</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-set-grab-keys" title="spice_display_set_grab_keys ()">spice_display_set_grab_keys</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="returnvalue">SpiceGrabSequence</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-get-grab-keys" title="spice_display_get_grab_keys ()">spice_display_get_grab_keys</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-send-keys" title="spice_display_send_keys ()">spice_display_send_keys</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/gdk-pixbufgdk-pixbuf-The-GdkPixbuf-Structure.html#GdkPixbuf-struct"><span class="returnvalue">GdkPixbuf</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-get-pixbuf" title="spice_display_get_pixbuf ()">spice_display_get_pixbuf</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="returnvalue">SpiceGrabSequence</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-grab-sequence-new" title="spice_grab_sequence_new ()">spice_grab_sequence_new</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="returnvalue">SpiceGrabSequence</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-grab-sequence-new-from-string" title="spice_grab_sequence_new_from_string ()">spice_grab_sequence_new_from_string</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="returnvalue">SpiceGrabSequence</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-grab-sequence-copy" title="spice_grab_sequence_copy ()">spice_grab_sequence_copy</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-grab-sequence-free" title="spice_grab_sequence_free ()">spice_grab_sequence_free</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceDisplay.html#spice-grab-sequence-as-string" title="spice_grab_sequence_as_string ()">spice_grab_sequence_as_string</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<a name="SpiceGrabSequence"></a><div class="refsect1">
+<a name="spice-gtk-SpiceDisplay.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="spice-gtk-SpiceDisplay.html#SpiceDisplayKeyEvent" title="enum SpiceDisplayKeyEvent">SpiceDisplayKeyEvent</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword"> </td>
+<td class="function_name"><a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence-struct" title="SpiceGrabSequence">SpiceGrabSequence</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceDisplay.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen"> <a href="https://developer.gnome.org/gobject/unstable/gobject-Boxed-Types.html">GBoxed</a>
+ <span class="lineart">╰──</span> SpiceGrabSequence
+</pre>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceDisplay.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client-gtk.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceDisplay.description"></a><h2>Description</h2>
+<p>A GTK widget that displays a SPICE server. It sends keyboard/mouse
+events and can also share clipboard...</p>
+<p>Arbitrary key events can be sent thanks to <a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-send-keys" title="spice_display_send_keys ()"><code class="function">spice_display_send_keys()</code></a>.</p>
+<p>The widget will optionally grab the keyboard and the mouse when
+focused if the properties <span class="type">“grab-keyboard”</span> and
+<span class="type">“grab-mouse”</span> are <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><span class="type">TRUE</span></a> respectively. It can be
+ungrabbed with <a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-mouse-ungrab" title="spice_display_mouse_ungrab ()"><code class="function">spice_display_mouse_ungrab()</code></a>, and by setting a key
+combination with <a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-set-grab-keys" title="spice_display_set_grab_keys ()"><code class="function">spice_display_set_grab_keys()</code></a>.</p>
+<p>Finally, <a class="link" href="spice-gtk-SpiceDisplay.html#spice-display-get-pixbuf" title="spice_display_get_pixbuf ()"><code class="function">spice_display_get_pixbuf()</code></a> will take a screenshot of the
+current display and return an <a href="/usr/share/gtk-doc/html/gdk-pixbufgdk-pixbuf-The-GdkPixbuf-Structure.html#GdkPixbuf-struct"><span class="type">GdkPixbuf</span></a> (that you can then easily
+save to disk).</p>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceDisplay.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-display-new"></a><h3>spice_display_new ()</h3>
+<pre class="programlisting"><span class="returnvalue">SpiceDisplay</span> *
+spice_display_new (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>,
+ <em class="parameter"><code><span class="type">int</span> channel_id</code></em>);</pre>
+<p>Creates a new <span class="type">SpiceDisplay</span> widget.</p>
+<div class="refsect3">
+<a name="spice-display-new.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>channel_id</p></td>
+<td class="parameter_description"><p>the display channel ID to associate with <span class="type">SpiceDisplay</span></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-display-new.returns"></a><h4>Returns</h4>
+<p> a new <span class="type">SpiceDisplay</span> widget.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-display-new-with-monitor"></a><h3>spice_display_new_with_monitor ()</h3>
+<pre class="programlisting"><span class="returnvalue">SpiceDisplay</span> *
+spice_display_new_with_monitor (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> channel_id</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gint"><span class="type">gint</span></a> monitor_id</code></em>);</pre>
+<p>Creates a new <span class="type">SpiceDisplay</span> widget associated with the monitor id.</p>
+<div class="refsect3">
+<a name="spice-display-new-with-monitor.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p>a <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>channel_id</p></td>
+<td class="parameter_description"><p>the display channel ID to associate with <span class="type">SpiceDisplay</span></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>monitor_id</p></td>
+<td class="parameter_description"><p>the monitor id within the display channel</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-display-new-with-monitor.returns"></a><h4>Returns</h4>
+<p> a new <span class="type">SpiceDisplay</span> widget.</p>
+</div>
+<p class="since">Since: 0.13</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-display-mouse-ungrab"></a><h3>spice_display_mouse_ungrab ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_display_mouse_ungrab (<em class="parameter"><code><span class="type">SpiceDisplay</span> *display</code></em>);</pre>
+<p>Ungrab the mouse.</p>
+<div class="refsect3">
+<a name="spice-display-mouse-ungrab.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>display</p></td>
+<td class="parameter_description"><p>a <span class="type">SpiceDisplay</span></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-display-set-grab-keys"></a><h3>spice_display_set_grab_keys ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_display_set_grab_keys (<em class="parameter"><code><span class="type">SpiceDisplay</span> *display</code></em>,
+ <em class="parameter"><code><a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="type">SpiceGrabSequence</span></a> *seq</code></em>);</pre>
+<p>Set the key combination to grab/ungrab the keyboard. The default is
+"Control L + Alt L".</p>
+<div class="refsect3">
+<a name="spice-display-set-grab-keys.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>display</p></td>
+<td class="parameter_description"><p>the display widget</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>seq</p></td>
+<td class="parameter_description"><p> key sequence. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-display-get-grab-keys"></a><h3>spice_display_get_grab_keys ()</h3>
+<pre class="programlisting"><a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="returnvalue">SpiceGrabSequence</span></a> *
+spice_display_get_grab_keys (<em class="parameter"><code><span class="type">SpiceDisplay</span> *display</code></em>);</pre>
+<p>Finds the current grab key combination for the <em class="parameter"><code>display</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-display-get-grab-keys.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>display</p></td>
+<td class="parameter_description"><p>the display widget</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-display-get-grab-keys.returns"></a><h4>Returns</h4>
+<p> the current grab key combination. </p>
+<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-display-send-keys"></a><h3>spice_display_send_keys ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_display_send_keys (<em class="parameter"><code><span class="type">SpiceDisplay</span> *display</code></em>,
+ <em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> *keyvals</code></em>,
+ <em class="parameter"><code><span class="type">int</span> nkeyvals</code></em>,
+ <em class="parameter"><code><a class="link" href="spice-gtk-SpiceDisplay.html#SpiceDisplayKeyEvent" title="enum SpiceDisplayKeyEvent"><span class="type">SpiceDisplayKeyEvent</span></a> kind</code></em>);</pre>
+<p>Send keyval press/release events to the display.</p>
+<div class="refsect3">
+<a name="spice-display-send-keys.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>display</p></td>
+<td class="parameter_description"><p>The <span class="type">SpiceDisplay</span></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>keyvals</p></td>
+<td class="parameter_description"><p> Keyval array. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=nkeyvals]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>nkeyvals</p></td>
+<td class="parameter_description"><p>Length of keyvals</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>kind</p></td>
+<td class="parameter_description"><p><a class="link" href="spice-gtk-SpiceDisplay.html#SpiceDisplayKeyEvent" title="enum SpiceDisplayKeyEvent"><span class="type">SpiceDisplayKeyEvent</span></a> action</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-display-get-pixbuf"></a><h3>spice_display_get_pixbuf ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/gdk-pixbufgdk-pixbuf-The-GdkPixbuf-Structure.html#GdkPixbuf-struct"><span class="returnvalue">GdkPixbuf</span></a> *
+spice_display_get_pixbuf (<em class="parameter"><code><span class="type">SpiceDisplay</span> *display</code></em>);</pre>
+<p>Take a screenshot of the display.</p>
+<div class="refsect3">
+<a name="spice-display-get-pixbuf.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>display</p></td>
+<td class="parameter_description"><p>a <span class="type">SpiceDisplay</span></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-display-get-pixbuf.returns"></a><h4>Returns</h4>
+<p> a <a href="/usr/share/gtk-doc/html/gdk-pixbufgdk-pixbuf-The-GdkPixbuf-Structure.html#GdkPixbuf-struct"><span class="type">GdkPixbuf</span></a> with the screenshot image buffer. </p>
+<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-grab-sequence-new"></a><h3>spice_grab_sequence_new ()</h3>
+<pre class="programlisting"><a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="returnvalue">SpiceGrabSequence</span></a> *
+spice_grab_sequence_new (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> nkeysyms</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> *keysyms</code></em>);</pre>
+<p>Creates a new grab sequence from a list of keysym values</p>
+<div class="refsect3">
+<a name="spice-grab-sequence-new.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>nkeysyms</p></td>
+<td class="parameter_description"><p>length of <em class="parameter"><code>keysyms</code></em>
+</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>keysyms</p></td>
+<td class="parameter_description"><p> the keysym values. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=nkeysyms]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-grab-sequence-new.returns"></a><h4>Returns</h4>
+<p> a new grab sequence object. </p>
+<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-grab-sequence-new-from-string"></a><h3>spice_grab_sequence_new_from_string ()</h3>
+<pre class="programlisting"><a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="returnvalue">SpiceGrabSequence</span></a> *
+spice_grab_sequence_new_from_string (<em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *str</code></em>);</pre>
+<p>Creates a new <a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="type">SpiceGrabSequence</span></a> from the string representation.</p>
+<div class="refsect3">
+<a name="spice-grab-sequence-new-from-string.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>str</p></td>
+<td class="parameter_description"><p>a string of '+' separated key names (ex: "Control_L+Alt_L")</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-grab-sequence-new-from-string.returns"></a><h4>Returns</h4>
+<p> a new <a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="type">SpiceGrabSequence</span></a>.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-grab-sequence-copy"></a><h3>spice_grab_sequence_copy ()</h3>
+<pre class="programlisting"><a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="returnvalue">SpiceGrabSequence</span></a> *
+spice_grab_sequence_copy (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="type">SpiceGrabSequence</span></a> *sequence</code></em>);</pre>
+<p>Creates a copy of the <em class="parameter"><code>sequence</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-grab-sequence-copy.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>sequence</p></td>
+<td class="parameter_description"><p>sequence to copy</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-grab-sequence-copy.returns"></a><h4>Returns</h4>
+<p> a copy of <em class="parameter"><code>sequence</code></em>
+. </p>
+<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-grab-sequence-free"></a><h3>spice_grab_sequence_free ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_grab_sequence_free (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="type">SpiceGrabSequence</span></a> *sequence</code></em>);</pre>
+<p>Free <em class="parameter"><code>sequence</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-grab-sequence-free.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>sequence</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="type">SpiceGrabSequence</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-grab-sequence-as-string"></a><h3>spice_grab_sequence_as_string ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+spice_grab_sequence_as_string (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="type">SpiceGrabSequence</span></a> *sequence</code></em>);</pre>
+<p>Creates a string representing the <em class="parameter"><code>sequence</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-grab-sequence-as-string.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>sequence</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceDisplay.html#SpiceGrabSequence"><span class="type">SpiceGrabSequence</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-grab-sequence-as-string.returns"></a><h4>Returns</h4>
+<p> a newly allocated string representing the key sequence. </p>
+<p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceDisplay.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceDisplayKeyEvent"></a><h3>enum SpiceDisplayKeyEvent</h3>
+<p>Constants for key events.</p>
+<div class="refsect3">
+<a name="SpiceDisplayKeyEvent.members"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-DISPLAY-KEY-EVENT-PRESS:CAPS"></a>SPICE_DISPLAY_KEY_EVENT_PRESS</p></td>
+<td class="enum_member_description">
+<p>key press</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-DISPLAY-KEY-EVENT-RELEASE:CAPS"></a>SPICE_DISPLAY_KEY_EVENT_RELEASE</p></td>
+<td class="enum_member_description">
+<p>key release</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="SPICE-DISPLAY-KEY-EVENT-CLICK:CAPS"></a>SPICE_DISPLAY_KEY_EVENT_CLICK</p></td>
+<td class="enum_member_description">
+<p>key click (press and release)</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceGrabSequence-struct"></a><h3>SpiceGrabSequence</h3>
+<pre class="programlisting">typedef struct _SpiceGrabSequence SpiceGrabSequence;</pre>
+<p>An opaque type that represents a grab sequence.</p>
+</div>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Spice GTK Session: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch03.html" title="GTK Widget, from spice-client-gtk">
+<link rel="prev" href="ch03.html" title="GTK Widget, from spice-client-gtk">
+<link rel="next" href="spice-gtk-SpiceDisplay.html" title="Spice Display">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#spice-gtk-SpiceGtkSession.description" class="shortcut">Description</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch03.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="ch03.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="spice-gtk-SpiceDisplay.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="spice-gtk-SpiceGtkSession"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="spice-gtk-SpiceGtkSession.top_of_page"></a>Spice GTK Session</span></h2>
+<p>Spice GTK Session — handles GTK connection details</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceGtkSession.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceGtkSession.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<span class="returnvalue">SpiceGtkSession</span> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceGtkSession.html#spice-gtk-session-get" title="spice_gtk_session_get ()">spice_gtk_session_get</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceGtkSession.html#spice-gtk-session-copy-to-guest" title="spice_gtk_session_copy_to_guest ()">spice_gtk_session_copy_to_guest</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceGtkSession.html#spice-gtk-session-paste-from-guest" title="spice_gtk_session_paste_from_guest ()">spice_gtk_session_paste_from_guest</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceGtkSession.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client-gtk.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceGtkSession.description"></a><h2>Description</h2>
+<p>The <span class="type">SpiceGtkSession</span> class is the spice-client-gtk counter part of
+<a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a>. It contains functionality which should be handled per
+session rather then per <span class="type">SpiceDisplay</span> (one session can have multiple
+displays), but which cannot live in <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> as it depends on
+GTK. For example the clipboard functionality.</p>
+<p>There should always be a 1:1 relation between <span class="type">SpiceGtkSession</span> objects
+and <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> objects. Therefor there is no spice_gtk_session_new,
+instead there is <a class="link" href="spice-gtk-SpiceGtkSession.html#spice-gtk-session-get" title="spice_gtk_session_get ()"><code class="function">spice_gtk_session_get()</code></a> which ensures this 1:1 relation.</p>
+<p>Client and guest clipboards will be shared automatically if
+<span class="type">“auto-clipboard”</span> is set to <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><span class="type">TRUE</span></a>. Alternatively, you
+can send / receive clipboard data from client to guest with
+<a class="link" href="spice-gtk-SpiceGtkSession.html#spice-gtk-session-copy-to-guest" title="spice_gtk_session_copy_to_guest ()"><code class="function">spice_gtk_session_copy_to_guest()</code></a> / <a class="link" href="spice-gtk-SpiceGtkSession.html#spice-gtk-session-paste-from-guest" title="spice_gtk_session_paste_from_guest ()"><code class="function">spice_gtk_session_paste_from_guest()</code></a>.</p>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceGtkSession.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-gtk-session-get"></a><h3>spice_gtk_session_get ()</h3>
+<pre class="programlisting"><span class="returnvalue">SpiceGtkSession</span> *
+spice_gtk_session_get (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>);</pre>
+<p>Gets the <span class="type">SpiceGtkSession</span> associated with the passed in <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a>.
+A new <span class="type">SpiceGtkSession</span> instance will be created the first time this
+function is called for a certain <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a>.</p>
+<p>Note that this function returns a weak reference, which should not be used
+after the <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> itself has been unref-ed by the caller.</p>
+<div class="refsect3">
+<a name="spice-gtk-session-get.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> for which to get the <span class="type">SpiceGtkSession</span></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-gtk-session-get.returns"></a><h4>Returns</h4>
+<p> a weak reference to the <span class="type">SpiceGtkSession</span> associated with the passed in <a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a></p>
+<p>Since 0.8. </p>
+<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-gtk-session-copy-to-guest"></a><h3>spice_gtk_session_copy_to_guest ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_gtk_session_copy_to_guest (<em class="parameter"><code><span class="type">SpiceGtkSession</span> *self</code></em>);</pre>
+<p>Copy client-side clipboard to guest clipboard.</p>
+<p>Since 0.8</p>
+<div class="refsect3">
+<a name="spice-gtk-session-copy-to-guest.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p><span class="type">SpiceGtkSession</span></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-gtk-session-paste-from-guest"></a><h3>spice_gtk_session_paste_from_guest ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_gtk_session_paste_from_guest (<em class="parameter"><code><span class="type">SpiceGtkSession</span> *self</code></em>);</pre>
+<p>Copy guest clipboard to client-side clipboard.</p>
+<p>Since 0.8</p>
+<div class="refsect3">
+<a name="spice-gtk-session-paste-from-guest.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>self</p></td>
+<td class="parameter_description"><p><span class="type">SpiceGtkSession</span></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceGtkSession.other_details"></a><h2>Types and Values</h2>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceGtkSession.see-also"></a><h2>See Also</h2>
+<p><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a>, and the GTK widget <span class="type">SpiceDisplay</span></p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>SpiceURI: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="application-support.html" title="Application Support, from spice-client-glib">
+<link rel="prev" href="spice-gtk-Version-Information.html" title="Version Information">
+<link rel="next" href="SpiceFileTransferTask.html" title="File Transfer Task">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#spice-gtk-SpiceURI.description" class="shortcut">Description</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="application-support.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="spice-gtk-Version-Information.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="SpiceFileTransferTask.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="spice-gtk-SpiceURI"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="spice-gtk-SpiceURI.top_of_page"></a>SpiceURI</span></h2>
+<p>SpiceURI — URIs handling</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceURI.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceURI.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-get-scheme" title="spice_uri_get_scheme ()">spice_uri_get_scheme</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-set-scheme" title="spice_uri_set_scheme ()">spice_uri_set_scheme</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-get-hostname" title="spice_uri_get_hostname ()">spice_uri_get_hostname</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-set-hostname" title="spice_uri_set_hostname ()">spice_uri_set_hostname</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="returnvalue">guint</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-get-port" title="spice_uri_get_port ()">spice_uri_get_port</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-set-port" title="spice_uri_set_port ()">spice_uri_set_port</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-get-user" title="spice_uri_get_user ()">spice_uri_get_user</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-set-user" title="spice_uri_set_user ()">spice_uri_set_user</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-get-password" title="spice_uri_get_password ()">spice_uri_get_password</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-set-password" title="spice_uri_set_password ()">spice_uri_set_password</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceURI.html#spice-uri-to-string" title="spice_uri_to_string ()">spice_uri_to_string</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceURI.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="datatype_keyword"> </td>
+<td class="function_name"><a class="link" href="spice-gtk-SpiceURI.html#SpiceURIClass" title="SpiceURIClass">SpiceURIClass</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword"> </td>
+<td class="function_name"><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI">SpiceURI</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceURI.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceURI.description"></a><h2>Description</h2>
+<p>A SpiceURI represents a (parsed) URI.</p>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceURI.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-uri-get-scheme"></a><h3>spice_uri_get_scheme ()</h3>
+<pre class="programlisting">const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+spice_uri_get_scheme (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> *uri</code></em>);</pre>
+<p>Gets <em class="parameter"><code>uri</code></em>
+'s scheme.</p>
+<div class="refsect3">
+<a name="spice-uri-get-scheme.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>uri</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-uri-get-scheme.returns"></a><h4>Returns</h4>
+<p> <em class="parameter"><code>uri</code></em>
+'s scheme.</p>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-uri-set-scheme"></a><h3>spice_uri_set_scheme ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_uri_set_scheme (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> *uri</code></em>,
+ <em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *scheme</code></em>);</pre>
+<p>Sets <em class="parameter"><code>uri</code></em>
+'s scheme to <em class="parameter"><code>scheme</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-uri-set-scheme.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>uri</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>scheme</p></td>
+<td class="parameter_description"><p>the scheme</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-uri-get-hostname"></a><h3>spice_uri_get_hostname ()</h3>
+<pre class="programlisting">const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+spice_uri_get_hostname (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> *uri</code></em>);</pre>
+<p>Gets <em class="parameter"><code>uri</code></em>
+'s hostname.</p>
+<div class="refsect3">
+<a name="spice-uri-get-hostname.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>uri</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-uri-get-hostname.returns"></a><h4>Returns</h4>
+<p> <em class="parameter"><code>uri</code></em>
+'s hostname.</p>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-uri-set-hostname"></a><h3>spice_uri_set_hostname ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_uri_set_hostname (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> *uri</code></em>,
+ <em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *hostname</code></em>);</pre>
+<p>Sets <em class="parameter"><code>uri</code></em>
+'s hostname to <em class="parameter"><code>hostname</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-uri-set-hostname.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>uri</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>hostname</p></td>
+<td class="parameter_description"><p>the hostname</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-uri-get-port"></a><h3>spice_uri_get_port ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="returnvalue">guint</span></a>
+spice_uri_get_port (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> *uri</code></em>);</pre>
+<p>Gets <em class="parameter"><code>uri</code></em>
+'s port.</p>
+<div class="refsect3">
+<a name="spice-uri-get-port.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>uri</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-uri-get-port.returns"></a><h4>Returns</h4>
+<p> <em class="parameter"><code>uri</code></em>
+'s port.</p>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-uri-set-port"></a><h3>spice_uri_set_port ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_uri_set_port (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> *uri</code></em>,
+ <em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint"><span class="type">guint</span></a> port</code></em>);</pre>
+<p>Sets <em class="parameter"><code>uri</code></em>
+'s port to <em class="parameter"><code>port</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-uri-set-port.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>uri</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>port</p></td>
+<td class="parameter_description"><p>the port</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-uri-get-user"></a><h3>spice_uri_get_user ()</h3>
+<pre class="programlisting">const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+spice_uri_get_user (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> *uri</code></em>);</pre>
+<p>Gets <em class="parameter"><code>uri</code></em>
+'s user.</p>
+<div class="refsect3">
+<a name="spice-uri-get-user.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>uri</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-uri-get-user.returns"></a><h4>Returns</h4>
+<p> <em class="parameter"><code>uri</code></em>
+'s user.</p>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-uri-set-user"></a><h3>spice_uri_set_user ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_uri_set_user (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> *uri</code></em>,
+ <em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *user</code></em>);</pre>
+<p>Sets <em class="parameter"><code>uri</code></em>
+'s user to <em class="parameter"><code>user</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-uri-set-user.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>uri</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>user</p></td>
+<td class="parameter_description"><p>the user, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-uri-get-password"></a><h3>spice_uri_get_password ()</h3>
+<pre class="programlisting">const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+spice_uri_get_password (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> *uri</code></em>);</pre>
+<p>Gets <em class="parameter"><code>uri</code></em>
+'s password.</p>
+<div class="refsect3">
+<a name="spice-uri-get-password.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>uri</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-uri-get-password.returns"></a><h4>Returns</h4>
+<p> <em class="parameter"><code>uri</code></em>
+'s password.</p>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-uri-set-password"></a><h3>spice_uri_set_password ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_uri_set_password (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> *uri</code></em>,
+ <em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *password</code></em>);</pre>
+<p>Sets <em class="parameter"><code>uri</code></em>
+'s password to <em class="parameter"><code>password</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-uri-set-password.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>uri</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>password</p></td>
+<td class="parameter_description"><p>the password, or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-uri-to-string"></a><h3>spice_uri_to_string ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+spice_uri_to_string (<em class="parameter"><code><a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> *uri</code></em>);</pre>
+<p>Returns a string representing <em class="parameter"><code>uri</code></em>
+.</p>
+<div class="refsect3">
+<a name="spice-uri-to-string.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>uri</p></td>
+<td class="parameter_description"><p>a <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-uri-to-string.returns"></a><h4>Returns</h4>
+<p> a string representing <em class="parameter"><code>uri</code></em>
+, which the caller must free.</p>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceURI.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SpiceURIClass"></a><h3>SpiceURIClass</h3>
+<pre class="programlisting">typedef struct _SpiceURIClass SpiceURIClass;</pre>
+<p>The <a class="link" href="spice-gtk-SpiceURI.html#SpiceURIClass" title="SpiceURIClass"><span class="type">SpiceURIClass</span></a> struct is opaque and cannot be accessed directly.
+It is class structure for <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a>.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SpiceURI"></a><h3>SpiceURI</h3>
+<pre class="programlisting">typedef struct _SpiceURI SpiceURI;</pre>
+<p>The <a class="link" href="spice-gtk-SpiceURI.html#SpiceURI" title="SpiceURI"><span class="type">SpiceURI</span></a> struct is opaque and cannot be accessed directly.</p>
+</div>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Spice USB device selection widget: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="ch03.html" title="GTK Widget, from spice-client-gtk">
+<link rel="prev" href="spice-gtk-SpiceDisplay.html" title="Spice Display">
+<link rel="next" href="application-support.html" title="Application Support, from spice-client-glib">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#spice-gtk-SpiceUsbDeviceWidget.description" class="shortcut">Description</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch03.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="spice-gtk-SpiceDisplay.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="application-support.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="spice-gtk-SpiceUsbDeviceWidget"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="spice-gtk-SpiceUsbDeviceWidget.top_of_page"></a>Spice USB device selection widget</span></h2>
+<p>Spice USB device selection widget — USB device selection widget</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceUsbDeviceWidget.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceUsbDeviceWidget.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody><tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/gtk3GtkWidget.html#GtkWidget-struct"><span class="returnvalue">GtkWidget</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-SpiceUsbDeviceWidget.html#spice-usb-device-widget-new" title="spice_usb_device_widget_new ()">spice_usb_device_widget_new</a> <span class="c_punctuation">()</span>
+</td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceUsbDeviceWidget.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client-gtk.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceUsbDeviceWidget.description"></a><h2>Description</h2>
+<p><span class="type">SpiceUsbDeviceWidget</span> is a gtk widget which apps can use to easily
+add an UI to select USB devices to redirect (or unredirect).</p>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceUsbDeviceWidget.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-usb-device-widget-new"></a><h3>spice_usb_device_widget_new ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/gtk3GtkWidget.html#GtkWidget-struct"><span class="returnvalue">GtkWidget</span></a> *
+spice_usb_device_widget_new (<em class="parameter"><code><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> *session</code></em>,
+ <em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *device_format_string</code></em>);</pre>
+<p>Creates a new widget to control USB redirection.</p>
+<div class="refsect3">
+<a name="spice-usb-device-widget-new.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>session</p></td>
+<td class="parameter_description"><p><a class="link" href="SpiceSession.html" title="Spice Session"><span class="type">SpiceSession</span></a> for which to widget will control USB redirection</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>device_format_string</p></td>
+<td class="parameter_description"><p> String passed to
+<a class="link" href="SpiceUsbDeviceManager.html#spice-usb-device-get-description" title="spice_usb_device_get_description ()"><code class="function">spice_usb_device_get_description()</code></a>. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-usb-device-widget-new.returns"></a><h4>Returns</h4>
+<p> a new <span class="type">SpiceUsbDeviceWidget</span> instance</p>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-SpiceUsbDeviceWidget.other_details"></a><h2>Types and Values</h2>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Utilities: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="application-support.html" title="Application Support, from spice-client-glib">
+<link rel="prev" href="SpiceUsbDeviceManager.html" title="Spice USB Manager">
+<link rel="next" href="spice-gtk-Version-Information.html" title="Version Information">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#spice-gtk-Utilities.description" class="shortcut">Description</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="application-support.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="SpiceUsbDeviceManager.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="spice-gtk-Version-Information.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="spice-gtk-Utilities"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="spice-gtk-Utilities.top_of_page"></a>Utilities</span></h2>
+<p>Utilities — version and debugging functions</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="spice-gtk-Utilities.stability-level"></a><h2>Stability Level</h2>
+<acronym title="The intention of a Stable interface is to enable arbitrary third parties to
+develop applications to these interfaces, release them, and have confidence that
+they will run on all minor releases of the product (after the one in which the
+interface was introduced, and within the same major release). Even at a major
+release, incompatible changes are expected to be rare, and to have strong
+justifications.
+"><span class="acronym">Stable</span></acronym>, unless otherwise indicated
+</div>
+<div class="refsect1">
+<a name="spice-gtk-Utilities.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-Utilities.html#spice-util-set-debug" title="spice_util_set_debug ()">spice_util_set_debug</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-Utilities.html#spice-util-get-version-string" title="spice_util_get_version_string ()">spice_util_get_version_string</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-Utilities.html#spice-uuid-to-string" title="spice_uuid_to_string ()">spice_uuid_to_string</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-Utilities.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-client.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-Utilities.description"></a><h2>Description</h2>
+<p>Various functions for debugging and informational purposes.</p>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-Utilities.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="spice-util-set-debug"></a><h3>spice_util_set_debug ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+spice_util_set_debug (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gboolean"><span class="type">gboolean</span></a> enabled</code></em>);</pre>
+<p>Enable or disable Spice-GTK debugging messages.</p>
+<div class="refsect3">
+<a name="spice-util-set-debug.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>enabled</p></td>
+<td class="parameter_description"><p><a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> or <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a></p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-util-get-version-string"></a><h3>spice_util_get_version_string ()</h3>
+<pre class="programlisting">const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+spice_util_get_version_string (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p>Gets the version string</p>
+<div class="refsect3">
+<a name="spice-util-get-version-string.returns"></a><h4>Returns</h4>
+<p> Spice-GTK version as a const string.</p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="spice-uuid-to-string"></a><h3>spice_uuid_to_string ()</h3>
+<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+spice_uuid_to_string (<em class="parameter"><code>const <a href="/usr/share/gtk-doc/html/glibglib-Basic-Types.html#guint8"><span class="type">guint8</span></a> uuid[16]</code></em>);</pre>
+<p>Creates a string representation of <em class="parameter"><code>uuid</code></em>
+, of the form
+"06e023d5-86d8-420e-8103-383e4566087a"</p>
+<div class="refsect3">
+<a name="spice-uuid-to-string.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>uuid</p></td>
+<td class="parameter_description"><p>UUID byte array</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="spice-uuid-to-string.returns"></a><h4>Returns</h4>
+<p> A string that should be freed with <a href="/usr/share/gtk-doc/html/glibglib-Memory-Allocation.html#g-free"><code class="function">g_free()</code></a>.</p>
+</div>
+<p class="since">Since: 0.22</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-Utilities.other_details"></a><h2>Types and Values</h2>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Version Information: Spice-GTK Reference Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="Spice-GTK Reference Manual">
+<link rel="up" href="application-support.html" title="Application Support, from spice-client-glib">
+<link rel="prev" href="spice-gtk-Utilities.html" title="Utilities">
+<link rel="next" href="spice-gtk-SpiceURI.html" title="SpiceURI">
+<meta name="generator" content="GTK-Doc V1.25 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span>
+ <a href="#spice-gtk-Version-Information.description" class="shortcut">Description</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="application-support.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="spice-gtk-Utilities.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="spice-gtk-SpiceURI.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="spice-gtk-Version-Information"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="spice-gtk-Version-Information.top_of_page"></a>Version Information</span></h2>
+<p>Version Information — Spice-Gtk version checking</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="spice-gtk-Version-Information.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody><tr>
+<td class="define_keyword">#define</td>
+<td class="function_name">
+<a class="link" href="spice-gtk-Version-Information.html#SPICE-GTK-CHECK-VERSION:CAPS" title="SPICE_GTK_CHECK_VERSION()">SPICE_GTK_CHECK_VERSION</a><span class="c_punctuation">()</span>
+</td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-Version-Information.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="spice-gtk-Version-Information.html#SPICE-GTK-MAJOR-VERSION:CAPS" title="SPICE_GTK_MAJOR_VERSION">SPICE_GTK_MAJOR_VERSION</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="spice-gtk-Version-Information.html#SPICE-GTK-MICRO-VERSION:CAPS" title="SPICE_GTK_MICRO_VERSION">SPICE_GTK_MICRO_VERSION</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="spice-gtk-Version-Information.html#SPICE-GTK-MINOR-VERSION:CAPS" title="SPICE_GTK_MINOR_VERSION">SPICE_GTK_MINOR_VERSION</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-Version-Information.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include <spice-version.h>
+</pre>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-Version-Information.description"></a><h2>Description</h2>
+<p>Spice-Gtk provides macros to check the version of the library
+at compile-time</p>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-Version-Information.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="SPICE-GTK-CHECK-VERSION:CAPS"></a><h3>SPICE_GTK_CHECK_VERSION()</h3>
+<pre class="programlisting">#define SPICE_GTK_CHECK_VERSION(major, minor, micro)</pre>
+<p>Compile-time version checking. Evaluates to <a href="/usr/share/gtk-doc/html/glibglib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if the version
+of Spice-Gtk is greater than the required one.</p>
+<div class="refsect3">
+<a name="SPICE-GTK-CHECK-VERSION.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>major</p></td>
+<td class="parameter_description"><p>required major version</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>minor</p></td>
+<td class="parameter_description"><p>required minor version</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>micro</p></td>
+<td class="parameter_description"><p>required micro version</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: 0.24</p>
+</div>
+</div>
+<div class="refsect1">
+<a name="spice-gtk-Version-Information.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="SPICE-GTK-MAJOR-VERSION:CAPS"></a><h3>SPICE_GTK_MAJOR_VERSION</h3>
+<pre class="programlisting">#define SPICE_GTK_MAJOR_VERSION (0)
+</pre>
+<p>Spice-Gtk major version component (e.g. 1 if version is 1.2.3)</p>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SPICE-GTK-MICRO-VERSION:CAPS"></a><h3>SPICE_GTK_MICRO_VERSION</h3>
+<pre class="programlisting">#define SPICE_GTK_MICRO_VERSION (0)
+</pre>
+<p>Spice-Gtk micro version component (e.g. 3 if version is 1.2.3)</p>
+<p class="since">Since: 0.24</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="SPICE-GTK-MINOR-VERSION:CAPS"></a><h3>SPICE_GTK_MINOR_VERSION</h3>
+<pre class="programlisting">#define SPICE_GTK_MINOR_VERSION (33)
+</pre>
+<p>Spice-Gtk minor version component (e.g. 2 if version is 1.2.3)</p>
+<p class="since">Since: 0.24</p>
+</div>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.25</div>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<book xmlns="http://www.devhelp.net/book" title="Spice-GTK Reference Manual" link="index.html" author="" name="spice-gtk" version="2" language="c">
+ <chapters>
+ <sub name="API Reference" link="api-reference.html">
+ <sub name="Object Hierarchy" link="ch01.html"/>
+ <sub name="Session and Channels Objects, from spice-client-glib" link="ch02.html">
+ <sub name="Spice Session" link="SpiceSession.html"/>
+ <sub name="Spice Channel" link="SpiceChannel.html"/>
+ <sub name="Cursor Channel" link="SpiceCursorChannel.html"/>
+ <sub name="Display Channel" link="SpiceDisplayChannel.html"/>
+ <sub name="Inputs Channel" link="SpiceInputsChannel.html"/>
+ <sub name="Main Channel" link="SpiceMainChannel.html"/>
+ <sub name="Playback Channel" link="SpicePlaybackChannel.html"/>
+ <sub name="Record Channel" link="SpiceRecordChannel.html"/>
+ <sub name="Smartcard Channel" link="SpiceSmartcardChannel.html"/>
+ <sub name="USB Redirection Channel" link="SpiceUsbredirChannel.html"/>
+ <sub name="Port Channel" link="SpicePortChannel.html"/>
+ <sub name="WebDAV Channel" link="SpiceWebdavChannel.html"/>
+ </sub>
+ <sub name="GTK Widget, from spice-client-gtk" link="ch03.html">
+ <sub name="Spice GTK Session" link="spice-gtk-SpiceGtkSession.html"/>
+ <sub name="Spice Display" link="spice-gtk-SpiceDisplay.html"/>
+ <sub name="Spice USB device selection widget" link="spice-gtk-SpiceUsbDeviceWidget.html"/>
+ </sub>
+ <sub name="Application Support, from spice-client-glib" link="application-support.html">
+ <sub name="Spice Audio" link="SpiceAudio.html"/>
+ <sub name="Spice Smartcard Manager" link="SpiceSmartcardManager.html"/>
+ <sub name="Spice USB Manager" link="SpiceUsbDeviceManager.html"/>
+ <sub name="Utilities" link="spice-gtk-Utilities.html"/>
+ <sub name="Version Information" link="spice-gtk-Version-Information.html"/>
+ <sub name="SpiceURI" link="spice-gtk-SpiceURI.html"/>
+ <sub name="File Transfer Task" link="SpiceFileTransferTask.html"/>
+ </sub>
+ </sub>
+ <sub name="Object Hierarchy" link="object-tree.html"/>
+ <sub name="API Index" link="api-index-full.html"/>
+ <sub name="Index of deprecated symbols" link="api-index-deprecated.html"/>
+ <sub name="Annotation Glossary" link="annotation-glossary.html"/>
+ </chapters>
+ <functions>
+ <keyword type="function" name="spice_session_new ()" link="SpiceSession.html#spice-session-new"/>
+ <keyword type="function" name="spice_session_connect ()" link="SpiceSession.html#spice-session-connect"/>
+ <keyword type="function" name="spice_session_open_fd ()" link="SpiceSession.html#spice-session-open-fd"/>
+ <keyword type="function" name="spice_session_disconnect ()" link="SpiceSession.html#spice-session-disconnect"/>
+ <keyword type="function" name="spice_session_get_channels ()" link="SpiceSession.html#spice-session-get-channels"/>
+ <keyword type="function" name="spice_session_get_read_only ()" link="SpiceSession.html#spice-session-get-read-only"/>
+ <keyword type="function" name="spice_session_has_channel_type ()" link="SpiceSession.html#spice-session-has-channel-type"/>
+ <keyword type="function" name="spice_session_get_proxy_uri ()" link="SpiceSession.html#spice-session-get-proxy-uri" since="0.24"/>
+ <keyword type="function" name="spice_session_is_for_migration ()" link="SpiceSession.html#spice-session-is-for-migration" since="0.27"/>
+ <keyword type="function" name="spice_get_option_group ()" link="SpiceSession.html#spice-get-option-group"/>
+ <keyword type="function" name="spice_set_session_option ()" link="SpiceSession.html#spice-set-session-option"/>
+ <keyword type="function" name="spice_client_error_quark ()" link="SpiceSession.html#spice-client-error-quark"/>
+ <keyword type="struct" name="SpiceSession" link="SpiceSession.html#SpiceSession-struct"/>
+ <keyword type="struct" name="SpiceSessionClass" link="SpiceSession.html#SpiceSessionClass"/>
+ <keyword type="enum" name="enum SpiceSessionMigration" link="SpiceSession.html#SpiceSessionMigration"/>
+ <keyword type="enum" name="enum SpiceSessionVerify" link="SpiceSession.html#SpiceSessionVerify"/>
+ <keyword type="enum" name="enum SpiceClientError" link="SpiceSession.html#SpiceClientError"/>
+ <keyword type="macro" name="SPICE_CLIENT_ERROR" link="SpiceSession.html#SPICE-CLIENT-ERROR:CAPS"/>
+ <keyword type="property" name="The “ca” property" link="SpiceSession.html#SpiceSession--ca"/>
+ <keyword type="property" name="The “ca-file” property" link="SpiceSession.html#SpiceSession--ca-file"/>
+ <keyword type="property" name="The “cache-size” property" link="SpiceSession.html#SpiceSession--cache-size"/>
+ <keyword type="property" name="The “cert-subject” property" link="SpiceSession.html#SpiceSession--cert-subject"/>
+ <keyword type="property" name="The “ciphers” property" link="SpiceSession.html#SpiceSession--ciphers"/>
+ <keyword type="property" name="The “client-sockets” property" link="SpiceSession.html#SpiceSession--client-sockets"/>
+ <keyword type="property" name="The “color-depth” property" link="SpiceSession.html#SpiceSession--color-depth"/>
+ <keyword type="property" name="The “disable-effects” property" link="SpiceSession.html#SpiceSession--disable-effects"/>
+ <keyword type="property" name="The “enable-audio” property" link="SpiceSession.html#SpiceSession--enable-audio"/>
+ <keyword type="property" name="The “enable-smartcard” property" link="SpiceSession.html#SpiceSession--enable-smartcard"/>
+ <keyword type="property" name="The “enable-usbredir” property" link="SpiceSession.html#SpiceSession--enable-usbredir"/>
+ <keyword type="property" name="The “glz-window-size” property" link="SpiceSession.html#SpiceSession--glz-window-size"/>
+ <keyword type="property" name="The “host” property" link="SpiceSession.html#SpiceSession--host"/>
+ <keyword type="property" name="The “inhibit-keyboard-grab” property" link="SpiceSession.html#SpiceSession--inhibit-keyboard-grab"/>
+ <keyword type="property" name="The “migration-state” property" link="SpiceSession.html#SpiceSession--migration-state"/>
+ <keyword type="property" name="The “name” property" link="SpiceSession.html#SpiceSession--name"/>
+ <keyword type="property" name="The “password” property" link="SpiceSession.html#SpiceSession--password"/>
+ <keyword type="property" name="The “port” property" link="SpiceSession.html#SpiceSession--port"/>
+ <keyword type="property" name="The “preferred-compression” property" link="SpiceSession.html#SpiceSession--preferred-compression"/>
+ <keyword type="property" name="The “protocol” property" link="SpiceSession.html#SpiceSession--protocol"/>
+ <keyword type="property" name="The “proxy” property" link="SpiceSession.html#SpiceSession--proxy"/>
+ <keyword type="property" name="The “pubkey” property" link="SpiceSession.html#SpiceSession--pubkey"/>
+ <keyword type="property" name="The “read-only” property" link="SpiceSession.html#SpiceSession--read-only"/>
+ <keyword type="property" name="The “secure-channels” property" link="SpiceSession.html#SpiceSession--secure-channels"/>
+ <keyword type="property" name="The “share-dir-ro” property" link="SpiceSession.html#SpiceSession--share-dir-ro"/>
+ <keyword type="property" name="The “shared-dir” property" link="SpiceSession.html#SpiceSession--shared-dir"/>
+ <keyword type="property" name="The “smartcard-certificates” property" link="SpiceSession.html#SpiceSession--smartcard-certificates"/>
+ <keyword type="property" name="The “smartcard-db” property" link="SpiceSession.html#SpiceSession--smartcard-db"/>
+ <keyword type="property" name="The “tls-port” property" link="SpiceSession.html#SpiceSession--tls-port"/>
+ <keyword type="property" name="The “unix-path” property" link="SpiceSession.html#SpiceSession--unix-path"/>
+ <keyword type="property" name="The “uri” property" link="SpiceSession.html#SpiceSession--uri"/>
+ <keyword type="property" name="The “username” property" link="SpiceSession.html#SpiceSession--username"/>
+ <keyword type="property" name="The “uuid” property" link="SpiceSession.html#SpiceSession--uuid"/>
+ <keyword type="property" name="The “verify” property" link="SpiceSession.html#SpiceSession--verify"/>
+ <keyword type="signal" name="The “channel-destroy” signal" link="SpiceSession.html#SpiceSession-channel-destroy"/>
+ <keyword type="signal" name="The “channel-new” signal" link="SpiceSession.html#SpiceSession-channel-new"/>
+ <keyword type="signal" name="The “mm-time-reset” signal" link="SpiceSession.html#SpiceSession-mm-time-reset"/>
+ <keyword type="function" name="spice_channel_new ()" link="SpiceChannel.html#spice-channel-new"/>
+ <keyword type="function" name="spice_channel_destroy ()" link="SpiceChannel.html#spice-channel-destroy" deprecated=""/>
+ <keyword type="function" name="spice_channel_connect ()" link="SpiceChannel.html#spice-channel-connect"/>
+ <keyword type="function" name="spice_channel_open_fd ()" link="SpiceChannel.html#spice-channel-open-fd"/>
+ <keyword type="function" name="spice_channel_disconnect ()" link="SpiceChannel.html#spice-channel-disconnect"/>
+ <keyword type="function" name="spice_channel_test_capability ()" link="SpiceChannel.html#spice-channel-test-capability"/>
+ <keyword type="function" name="spice_channel_test_common_capability ()" link="SpiceChannel.html#spice-channel-test-common-capability"/>
+ <keyword type="function" name="spice_channel_type_to_string ()" link="SpiceChannel.html#spice-channel-type-to-string" since="0.20"/>
+ <keyword type="function" name="spice_channel_string_to_type ()" link="SpiceChannel.html#spice-channel-string-to-type" since="0.21"/>
+ <keyword type="function" name="spice_channel_set_capability ()" link="SpiceChannel.html#spice-channel-set-capability" deprecated="0.13: this function has been removed"/>
+ <keyword type="function" name="spice_channel_flush_async ()" link="SpiceChannel.html#spice-channel-flush-async" since="0.15"/>
+ <keyword type="function" name="spice_channel_flush_finish ()" link="SpiceChannel.html#spice-channel-flush-finish" since="0.15"/>
+ <keyword type="function" name="spice_channel_get_error ()" link="SpiceChannel.html#spice-channel-get-error" since="0.24"/>
+ <keyword type="enum" name="enum SpiceChannelEvent" link="SpiceChannel.html#SpiceChannelEvent"/>
+ <keyword type="struct" name="SpiceChannel" link="SpiceChannel.html#SpiceChannel-struct"/>
+ <keyword type="struct" name="SpiceChannelClass" link="SpiceChannel.html#SpiceChannelClass"/>
+ <keyword type="property" name="The “channel-id” property" link="SpiceChannel.html#SpiceChannel--channel-id"/>
+ <keyword type="property" name="The “channel-type” property" link="SpiceChannel.html#SpiceChannel--channel-type"/>
+ <keyword type="property" name="The “socket” property" link="SpiceChannel.html#SpiceChannel--socket"/>
+ <keyword type="property" name="The “spice-session” property" link="SpiceChannel.html#SpiceChannel--spice-session"/>
+ <keyword type="property" name="The “total-read-bytes” property" link="SpiceChannel.html#SpiceChannel--total-read-bytes"/>
+ <keyword type="signal" name="The “channel-event” signal" link="SpiceChannel.html#SpiceChannel-channel-event"/>
+ <keyword type="signal" name="The “open-fd” signal" link="SpiceChannel.html#SpiceChannel-open-fd"/>
+ <keyword type="struct" name="struct SpiceCursorChannel" link="SpiceCursorChannel.html#SpiceCursorChannel-struct"/>
+ <keyword type="struct" name="struct SpiceCursorChannelClass" link="SpiceCursorChannel.html#SpiceCursorChannelClass"/>
+ <keyword type="signal" name="The “cursor-hide” signal" link="SpiceCursorChannel.html#SpiceCursorChannel-cursor-hide"/>
+ <keyword type="signal" name="The “cursor-move” signal" link="SpiceCursorChannel.html#SpiceCursorChannel-cursor-move"/>
+ <keyword type="signal" name="The “cursor-reset” signal" link="SpiceCursorChannel.html#SpiceCursorChannel-cursor-reset"/>
+ <keyword type="signal" name="The “cursor-set” signal" link="SpiceCursorChannel.html#SpiceCursorChannel-cursor-set"/>
+ <keyword type="function" name="spice_display_get_gl_scanout ()" link="SpiceDisplayChannel.html#spice-display-get-gl-scanout" since="0.31"/>
+ <keyword type="function" name="spice_display_gl_draw_done ()" link="SpiceDisplayChannel.html#spice-display-gl-draw-done" since="0.31"/>
+ <keyword type="function" name="spice_display_get_primary ()" link="SpiceDisplayChannel.html#spice-display-get-primary"/>
+ <keyword type="function" name="spice_display_change_preferred_compression ()" link="SpiceDisplayChannel.html#spice-display-change-preferred-compression" since="0.31"/>
+ <keyword type="function" name="spice_gl_scanout_free ()" link="SpiceDisplayChannel.html#spice-gl-scanout-free"/>
+ <keyword type="struct" name="struct SpiceDisplayChannel" link="SpiceDisplayChannel.html#SpiceDisplayChannel-struct"/>
+ <keyword type="struct" name="struct SpiceDisplayChannelClass" link="SpiceDisplayChannel.html#SpiceDisplayChannelClass"/>
+ <keyword type="struct" name="struct SpiceDisplayMonitorConfig" link="SpiceDisplayChannel.html#SpiceDisplayMonitorConfig"/>
+ <keyword type="struct" name="struct SpiceDisplayPrimary" link="SpiceDisplayChannel.html#SpiceDisplayPrimary"/>
+ <keyword type="struct" name="struct SpiceGlScanout" link="SpiceDisplayChannel.html#SpiceGlScanout-struct"/>
+ <keyword type="property" name="The “gl-scanout” property" link="SpiceDisplayChannel.html#SpiceDisplayChannel--gl-scanout"/>
+ <keyword type="property" name="The “height” property" link="SpiceDisplayChannel.html#SpiceDisplayChannel--height"/>
+ <keyword type="property" name="The “monitors” property" link="SpiceDisplayChannel.html#SpiceDisplayChannel--monitors"/>
+ <keyword type="property" name="The “monitors-max” property" link="SpiceDisplayChannel.html#SpiceDisplayChannel--monitors-max"/>
+ <keyword type="property" name="The “width” property" link="SpiceDisplayChannel.html#SpiceDisplayChannel--width"/>
+ <keyword type="signal" name="The “display-invalidate” signal" link="SpiceDisplayChannel.html#SpiceDisplayChannel-display-invalidate"/>
+ <keyword type="signal" name="The “display-mark” signal" link="SpiceDisplayChannel.html#SpiceDisplayChannel-display-mark"/>
+ <keyword type="signal" name="The “display-primary-create” signal" link="SpiceDisplayChannel.html#SpiceDisplayChannel-display-primary-create"/>
+ <keyword type="signal" name="The “display-primary-destroy” signal" link="SpiceDisplayChannel.html#SpiceDisplayChannel-display-primary-destroy"/>
+ <keyword type="signal" name="The “gl-draw” signal" link="SpiceDisplayChannel.html#SpiceDisplayChannel-gl-draw"/>
+ <keyword type="function" name="spice_inputs_motion ()" link="SpiceInputsChannel.html#spice-inputs-motion"/>
+ <keyword type="function" name="spice_inputs_position ()" link="SpiceInputsChannel.html#spice-inputs-position"/>
+ <keyword type="function" name="spice_inputs_button_press ()" link="SpiceInputsChannel.html#spice-inputs-button-press"/>
+ <keyword type="function" name="spice_inputs_button_release ()" link="SpiceInputsChannel.html#spice-inputs-button-release"/>
+ <keyword type="function" name="spice_inputs_key_press ()" link="SpiceInputsChannel.html#spice-inputs-key-press"/>
+ <keyword type="function" name="spice_inputs_key_press_and_release ()" link="SpiceInputsChannel.html#spice-inputs-key-press-and-release" since="0.13"/>
+ <keyword type="function" name="spice_inputs_key_release ()" link="SpiceInputsChannel.html#spice-inputs-key-release"/>
+ <keyword type="function" name="spice_inputs_set_key_locks ()" link="SpiceInputsChannel.html#spice-inputs-set-key-locks"/>
+ <keyword type="struct" name="struct SpiceInputsChannel" link="SpiceInputsChannel.html#SpiceInputsChannel-struct"/>
+ <keyword type="struct" name="struct SpiceInputsChannelClass" link="SpiceInputsChannel.html#SpiceInputsChannelClass"/>
+ <keyword type="enum" name="enum SpiceInputsLock" link="SpiceInputsChannel.html#SpiceInputsLock"/>
+ <keyword type="property" name="The “key-modifiers” property" link="SpiceInputsChannel.html#SpiceInputsChannel--key-modifiers"/>
+ <keyword type="signal" name="The “inputs-modifiers” signal" link="SpiceInputsChannel.html#SpiceInputsChannel-inputs-modifiers"/>
+ <keyword type="function" name="spice_main_set_display ()" link="SpiceMainChannel.html#spice-main-set-display"/>
+ <keyword type="function" name="spice_main_set_display_enabled ()" link="SpiceMainChannel.html#spice-main-set-display-enabled" since="0.6"/>
+ <keyword type="function" name="spice_main_update_display ()" link="SpiceMainChannel.html#spice-main-update-display"/>
+ <keyword type="function" name="spice_main_update_display_enabled ()" link="SpiceMainChannel.html#spice-main-update-display-enabled" since="0.30"/>
+ <keyword type="function" name="spice_main_send_monitor_config ()" link="SpiceMainChannel.html#spice-main-send-monitor-config"/>
+ <keyword type="function" name="spice_main_agent_test_capability ()" link="SpiceMainChannel.html#spice-main-agent-test-capability"/>
+ <keyword type="function" name="spice_main_request_mouse_mode ()" link="SpiceMainChannel.html#spice-main-request-mouse-mode" since="0.32"/>
+ <keyword type="function" name="spice_main_clipboard_selection_grab ()" link="SpiceMainChannel.html#spice-main-clipboard-selection-grab" since="0.6"/>
+ <keyword type="function" name="spice_main_clipboard_selection_notify ()" link="SpiceMainChannel.html#spice-main-clipboard-selection-notify" since="0.6"/>
+ <keyword type="function" name="spice_main_clipboard_selection_release ()" link="SpiceMainChannel.html#spice-main-clipboard-selection-release" since="0.6"/>
+ <keyword type="function" name="spice_main_clipboard_selection_request ()" link="SpiceMainChannel.html#spice-main-clipboard-selection-request" since="0.6"/>
+ <keyword type="function" name="spice_main_clipboard_grab ()" link="SpiceMainChannel.html#spice-main-clipboard-grab" deprecated="0.6: use spice_main_clipboard_selection_grab() instead."/>
+ <keyword type="function" name="spice_main_clipboard_release ()" link="SpiceMainChannel.html#spice-main-clipboard-release" deprecated="0.6: use spice_main_clipboard_selection_release() instead."/>
+ <keyword type="function" name="spice_main_clipboard_notify ()" link="SpiceMainChannel.html#spice-main-clipboard-notify" deprecated="0.6: use spice_main_clipboard_selection_notify() instead."/>
+ <keyword type="function" name="spice_main_clipboard_request ()" link="SpiceMainChannel.html#spice-main-clipboard-request" deprecated="0.6: use spice_main_clipboard_selection_request() instead."/>
+ <keyword type="function" name="spice_main_file_copy_async ()" link="SpiceMainChannel.html#spice-main-file-copy-async"/>
+ <keyword type="function" name="spice_main_file_copy_finish ()" link="SpiceMainChannel.html#spice-main-file-copy-finish"/>
+ <keyword type="struct" name="struct SpiceMainChannel" link="SpiceMainChannel.html#SpiceMainChannel-struct"/>
+ <keyword type="struct" name="struct SpiceMainChannelClass" link="SpiceMainChannel.html#SpiceMainChannelClass"/>
+ <keyword type="property" name="The “agent-caps-0” property" link="SpiceMainChannel.html#SpiceMainChannel--agent-caps-0"/>
+ <keyword type="property" name="The “agent-connected” property" link="SpiceMainChannel.html#SpiceMainChannel--agent-connected"/>
+ <keyword type="property" name="The “color-depth” property" link="SpiceMainChannel.html#SpiceMainChannel--color-depth"/>
+ <keyword type="property" name="The “disable-animation” property" link="SpiceMainChannel.html#SpiceMainChannel--disable-animation"/>
+ <keyword type="property" name="The “disable-display-align” property" link="SpiceMainChannel.html#SpiceMainChannel--disable-display-align"/>
+ <keyword type="property" name="The “disable-display-position” property" link="SpiceMainChannel.html#SpiceMainChannel--disable-display-position"/>
+ <keyword type="property" name="The “disable-font-smooth” property" link="SpiceMainChannel.html#SpiceMainChannel--disable-font-smooth"/>
+ <keyword type="property" name="The “disable-wallpaper” property" link="SpiceMainChannel.html#SpiceMainChannel--disable-wallpaper"/>
+ <keyword type="property" name="The “max-clipboard” property" link="SpiceMainChannel.html#SpiceMainChannel--max-clipboard"/>
+ <keyword type="property" name="The “mouse-mode” property" link="SpiceMainChannel.html#SpiceMainChannel--mouse-mode"/>
+ <keyword type="signal" name="The “main-agent-update” signal" link="SpiceMainChannel.html#SpiceMainChannel-main-agent-update"/>
+ <keyword type="signal" name="The “main-clipboard” signal" link="SpiceMainChannel.html#SpiceMainChannel-main-clipboard"/>
+ <keyword type="signal" name="The “main-clipboard-grab” signal" link="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-grab"/>
+ <keyword type="signal" name="The “main-clipboard-release” signal" link="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-release"/>
+ <keyword type="signal" name="The “main-clipboard-request” signal" link="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-request"/>
+ <keyword type="signal" name="The “main-clipboard-selection” signal" link="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection"/>
+ <keyword type="signal" name="The “main-clipboard-selection-grab” signal" link="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection-grab"/>
+ <keyword type="signal" name="The “main-clipboard-selection-release” signal" link="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection-release"/>
+ <keyword type="signal" name="The “main-clipboard-selection-request” signal" link="SpiceMainChannel.html#SpiceMainChannel-main-clipboard-selection-request"/>
+ <keyword type="signal" name="The “main-mouse-update” signal" link="SpiceMainChannel.html#SpiceMainChannel-main-mouse-update"/>
+ <keyword type="signal" name="The “migration-started” signal" link="SpiceMainChannel.html#SpiceMainChannel-migration-started"/>
+ <keyword type="signal" name="The “new-file-transfer” signal" link="SpiceMainChannel.html#SpiceMainChannel-new-file-transfer"/>
+ <keyword type="function" name="spice_playback_channel_set_delay ()" link="SpicePlaybackChannel.html#spice-playback-channel-set-delay"/>
+ <keyword type="struct" name="struct SpicePlaybackChannel" link="SpicePlaybackChannel.html#SpicePlaybackChannel-struct"/>
+ <keyword type="struct" name="struct SpicePlaybackChannelClass" link="SpicePlaybackChannel.html#SpicePlaybackChannelClass"/>
+ <keyword type="property" name="The “min-latency” property" link="SpicePlaybackChannel.html#SpicePlaybackChannel--min-latency"/>
+ <keyword type="property" name="The “mute” property" link="SpicePlaybackChannel.html#SpicePlaybackChannel--mute"/>
+ <keyword type="property" name="The “nchannels” property" link="SpicePlaybackChannel.html#SpicePlaybackChannel--nchannels"/>
+ <keyword type="property" name="The “volume” property" link="SpicePlaybackChannel.html#SpicePlaybackChannel--volume"/>
+ <keyword type="signal" name="The “playback-data” signal" link="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-data"/>
+ <keyword type="signal" name="The “playback-get-delay” signal" link="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-get-delay"/>
+ <keyword type="signal" name="The “playback-start” signal" link="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-start"/>
+ <keyword type="signal" name="The “playback-stop” signal" link="SpicePlaybackChannel.html#SpicePlaybackChannel-playback-stop"/>
+ <keyword type="function" name="spice_record_send_data ()" link="SpiceRecordChannel.html#spice-record-send-data"/>
+ <keyword type="struct" name="struct SpiceRecordChannel" link="SpiceRecordChannel.html#SpiceRecordChannel-struct"/>
+ <keyword type="struct" name="struct SpiceRecordChannelClass" link="SpiceRecordChannel.html#SpiceRecordChannelClass"/>
+ <keyword type="property" name="The “mute” property" link="SpiceRecordChannel.html#SpiceRecordChannel--mute"/>
+ <keyword type="property" name="The “nchannels” property" link="SpiceRecordChannel.html#SpiceRecordChannel--nchannels"/>
+ <keyword type="property" name="The “volume” property" link="SpiceRecordChannel.html#SpiceRecordChannel--volume"/>
+ <keyword type="signal" name="The “record-start” signal" link="SpiceRecordChannel.html#SpiceRecordChannel-record-start"/>
+ <keyword type="signal" name="The “record-stop” signal" link="SpiceRecordChannel.html#SpiceRecordChannel-record-stop"/>
+ <keyword type="struct" name="struct SpiceSmartcardChannel" link="SpiceSmartcardChannel.html#SpiceSmartcardChannel-struct"/>
+ <keyword type="struct" name="struct SpiceSmartcardChannelClass" link="SpiceSmartcardChannel.html#SpiceSmartcardChannelClass"/>
+ <keyword type="struct" name="struct SpiceUsbredirChannel" link="SpiceUsbredirChannel.html#SpiceUsbredirChannel-struct"/>
+ <keyword type="struct" name="struct SpiceUsbredirChannelClass" link="SpiceUsbredirChannel.html#SpiceUsbredirChannelClass"/>
+ <keyword type="function" name="spice_port_event ()" link="SpicePortChannel.html#spice-port-event" since="0.15"/>
+ <keyword type="function" name="spice_port_write_async ()" link="SpicePortChannel.html#spice-port-write-async" since="0.15"/>
+ <keyword type="function" name="spice_port_write_finish ()" link="SpicePortChannel.html#spice-port-write-finish" since="0.15"/>
+ <keyword type="struct" name="struct SpicePortChannel" link="SpicePortChannel.html#SpicePortChannel-struct"/>
+ <keyword type="struct" name="struct SpicePortChannelClass" link="SpicePortChannel.html#SpicePortChannelClass"/>
+ <keyword type="property" name="The “port-name” property" link="SpicePortChannel.html#SpicePortChannel--port-name"/>
+ <keyword type="property" name="The “port-opened” property" link="SpicePortChannel.html#SpicePortChannel--port-opened"/>
+ <keyword type="signal" name="The “port-data” signal" link="SpicePortChannel.html#SpicePortChannel-port-data"/>
+ <keyword type="signal" name="The “port-event” signal" link="SpicePortChannel.html#SpicePortChannel-port-event"/>
+ <keyword type="struct" name="struct SpiceWebdavChannel" link="SpiceWebdavChannel.html#SpiceWebdavChannel-struct"/>
+ <keyword type="struct" name="struct SpiceWebdavChannelClass" link="SpiceWebdavChannel.html#SpiceWebdavChannelClass"/>
+ <keyword type="function" name="spice_gtk_session_get ()" link="spice-gtk-SpiceGtkSession.html#spice-gtk-session-get"/>
+ <keyword type="function" name="spice_gtk_session_copy_to_guest ()" link="spice-gtk-SpiceGtkSession.html#spice-gtk-session-copy-to-guest"/>
+ <keyword type="function" name="spice_gtk_session_paste_from_guest ()" link="spice-gtk-SpiceGtkSession.html#spice-gtk-session-paste-from-guest"/>
+ <keyword type="function" name="spice_display_new ()" link="spice-gtk-SpiceDisplay.html#spice-display-new"/>
+ <keyword type="function" name="spice_display_new_with_monitor ()" link="spice-gtk-SpiceDisplay.html#spice-display-new-with-monitor" since="0.13"/>
+ <keyword type="function" name="spice_display_mouse_ungrab ()" link="spice-gtk-SpiceDisplay.html#spice-display-mouse-ungrab"/>
+ <keyword type="function" name="spice_display_set_grab_keys ()" link="spice-gtk-SpiceDisplay.html#spice-display-set-grab-keys"/>
+ <keyword type="function" name="spice_display_get_grab_keys ()" link="spice-gtk-SpiceDisplay.html#spice-display-get-grab-keys"/>
+ <keyword type="function" name="spice_display_send_keys ()" link="spice-gtk-SpiceDisplay.html#spice-display-send-keys"/>
+ <keyword type="function" name="spice_display_get_pixbuf ()" link="spice-gtk-SpiceDisplay.html#spice-display-get-pixbuf"/>
+ <keyword type="function" name="spice_grab_sequence_new ()" link="spice-gtk-SpiceDisplay.html#spice-grab-sequence-new"/>
+ <keyword type="function" name="spice_grab_sequence_new_from_string ()" link="spice-gtk-SpiceDisplay.html#spice-grab-sequence-new-from-string"/>
+ <keyword type="function" name="spice_grab_sequence_copy ()" link="spice-gtk-SpiceDisplay.html#spice-grab-sequence-copy"/>
+ <keyword type="function" name="spice_grab_sequence_free ()" link="spice-gtk-SpiceDisplay.html#spice-grab-sequence-free"/>
+ <keyword type="function" name="spice_grab_sequence_as_string ()" link="spice-gtk-SpiceDisplay.html#spice-grab-sequence-as-string"/>
+ <keyword type="enum" name="enum SpiceDisplayKeyEvent" link="spice-gtk-SpiceDisplay.html#SpiceDisplayKeyEvent"/>
+ <keyword type="struct" name="SpiceGrabSequence" link="spice-gtk-SpiceDisplay.html#SpiceGrabSequence-struct"/>
+ <keyword type="function" name="spice_usb_device_widget_new ()" link="spice-gtk-SpiceUsbDeviceWidget.html#spice-usb-device-widget-new"/>
+ <keyword type="function" name="spice_audio_get ()" link="SpiceAudio.html#spice-audio-get"/>
+ <keyword type="function" name="spice_audio_new ()" link="SpiceAudio.html#spice-audio-new" deprecated="0.8: Use spice_audio_get() instead"/>
+ <keyword type="struct" name="struct SpiceAudio" link="SpiceAudio.html#SpiceAudio-struct"/>
+ <keyword type="struct" name="struct SpiceAudioClass" link="SpiceAudio.html#SpiceAudioClass"/>
+ <keyword type="property" name="The “main-context” property" link="SpiceAudio.html#SpiceAudio--main-context"/>
+ <keyword type="property" name="The “session” property" link="SpiceAudio.html#SpiceAudio--session"/>
+ <keyword type="function" name="spice_smartcard_manager_get ()" link="SpiceSmartcardManager.html#spice-smartcard-manager-get"/>
+ <keyword type="function" name="spice_smartcard_manager_get_readers ()" link="SpiceSmartcardManager.html#spice-smartcard-manager-get-readers" since="0.20"/>
+ <keyword type="function" name="spice_smartcard_manager_insert_card ()" link="SpiceSmartcardManager.html#spice-smartcard-manager-insert-card" since="0.20"/>
+ <keyword type="function" name="spice_smartcard_manager_remove_card ()" link="SpiceSmartcardManager.html#spice-smartcard-manager-remove-card" since="0.20"/>
+ <keyword type="function" name="spice_smartcard_reader_is_software ()" link="SpiceSmartcardManager.html#spice-smartcard-reader-is-software"/>
+ <keyword type="function" name="spice_smartcard_reader_insert_card ()" link="SpiceSmartcardManager.html#spice-smartcard-reader-insert-card"/>
+ <keyword type="function" name="spice_smartcard_reader_remove_card ()" link="SpiceSmartcardManager.html#spice-smartcard-reader-remove-card"/>
+ <keyword type="struct" name="struct SpiceSmartcardManager" link="SpiceSmartcardManager.html#SpiceSmartcardManager-struct"/>
+ <keyword type="struct" name="struct SpiceSmartcardManagerClass" link="SpiceSmartcardManager.html#SpiceSmartcardManagerClass"/>
+ <keyword type="struct" name="SpiceSmartcardReader" link="SpiceSmartcardManager.html#SpiceSmartcardReader"/>
+ <keyword type="signal" name="The “card-inserted” signal" link="SpiceSmartcardManager.html#SpiceSmartcardManager-card-inserted"/>
+ <keyword type="signal" name="The “card-removed” signal" link="SpiceSmartcardManager.html#SpiceSmartcardManager-card-removed"/>
+ <keyword type="signal" name="The “reader-added” signal" link="SpiceSmartcardManager.html#SpiceSmartcardManager-reader-added"/>
+ <keyword type="signal" name="The “reader-removed” signal" link="SpiceSmartcardManager.html#SpiceSmartcardManager-reader-removed"/>
+ <keyword type="function" name="spice_usb_device_manager_get ()" link="SpiceUsbDeviceManager.html#spice-usb-device-manager-get"/>
+ <keyword type="function" name="spice_usb_device_manager_get_devices ()" link="SpiceUsbDeviceManager.html#spice-usb-device-manager-get-devices"/>
+ <keyword type="function" name="spice_usb_device_manager_get_devices_with_filter ()" link="SpiceUsbDeviceManager.html#spice-usb-device-manager-get-devices-with-filter" since="0.20"/>
+ <keyword type="function" name="spice_usb_device_manager_is_device_connected ()" link="SpiceUsbDeviceManager.html#spice-usb-device-manager-is-device-connected"/>
+ <keyword type="function" name="spice_usb_device_manager_is_redirecting ()" link="SpiceUsbDeviceManager.html#spice-usb-device-manager-is-redirecting" since="0.32"/>
+ <keyword type="function" name="spice_usb_device_manager_can_redirect_device ()" link="SpiceUsbDeviceManager.html#spice-usb-device-manager-can-redirect-device"/>
+ <keyword type="function" name="spice_usb_device_manager_connect_device_async ()" link="SpiceUsbDeviceManager.html#spice-usb-device-manager-connect-device-async"/>
+ <keyword type="function" name="spice_usb_device_manager_connect_device_finish ()" link="SpiceUsbDeviceManager.html#spice-usb-device-manager-connect-device-finish"/>
+ <keyword type="function" name="spice_usb_device_manager_disconnect_device ()" link="SpiceUsbDeviceManager.html#spice-usb-device-manager-disconnect-device" deprecated=""/>
+ <keyword type="function" name="spice_usb_device_manager_disconnect_device_async ()" link="SpiceUsbDeviceManager.html#spice-usb-device-manager-disconnect-device-async"/>
+ <keyword type="function" name="spice_usb_device_manager_disconnect_device_finish ()" link="SpiceUsbDeviceManager.html#spice-usb-device-manager-disconnect-device-finish"/>
+ <keyword type="function" name="spice_usb_device_get_description ()" link="SpiceUsbDeviceManager.html#spice-usb-device-get-description"/>
+ <keyword type="function" name="spice_usb_device_get_libusb_device ()" link="SpiceUsbDeviceManager.html#spice-usb-device-get-libusb-device" since="0.27"/>
+ <keyword type="struct" name="struct SpiceUsbDeviceManager" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-struct"/>
+ <keyword type="struct" name="struct SpiceUsbDeviceManagerClass" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManagerClass"/>
+ <keyword type="struct" name="SpiceUsbDevice" link="SpiceUsbDeviceManager.html#SpiceUsbDevice-struct"/>
+ <keyword type="property" name="The “auto-connect” property" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--auto-connect"/>
+ <keyword type="property" name="The “auto-connect-filter” property" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--auto-connect-filter"/>
+ <keyword type="property" name="The “free-channels” property" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--free-channels"/>
+ <keyword type="property" name="The “redirect-on-connect” property" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--redirect-on-connect"/>
+ <keyword type="property" name="The “session” property" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager--session"/>
+ <keyword type="signal" name="The “auto-connect-failed” signal" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-auto-connect-failed"/>
+ <keyword type="signal" name="The “device-added” signal" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-added"/>
+ <keyword type="signal" name="The “device-error” signal" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-error"/>
+ <keyword type="signal" name="The “device-removed” signal" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManager-device-removed"/>
+ <keyword type="function" name="spice_util_set_debug ()" link="spice-gtk-Utilities.html#spice-util-set-debug"/>
+ <keyword type="function" name="spice_util_get_version_string ()" link="spice-gtk-Utilities.html#spice-util-get-version-string"/>
+ <keyword type="function" name="spice_uuid_to_string ()" link="spice-gtk-Utilities.html#spice-uuid-to-string" since="0.22"/>
+ <keyword type="macro" name="SPICE_GTK_CHECK_VERSION()" link="spice-gtk-Version-Information.html#SPICE-GTK-CHECK-VERSION:CAPS" since="0.24"/>
+ <keyword type="macro" name="SPICE_GTK_MAJOR_VERSION" link="spice-gtk-Version-Information.html#SPICE-GTK-MAJOR-VERSION:CAPS" since="0.24"/>
+ <keyword type="macro" name="SPICE_GTK_MICRO_VERSION" link="spice-gtk-Version-Information.html#SPICE-GTK-MICRO-VERSION:CAPS" since="0.24"/>
+ <keyword type="macro" name="SPICE_GTK_MINOR_VERSION" link="spice-gtk-Version-Information.html#SPICE-GTK-MINOR-VERSION:CAPS" since="0.24"/>
+ <keyword type="function" name="spice_uri_get_scheme ()" link="spice-gtk-SpiceURI.html#spice-uri-get-scheme" since="0.24"/>
+ <keyword type="function" name="spice_uri_set_scheme ()" link="spice-gtk-SpiceURI.html#spice-uri-set-scheme" since="0.24"/>
+ <keyword type="function" name="spice_uri_get_hostname ()" link="spice-gtk-SpiceURI.html#spice-uri-get-hostname" since="0.24"/>
+ <keyword type="function" name="spice_uri_set_hostname ()" link="spice-gtk-SpiceURI.html#spice-uri-set-hostname" since="0.24"/>
+ <keyword type="function" name="spice_uri_get_port ()" link="spice-gtk-SpiceURI.html#spice-uri-get-port" since="0.24"/>
+ <keyword type="function" name="spice_uri_set_port ()" link="spice-gtk-SpiceURI.html#spice-uri-set-port" since="0.24"/>
+ <keyword type="function" name="spice_uri_get_user ()" link="spice-gtk-SpiceURI.html#spice-uri-get-user" since="0.24"/>
+ <keyword type="function" name="spice_uri_set_user ()" link="spice-gtk-SpiceURI.html#spice-uri-set-user" since="0.24"/>
+ <keyword type="function" name="spice_uri_get_password ()" link="spice-gtk-SpiceURI.html#spice-uri-get-password" since="0.24"/>
+ <keyword type="function" name="spice_uri_set_password ()" link="spice-gtk-SpiceURI.html#spice-uri-set-password" since="0.24"/>
+ <keyword type="function" name="spice_uri_to_string ()" link="spice-gtk-SpiceURI.html#spice-uri-to-string" since="0.24"/>
+ <keyword type="struct" name="SpiceURIClass" link="spice-gtk-SpiceURI.html#SpiceURIClass"/>
+ <keyword type="struct" name="SpiceURI" link="spice-gtk-SpiceURI.html#SpiceURI"/>
+ <keyword type="function" name="spice_file_transfer_task_get_progress ()" link="SpiceFileTransferTask.html#spice-file-transfer-task-get-progress" since="0.31"/>
+ <keyword type="function" name="spice_file_transfer_task_get_filename ()" link="SpiceFileTransferTask.html#spice-file-transfer-task-get-filename" since="0.31"/>
+ <keyword type="function" name="spice_file_transfer_task_get_total_bytes ()" link="SpiceFileTransferTask.html#spice-file-transfer-task-get-total-bytes" since="0.33"/>
+ <keyword type="function" name="spice_file_transfer_task_get_transferred_bytes ()" link="SpiceFileTransferTask.html#spice-file-transfer-task-get-transferred-bytes" since="0.33"/>
+ <keyword type="function" name="spice_file_transfer_task_cancel ()" link="SpiceFileTransferTask.html#spice-file-transfer-task-cancel" since="0.31"/>
+ <keyword type="property" name="The “cancellable” property" link="SpiceFileTransferTask.html#SpiceFileTransferTask--cancellable"/>
+ <keyword type="property" name="The “channel” property" link="SpiceFileTransferTask.html#SpiceFileTransferTask--channel"/>
+ <keyword type="property" name="The “file” property" link="SpiceFileTransferTask.html#SpiceFileTransferTask--file"/>
+ <keyword type="property" name="The “id” property" link="SpiceFileTransferTask.html#SpiceFileTransferTask--id"/>
+ <keyword type="property" name="The “progress” property" link="SpiceFileTransferTask.html#SpiceFileTransferTask--progress"/>
+ <keyword type="property" name="The “total-bytes” property" link="SpiceFileTransferTask.html#SpiceFileTransferTask--total-bytes"/>
+ <keyword type="property" name="The “transferred-bytes” property" link="SpiceFileTransferTask.html#SpiceFileTransferTask--transferred-bytes"/>
+ <keyword type="signal" name="The “finished” signal" link="SpiceFileTransferTask.html#SpiceFileTransferTask-finished"/>
+ <keyword type="constant" name="SPICE_SESSION_MIGRATION_NONE" link="SpiceSession.html#SPICE-SESSION-MIGRATION-NONE:CAPS"/>
+ <keyword type="constant" name="SPICE_SESSION_MIGRATION_SWITCHING" link="SpiceSession.html#SPICE-SESSION-MIGRATION-SWITCHING:CAPS"/>
+ <keyword type="constant" name="SPICE_SESSION_MIGRATION_MIGRATING" link="SpiceSession.html#SPICE-SESSION-MIGRATION-MIGRATING:CAPS"/>
+ <keyword type="constant" name="SPICE_SESSION_MIGRATION_CONNECTING" link="SpiceSession.html#SPICE-SESSION-MIGRATION-CONNECTING:CAPS"/>
+ <keyword type="constant" name="SPICE_SESSION_VERIFY_PUBKEY" link="SpiceSession.html#SPICE-SESSION-VERIFY-PUBKEY:CAPS"/>
+ <keyword type="constant" name="SPICE_SESSION_VERIFY_HOSTNAME" link="SpiceSession.html#SPICE-SESSION-VERIFY-HOSTNAME:CAPS"/>
+ <keyword type="constant" name="SPICE_SESSION_VERIFY_SUBJECT" link="SpiceSession.html#SPICE-SESSION-VERIFY-SUBJECT:CAPS"/>
+ <keyword type="constant" name="SPICE_CLIENT_ERROR_FAILED" link="SpiceSession.html#SPICE-CLIENT-ERROR-FAILED:CAPS"/>
+ <keyword type="constant" name="SPICE_CLIENT_ERROR_USB_DEVICE_REJECTED" link="SpiceSession.html#SPICE-CLIENT-ERROR-USB-DEVICE-REJECTED:CAPS"/>
+ <keyword type="constant" name="SPICE_CLIENT_ERROR_USB_DEVICE_LOST" link="SpiceSession.html#SPICE-CLIENT-ERROR-USB-DEVICE-LOST:CAPS"/>
+ <keyword type="constant" name="SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD" link="SpiceSession.html#SPICE-CLIENT-ERROR-AUTH-NEEDS-PASSWORD:CAPS"/>
+ <keyword type="constant" name="SPICE_CLIENT_ERROR_AUTH_NEEDS_USERNAME" link="SpiceSession.html#SPICE-CLIENT-ERROR-AUTH-NEEDS-USERNAME:CAPS"/>
+ <keyword type="constant" name="SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD_AND_USERNAME" link="SpiceSession.html#SPICE-CLIENT-ERROR-AUTH-NEEDS-PASSWORD-AND-USERNAME:CAPS"/>
+ <keyword type="constant" name="SPICE_CLIENT_ERROR_USB_SERVICE" link="SpiceSession.html#SPICE-CLIENT-ERROR-USB-SERVICE:CAPS"/>
+ <keyword type="constant" name="SPICE_CHANNEL_NONE" link="SpiceChannel.html#SPICE-CHANNEL-NONE:CAPS"/>
+ <keyword type="constant" name="SPICE_CHANNEL_OPENED" link="SpiceChannel.html#SPICE-CHANNEL-OPENED:CAPS"/>
+ <keyword type="constant" name="SPICE_CHANNEL_SWITCHING" link="SpiceChannel.html#SPICE-CHANNEL-SWITCHING:CAPS"/>
+ <keyword type="constant" name="SPICE_CHANNEL_CLOSED" link="SpiceChannel.html#SPICE-CHANNEL-CLOSED:CAPS"/>
+ <keyword type="constant" name="SPICE_CHANNEL_ERROR_CONNECT" link="SpiceChannel.html#SPICE-CHANNEL-ERROR-CONNECT:CAPS"/>
+ <keyword type="constant" name="SPICE_CHANNEL_ERROR_TLS" link="SpiceChannel.html#SPICE-CHANNEL-ERROR-TLS:CAPS"/>
+ <keyword type="constant" name="SPICE_CHANNEL_ERROR_LINK" link="SpiceChannel.html#SPICE-CHANNEL-ERROR-LINK:CAPS"/>
+ <keyword type="constant" name="SPICE_CHANNEL_ERROR_AUTH" link="SpiceChannel.html#SPICE-CHANNEL-ERROR-AUTH:CAPS"/>
+ <keyword type="constant" name="SPICE_CHANNEL_ERROR_IO" link="SpiceChannel.html#SPICE-CHANNEL-ERROR-IO:CAPS"/>
+ <keyword type="constant" name="SPICE_INPUTS_SCROLL_LOCK" link="SpiceInputsChannel.html#SPICE-INPUTS-SCROLL-LOCK:CAPS"/>
+ <keyword type="constant" name="SPICE_INPUTS_NUM_LOCK" link="SpiceInputsChannel.html#SPICE-INPUTS-NUM-LOCK:CAPS"/>
+ <keyword type="constant" name="SPICE_INPUTS_CAPS_LOCK" link="SpiceInputsChannel.html#SPICE-INPUTS-CAPS-LOCK:CAPS"/>
+ <keyword type="constant" name="SPICE_DISPLAY_KEY_EVENT_PRESS" link="spice-gtk-SpiceDisplay.html#SPICE-DISPLAY-KEY-EVENT-PRESS:CAPS"/>
+ <keyword type="constant" name="SPICE_DISPLAY_KEY_EVENT_RELEASE" link="spice-gtk-SpiceDisplay.html#SPICE-DISPLAY-KEY-EVENT-RELEASE:CAPS"/>
+ <keyword type="constant" name="SPICE_DISPLAY_KEY_EVENT_CLICK" link="spice-gtk-SpiceDisplay.html#SPICE-DISPLAY-KEY-EVENT-CLICK:CAPS"/>
+ <keyword type="member" name="SpiceSessionClass.channel-new" link="SpiceSession.html#SpiceSessionClass.channel-new"/>
+ <keyword type="member" name="SpiceSessionClass.channel-destroy" link="SpiceSession.html#SpiceSessionClass.channel-destroy"/>
+ <keyword type="member" name="SpiceChannelClass.channel-event" link="SpiceChannel.html#SpiceChannelClass.channel-event"/>
+ <keyword type="member" name="SpiceChannelClass.open-fd" link="SpiceChannel.html#SpiceChannelClass.open-fd"/>
+ <keyword type="member" name="SpiceCursorChannelClass.cursor-set" link="SpiceCursorChannel.html#SpiceCursorChannelClass.cursor-set"/>
+ <keyword type="member" name="SpiceCursorChannelClass.cursor-move" link="SpiceCursorChannel.html#SpiceCursorChannelClass.cursor-move"/>
+ <keyword type="member" name="SpiceCursorChannelClass.cursor-hide" link="SpiceCursorChannel.html#SpiceCursorChannelClass.cursor-hide"/>
+ <keyword type="member" name="SpiceCursorChannelClass.cursor-reset" link="SpiceCursorChannel.html#SpiceCursorChannelClass.cursor-reset"/>
+ <keyword type="member" name="SpiceDisplayChannelClass.display-primary-create" link="SpiceDisplayChannel.html#SpiceDisplayChannelClass.display-primary-create"/>
+ <keyword type="member" name="SpiceDisplayChannelClass.display-primary-destroy" link="SpiceDisplayChannel.html#SpiceDisplayChannelClass.display-primary-destroy"/>
+ <keyword type="member" name="SpiceDisplayChannelClass.display-invalidate" link="SpiceDisplayChannel.html#SpiceDisplayChannelClass.display-invalidate"/>
+ <keyword type="member" name="SpiceDisplayChannelClass.display-mark" link="SpiceDisplayChannel.html#SpiceDisplayChannelClass.display-mark"/>
+ <keyword type="member" name="SpiceDisplayMonitorConfig.id" link="SpiceDisplayChannel.html#SpiceDisplayMonitorConfig.id"/>
+ <keyword type="member" name="SpiceDisplayMonitorConfig.surface-id" link="SpiceDisplayChannel.html#SpiceDisplayMonitorConfig.surface-id"/>
+ <keyword type="member" name="SpiceDisplayMonitorConfig.x" link="SpiceDisplayChannel.html#SpiceDisplayMonitorConfig.x"/>
+ <keyword type="member" name="SpiceDisplayMonitorConfig.y" link="SpiceDisplayChannel.html#SpiceDisplayMonitorConfig.y"/>
+ <keyword type="member" name="SpiceDisplayMonitorConfig.width" link="SpiceDisplayChannel.html#SpiceDisplayMonitorConfig.width"/>
+ <keyword type="member" name="SpiceDisplayMonitorConfig.height" link="SpiceDisplayChannel.html#SpiceDisplayMonitorConfig.height"/>
+ <keyword type="member" name="SpiceDisplayPrimary.format" link="SpiceDisplayChannel.html#SpiceDisplayPrimary.format"/>
+ <keyword type="member" name="SpiceDisplayPrimary.width" link="SpiceDisplayChannel.html#SpiceDisplayPrimary.width"/>
+ <keyword type="member" name="SpiceDisplayPrimary.height" link="SpiceDisplayChannel.html#SpiceDisplayPrimary.height"/>
+ <keyword type="member" name="SpiceDisplayPrimary.stride" link="SpiceDisplayChannel.html#SpiceDisplayPrimary.stride"/>
+ <keyword type="member" name="SpiceDisplayPrimary.shmid" link="SpiceDisplayChannel.html#SpiceDisplayPrimary.shmid"/>
+ <keyword type="member" name="SpiceDisplayPrimary.data" link="SpiceDisplayChannel.html#SpiceDisplayPrimary.data"/>
+ <keyword type="member" name="SpiceDisplayPrimary.marked" link="SpiceDisplayChannel.html#SpiceDisplayPrimary.marked"/>
+ <keyword type="member" name="SpiceGlScanout-struct.fd" link="SpiceDisplayChannel.html#SpiceGlScanout-struct.fd"/>
+ <keyword type="member" name="SpiceGlScanout-struct.width" link="SpiceDisplayChannel.html#SpiceGlScanout-struct.width"/>
+ <keyword type="member" name="SpiceGlScanout-struct.height" link="SpiceDisplayChannel.html#SpiceGlScanout-struct.height"/>
+ <keyword type="member" name="SpiceGlScanout-struct.stride" link="SpiceDisplayChannel.html#SpiceGlScanout-struct.stride"/>
+ <keyword type="member" name="SpiceGlScanout-struct.format" link="SpiceDisplayChannel.html#SpiceGlScanout-struct.format"/>
+ <keyword type="member" name="SpiceGlScanout-struct.y0top" link="SpiceDisplayChannel.html#SpiceGlScanout-struct.y0top"/>
+ <keyword type="member" name="SpiceInputsChannelClass.inputs-modifiers" link="SpiceInputsChannel.html#SpiceInputsChannelClass.inputs-modifiers"/>
+ <keyword type="member" name="SpiceMainChannelClass.mouse-update" link="SpiceMainChannel.html#SpiceMainChannelClass.mouse-update"/>
+ <keyword type="member" name="SpiceMainChannelClass.agent-update" link="SpiceMainChannel.html#SpiceMainChannelClass.agent-update"/>
+ <keyword type="member" name="SpicePlaybackChannelClass.playback-start" link="SpicePlaybackChannel.html#SpicePlaybackChannelClass.playback-start"/>
+ <keyword type="member" name="SpicePlaybackChannelClass.playback-data" link="SpicePlaybackChannel.html#SpicePlaybackChannelClass.playback-data"/>
+ <keyword type="member" name="SpicePlaybackChannelClass.playback-stop" link="SpicePlaybackChannel.html#SpicePlaybackChannelClass.playback-stop"/>
+ <keyword type="member" name="SpiceRecordChannelClass.record-start" link="SpiceRecordChannel.html#SpiceRecordChannelClass.record-start"/>
+ <keyword type="member" name="SpiceRecordChannelClass.record-data" link="SpiceRecordChannel.html#SpiceRecordChannelClass.record-data"/>
+ <keyword type="member" name="SpiceRecordChannelClass.record-stop" link="SpiceRecordChannel.html#SpiceRecordChannelClass.record-stop"/>
+ <keyword type="member" name="SpiceSmartcardManagerClass.reader-added" link="SpiceSmartcardManager.html#SpiceSmartcardManagerClass.reader-added"/>
+ <keyword type="member" name="SpiceSmartcardManagerClass.reader-removed" link="SpiceSmartcardManager.html#SpiceSmartcardManagerClass.reader-removed"/>
+ <keyword type="member" name="SpiceSmartcardManagerClass.card-inserted" link="SpiceSmartcardManager.html#SpiceSmartcardManagerClass.card-inserted"/>
+ <keyword type="member" name="SpiceSmartcardManagerClass.card-removed" link="SpiceSmartcardManager.html#SpiceSmartcardManagerClass.card-removed"/>
+ <keyword type="member" name="SpiceUsbDeviceManagerClass.device-added" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManagerClass.device-added"/>
+ <keyword type="member" name="SpiceUsbDeviceManagerClass.device-removed" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManagerClass.device-removed"/>
+ <keyword type="member" name="SpiceUsbDeviceManagerClass.auto-connect-failed" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManagerClass.auto-connect-failed"/>
+ <keyword type="member" name="SpiceUsbDeviceManagerClass.device-error" link="SpiceUsbDeviceManager.html#SpiceUsbDeviceManagerClass.device-error"/>
+ </functions>
+</book>
--- /dev/null
+body
+{
+ font-family: cantarell, sans-serif;
+}
+.synopsis, .classsynopsis
+{
+ /* tango:aluminium 1/2 */
+ background: #eeeeec;
+ background: rgba(238, 238, 236, 0.5);
+ border: solid 1px rgb(238, 238, 236);
+ padding: 0.5em;
+}
+.programlisting
+{
+ /* tango:sky blue 0/1 */
+ /* fallback for no rgba support */
+ background: #e6f3ff;
+ border: solid 1px #729fcf;
+ background: rgba(114, 159, 207, 0.1);
+ border: solid 1px rgba(114, 159, 207, 0.2);
+ padding: 0.5em;
+}
+.variablelist
+{
+ padding: 4px;
+ margin-left: 3em;
+}
+.variablelist td:first-child
+{
+ vertical-align: top;
+}
+
+div.gallery-float
+{
+ float: left;
+ padding: 10px;
+}
+div.gallery-float img
+{
+ border-style: none;
+}
+div.gallery-spacer
+{
+ clear: both;
+}
+
+a, a:visited
+{
+ text-decoration: none;
+ /* tango:sky blue 2 */
+ color: #3465a4;
+}
+a:hover
+{
+ text-decoration: underline;
+ /* tango:sky blue 1 */
+ color: #729fcf;
+}
+
+div.informaltable table
+{
+ border-collapse: separate;
+ border-spacing: 1em 0.3em;
+ border: none;
+}
+
+div.informaltable table td, div.informaltable table th
+{
+ vertical-align: top;
+}
+
+.function_type,
+.variable_type,
+.property_type,
+.signal_type,
+.parameter_name,
+.struct_member_name,
+.union_member_name,
+.define_keyword,
+.datatype_keyword,
+.typedef_keyword
+{
+ text-align: right;
+}
+
+/* dim non-primary columns */
+.c_punctuation,
+.function_type,
+.variable_type,
+.property_type,
+.signal_type,
+.define_keyword,
+.datatype_keyword,
+.typedef_keyword,
+.property_flags,
+.signal_flags,
+.parameter_annotations,
+.enum_member_annotations,
+.struct_member_annotations,
+.union_member_annotations
+{
+ color: #888a85;
+}
+
+.function_type a,
+.function_type a:visited,
+.function_type a:hover,
+.property_type a,
+.property_type a:visited,
+.property_type a:hover,
+.signal_type a,
+.signal_type a:visited,
+.signal_type a:hover,
+.signal_flags a,
+.signal_flags a:visited,
+.signal_flags a:hover
+{
+ color: #729fcf;
+}
+
+td p
+{
+ margin: 0.25em;
+}
+
+div.table table
+{
+ border-collapse: collapse;
+ border-spacing: 0px;
+ /* tango:aluminium 3 */
+ border: solid 1px #babdb6;
+}
+
+div.table table td, div.table table th
+{
+ /* tango:aluminium 3 */
+ border: solid 1px #babdb6;
+ padding: 3px;
+ vertical-align: top;
+}
+
+div.table table th
+{
+ /* tango:aluminium 2 */
+ background-color: #d3d7cf;
+}
+
+h4
+{
+ color: #555753;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+hr
+{
+ /* tango:aluminium 1 */
+ color: #d3d7cf;
+ background: #d3d7cf;
+ border: none 0px;
+ height: 1px;
+ clear: both;
+ margin: 2.0em 0em 2.0em 0em;
+}
+
+dl.toc dt
+{
+ padding-bottom: 0.25em;
+}
+
+dl.toc > dt
+{
+ padding-top: 0.25em;
+ padding-bottom: 0.25em;
+ font-weight: bold;
+}
+
+dl.toc > dl
+{
+ padding-bottom: 0.5em;
+}
+
+.parameter
+{
+ font-style: normal;
+}
+
+.footer
+{
+ padding-top: 3.5em;
+ /* tango:aluminium 3 */
+ color: #babdb6;
+ text-align: center;
+ font-size: 80%;
+}
+
+.informalfigure,
+.figure
+{
+ margin: 1em;
+}
+
+.informalexample,
+.example
+{
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.warning
+{
+ /* tango:orange 0/1 */
+ background: #ffeed9;
+ background: rgba(252, 175, 62, 0.1);
+ border-color: #ffb04f;
+ border-color: rgba(252, 175, 62, 0.2);
+}
+.note
+{
+ /* tango:chameleon 0/0.5 */
+ background: #d8ffb2;
+ background: rgba(138, 226, 52, 0.1);
+ border-color: #abf562;
+ border-color: rgba(138, 226, 52, 0.2);
+}
+div.blockquote
+{
+ border-color: #eeeeec;
+}
+.note, .warning, div.blockquote
+{
+ padding: 0.5em;
+ border-width: 1px;
+ border-style: solid;
+ margin: 2em;
+}
+.note p, .warning p
+{
+ margin: 0;
+}
+
+div.warning h3.title,
+div.note h3.title
+{
+ display: none;
+}
+
+p + div.section
+{
+ margin-top: 1em;
+}
+
+div.refnamediv,
+div.refsynopsisdiv,
+div.refsect1,
+div.refsect2,
+div.toc,
+div.section
+{
+ margin-bottom: 1em;
+}
+
+/* blob links */
+h2 .extralinks, h3 .extralinks
+{
+ float: right;
+ /* tango:aluminium 3 */
+ color: #babdb6;
+ font-size: 80%;
+ font-weight: normal;
+}
+
+.lineart
+{
+ color: #d3d7cf;
+ font-weight: normal;
+}
+
+.annotation
+{
+ /* tango:aluminium 5 */
+ color: #555753;
+ font-weight: normal;
+}
+
+.structfield
+{
+ font-style: normal;
+ font-weight: normal;
+}
+
+acronym,abbr
+{
+ border-bottom: 1px dotted gray;
+}
+
+/* code listings */
+
+.listing_code .programlisting .normal,
+.listing_code .programlisting .normal a,
+.listing_code .programlisting .number,
+.listing_code .programlisting .cbracket,
+.listing_code .programlisting .symbol { color: #555753; }
+.listing_code .programlisting .comment,
+.listing_code .programlisting .linenum { color: #babdb6; } /* tango: aluminium 3 */
+.listing_code .programlisting .function,
+.listing_code .programlisting .function a,
+.listing_code .programlisting .preproc { color: #204a87; } /* tango: sky blue 3 */
+.listing_code .programlisting .string { color: #ad7fa8; } /* tango: plum */
+.listing_code .programlisting .keyword,
+.listing_code .programlisting .usertype,
+.listing_code .programlisting .type,
+.listing_code .programlisting .type a { color: #4e9a06; } /* tango: chameleon 3 */
+
+.listing_frame {
+ /* tango:sky blue 1 */
+ border: solid 1px #729fcf;
+ border: solid 1px rgba(114, 159, 207, 0.2);
+ padding: 0px;
+}
+
+.listing_lines, .listing_code {
+ margin-top: 0px;
+ margin-bottom: 0px;
+ padding: 0.5em;
+}
+.listing_lines {
+ /* tango:sky blue 0.5 */
+ background: #a6c5e3;
+ background: rgba(114, 159, 207, 0.2);
+ /* tango:aluminium 6 */
+ color: #2e3436;
+}
+.listing_code {
+ /* tango:sky blue 0 */
+ background: #e6f3ff;
+ background: rgba(114, 159, 207, 0.1);
+}
+.listing_code .programlisting {
+ /* override from previous */
+ border: none 0px;
+ padding: 0px;
+ background: none;
+}
+.listing_lines pre, .listing_code pre {
+ margin: 0px;
+}
+
+@media screen {
+ /* these have a <sup> as a first child, but since there are no parent selectors
+ * we can't use that. */
+ a.footnote
+ {
+ position: relative;
+ top: 0em ! important;
+ }
+ /* this is needed so that the local anchors are displayed below the naviagtion */
+ div.footnote a[name], div.refnamediv a[name], div.refsect1 a[name], div.refsect2 a[name], div.index a[name], div.glossary a[name], div.sect1 a[name]
+ {
+ display: inline-block;
+ position: relative;
+ top:-5em;
+ }
+ /* this seems to be a bug in the xsl style sheets when generating indexes */
+ div.index div.index
+ {
+ top: 0em;
+ }
+ /* make space for the fixed navigation bar and add space at the bottom so that
+ * link targets appear somewhat close to top
+ */
+ body
+ {
+ padding-top: 2.5em;
+ padding-bottom: 500px;
+ max-width: 60em;
+ }
+ p
+ {
+ max-width: 60em;
+ }
+ /* style and size the navigation bar */
+ table.navigation#top
+ {
+ position: fixed;
+ background: #e2e2e2;
+ border-bottom: solid 1px #babdb6;
+ border-spacing: 5px;
+ margin-top: 0;
+ margin-bottom: 0;
+ top: 0;
+ left: 0;
+ z-index: 10;
+ }
+ table.navigation#top td
+ {
+ padding-left: 6px;
+ padding-right: 6px;
+ }
+ .navigation a, .navigation a:visited
+ {
+ /* tango:sky blue 3 */
+ color: #204a87;
+ }
+ .navigation a:hover
+ {
+ /* tango:sky blue 2 */
+ color: #3465a4;
+ }
+ td.shortcuts
+ {
+ /* tango:sky blue 2 */
+ color: #3465a4;
+ font-size: 80%;
+ white-space: nowrap;
+ }
+ td.shortcuts .dim
+ {
+ color: #babdb6;
+ }
+ .navigation .title
+ {
+ font-size: 80%;
+ max-width: none;
+ margin: 0px;
+ font-weight: normal;
+ }
+}
+@media screen and (min-width: 60em) {
+ /* screen larger than 60em */
+ body { margin: auto; }
+}
+@media screen and (max-width: 60em) {
+ /* screen less than 60em */
+ #nav_hierarchy { display: none; }
+ #nav_interfaces { display: none; }
+ #nav_prerequisites { display: none; }
+ #nav_derived_interfaces { display: none; }
+ #nav_implementations { display: none; }
+ #nav_child_properties { display: none; }
+ #nav_style_properties { display: none; }
+ #nav_index { display: none; }
+ #nav_glossary { display: none; }
+ .gallery_image { display: none; }
+ .property_flags { display: none; }
+ .signal_flags { display: none; }
+ .parameter_annotations { display: none; }
+ .enum_member_annotations { display: none; }
+ .struct_member_annotations { display: none; }
+ .union_member_annotations { display: none; }
+ /* now that a column is hidden, optimize space */
+ col.parameters_name { width: auto; }
+ col.parameters_description { width: auto; }
+ col.struct_members_name { width: auto; }
+ col.struct_members_description { width: auto; }
+ col.enum_members_name { width: auto; }
+ col.enum_members_description { width: auto; }
+ col.union_members_name { width: auto; }
+ col.union_members_description { width: auto; }
+ .listing_lines { display: none; }
+}
+@media print {
+ table.navigation {
+ visibility: collapse;
+ display: none;
+ }
+ div.titlepage table.navigation {
+ visibility: visible;
+ display: table;
+ background: #e2e2e2;
+ border: solid 1px #babdb6;
+ margin-top: 0;
+ margin-bottom: 0;
+ top: 0;
+ left: 0;
+ height: 3em;
+ }
+}
+
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+[
+ <!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
+]>
+<book id="index">
+ <bookinfo>
+ <title>Spice-GTK Reference Manual</title>
+<!--
+ <releaseinfo>
+ for spice-gtk [VERSION].
+ The latest version of this documentation can be found on-line at
+ <ulink role="online-location" url="http://[SERVER]/spice-gtk/index.html">http://[SERVER]/spice-gtk/</ulink>.
+ </releaseinfo>
+-->
+ </bookinfo>
+
+ <part id="api-reference">
+ <title>API Reference</title>
+ <chapter>
+ <title>Object Hierarchy</title>
+ <xi:include href="xml/tree_index.sgml" />
+ </chapter>
+
+ <chapter>
+ <title>Session and Channels Objects, from spice-client-glib</title>
+ <xi:include href="xml/spice-session.xml"/>
+ <xi:include href="xml/spice-channel.xml"/>
+
+ <xi:include href="xml/channel-cursor.xml"/>
+ <xi:include href="xml/channel-display.xml"/>
+ <xi:include href="xml/channel-inputs.xml"/>
+ <xi:include href="xml/channel-main.xml"/>
+ <xi:include href="xml/channel-playback.xml"/>
+ <xi:include href="xml/channel-record.xml"/>
+ <xi:include href="xml/channel-smartcard.xml"/>
+ <xi:include href="xml/channel-usbredir.xml"/>
+ <xi:include href="xml/channel-port.xml"/>
+ <xi:include href="xml/channel-webdav.xml"/>
+ </chapter>
+
+ <chapter>
+ <title>GTK Widget, from spice-client-gtk</title>
+ <xi:include href="xml/spice-gtk-session.xml"/>
+ <xi:include href="xml/spice-widget.xml"/>
+ <xi:include href="xml/usb-device-widget.xml"/>
+ </chapter>
+
+ <chapter id="application-support">
+ <title>Application Support, from spice-client-glib</title>
+ <xi:include href="xml/spice-audio.xml"/>
+ <xi:include href="xml/smartcard-manager.xml"/>
+ <xi:include href="xml/usb-device-manager.xml"/>
+ <xi:include href="xml/spice-util.xml"/>
+ <xi:include href="xml/spice-version.xml"/>
+ <xi:include href="xml/spice-uri.xml"/>
+ <xi:include href="xml/file-transfer-task.xml"/>
+ </chapter>
+
+ </part>
+
+ <chapter id="object-tree">
+ <title>Object Hierarchy</title>
+ <xi:include href="xml/tree_index.sgml"/>
+ </chapter>
+ <index id="api-index-full">
+ <title>API Index</title>
+ <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
+ </index>
+ <!--
+ <index role="2.26">
+ <title>Index of new symbols in 2.26</title>
+ <xi:include href="xml/api-index-2.26.xml"><xi:fallback/></xi:include>
+ </index>
+ -->
+ <index id="api-index-deprecated" role="deprecated">
+ <title>Index of deprecated symbols</title>
+ <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
+ </index>
+
+ <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+</book>
--- /dev/null
+<SECTION>
+<FILE>channel-playback</FILE>
+<TITLE>SpicePlaybackChannel</TITLE>
+SpicePlaybackChannel
+SpicePlaybackChannelClass
+spice_playback_channel_set_delay
+<SUBSECTION Standard>
+SPICE_PLAYBACK_CHANNEL
+SPICE_IS_PLAYBACK_CHANNEL
+SPICE_TYPE_PLAYBACK_CHANNEL
+spice_playback_channel_get_type
+SPICE_PLAYBACK_CHANNEL_CLASS
+SPICE_IS_PLAYBACK_CHANNEL_CLASS
+SPICE_PLAYBACK_CHANNEL_GET_CLASS
+<SUBSECTION Private>
+SpicePlaybackChannelPrivate
+spice_playback_channel_get_latency
+spice_playback_channel_is_active
+spice_playback_channel_sync_latency
+</SECTION>
+
+<SECTION>
+<FILE>spice-session</FILE>
+<TITLE>SpiceSession</TITLE>
+SpiceSession
+SpiceSessionClass
+spice_session_new
+spice_session_connect
+spice_session_open_fd
+spice_session_disconnect
+spice_session_get_channels
+spice_session_get_read_only
+spice_session_has_channel_type
+spice_session_get_proxy_uri
+spice_session_is_for_migration
+<SUBSECTION>
+SpiceSessionMigration
+SpiceSessionVerify
+spice_get_option_group
+spice_set_session_option
+<SUBSECTION>
+SpiceClientError
+SPICE_CLIENT_ERROR
+spice_client_error_quark
+<SUBSECTION Standard>
+SPICE_SESSION
+SPICE_IS_SESSION
+SPICE_TYPE_SESSION
+spice_session_get_type
+SPICE_SESSION_CLASS
+SPICE_IS_SESSION_CLASS
+SPICE_SESSION_GET_CLASS
+SPICE_TYPE_SESSION_VERIFY
+spice_session_verify_get_type
+SPICE_TYPE_SESSION_MIGRATION
+spice_session_migration_get_type
+<SUBSECTION Private>
+SpiceSessionPrivate
+SPICE_CLIENT_USB_DEVICE_LOST
+SPICE_CLIENT_USB_DEVICE_REJECTED
+</SECTION>
+
+<SECTION>
+<FILE>channel-main</FILE>
+<TITLE>SpiceMainChannel</TITLE>
+SpiceMainChannel
+SpiceMainChannelClass
+<SUBSECTION>
+spice_main_set_display
+spice_main_set_display_enabled
+spice_main_update_display
+spice_main_update_display_enabled
+spice_main_send_monitor_config
+spice_main_agent_test_capability
+spice_main_request_mouse_mode
+spice_main_clipboard_selection_grab
+spice_main_clipboard_selection_notify
+spice_main_clipboard_selection_release
+spice_main_clipboard_selection_request
+spice_main_clipboard_grab
+spice_main_clipboard_release
+spice_main_clipboard_notify
+spice_main_clipboard_request
+spice_main_file_copy_async
+spice_main_file_copy_finish
+<SUBSECTION Standard>
+SPICE_MAIN_CHANNEL
+SPICE_IS_MAIN_CHANNEL
+SPICE_TYPE_MAIN_CHANNEL
+spice_main_channel_get_type
+SPICE_MAIN_CHANNEL_CLASS
+SPICE_IS_MAIN_CHANNEL_CLASS
+SPICE_MAIN_CHANNEL_GET_CLASS
+<SUBSECTION Private>
+SpiceMainChannelPrivate
+</SECTION>
+
+<SECTION>
+<FILE>spice-channel</FILE>
+<TITLE>SpiceChannel</TITLE>
+SpiceChannelEvent
+SpiceChannel
+SpiceChannelClass
+<SUBSECTION>
+spice_channel_new
+spice_channel_destroy
+spice_channel_connect
+spice_channel_open_fd
+spice_channel_disconnect
+spice_channel_test_capability
+spice_channel_test_common_capability
+spice_channel_type_to_string
+spice_channel_string_to_type
+spice_channel_set_capability
+spice_channel_flush_async
+spice_channel_flush_finish
+spice_channel_get_error
+<SUBSECTION Standard>
+SPICE_TYPE_CHANNEL_EVENT
+spice_channel_event_get_type
+SPICE_CHANNEL
+SPICE_IS_CHANNEL
+SPICE_TYPE_CHANNEL
+spice_channel_get_type
+SPICE_CHANNEL_CLASS
+SPICE_IS_CHANNEL_CLASS
+SPICE_CHANNEL_GET_CLASS
+<SUBSECTION Private>
+SpiceMsgIn
+SpiceMsgOut
+SpiceChannelClassPrivate
+SpiceChannelPrivate
+spice_msg_handler
+spice_msg_in
+spice_msg_out
+</SECTION>
+
+<SECTION>
+<FILE>spice-audio</FILE>
+<TITLE>SpiceAudio</TITLE>
+SpiceAudio
+SpiceAudioClass
+<SUBSECTION>
+spice_audio_get
+spice_audio_new
+<SUBSECTION Standard>
+SPICE_AUDIO
+SPICE_IS_AUDIO
+SPICE_TYPE_AUDIO
+spice_audio_get_type
+SPICE_AUDIO_CLASS
+SPICE_IS_AUDIO_CLASS
+SPICE_AUDIO_GET_CLASS
+<SUBSECTION Private>
+SpiceAudioPrivate
+</SECTION>
+
+<SECTION>
+<FILE>channel-display</FILE>
+<TITLE>SpiceDisplayChannel</TITLE>
+SpiceDisplayChannel
+SpiceDisplayChannelClass
+SpiceDisplayMonitorConfig
+SpiceDisplayPrimary
+SpiceGlScanout
+<SUBSECTION>
+spice_display_get_gl_scanout
+spice_display_gl_draw_done
+spice_display_get_primary
+spice_display_change_preferred_compression
+spice_gl_scanout_free
+<SUBSECTION Standard>
+SPICE_DISPLAY_CHANNEL
+SPICE_IS_DISPLAY_CHANNEL
+SPICE_TYPE_DISPLAY_CHANNEL
+spice_display_channel_get_type
+SPICE_DISPLAY_CHANNEL_CLASS
+SPICE_IS_DISPLAY_CHANNEL_CLASS
+SPICE_DISPLAY_CHANNEL_GET_CLASS
+SPICE_TYPE_GL_SCANOUT
+spice_gl_scanout_get_type
+<SUBSECTION Private>
+SpiceDisplayChannelPrivate
+</SECTION>
+
+<SECTION>
+<FILE>channel-cursor</FILE>
+<TITLE>SpiceCursorChannel</TITLE>
+SpiceCursorChannel
+SpiceCursorChannelClass
+<SUBSECTION Standard>
+SPICE_CURSOR_CHANNEL
+SPICE_IS_CURSOR_CHANNEL
+SPICE_TYPE_CURSOR_CHANNEL
+spice_cursor_channel_get_type
+SPICE_CURSOR_CHANNEL_CLASS
+SPICE_IS_CURSOR_CHANNEL_CLASS
+SPICE_CURSOR_CHANNEL_GET_CLASS
+<SUBSECTION Private>
+SpiceCursorChannelPrivate
+</SECTION>
+
+<SECTION>
+<FILE>channel-record</FILE>
+<TITLE>SpiceRecordChannel</TITLE>
+SpiceRecordChannel
+SpiceRecordChannelClass
+<SUBSECTION>
+spice_record_send_data
+<SUBSECTION Standard>
+SPICE_RECORD_CHANNEL
+SPICE_IS_RECORD_CHANNEL
+SPICE_TYPE_RECORD_CHANNEL
+spice_record_channel_get_type
+SPICE_RECORD_CHANNEL_CLASS
+SPICE_IS_RECORD_CHANNEL_CLASS
+SPICE_RECORD_CHANNEL_GET_CLASS
+<SUBSECTION Private>
+SpiceRecordChannelPrivate
+</SECTION>
+
+<SECTION>
+<FILE>channel-inputs</FILE>
+<TITLE>SpiceInputsChannel</TITLE>
+SpiceInputsChannel
+SpiceInputsChannelClass
+SpiceInputsLock
+<SUBSECTION>
+spice_inputs_motion
+spice_inputs_position
+spice_inputs_button_press
+spice_inputs_button_release
+spice_inputs_key_press
+spice_inputs_key_press_and_release
+spice_inputs_key_release
+spice_inputs_set_key_locks
+<SUBSECTION Standard>
+SPICE_TYPE_INPUTS_LOCK
+spice_inputs_lock_get_type
+SPICE_INPUTS_CHANNEL
+SPICE_IS_INPUTS_CHANNEL
+SPICE_TYPE_INPUTS_CHANNEL
+spice_inputs_channel_get_type
+SPICE_INPUTS_CHANNEL_CLASS
+SPICE_IS_INPUTS_CHANNEL_CLASS
+SPICE_INPUTS_CHANNEL_GET_CLASS
+<SUBSECTION Private>
+SpiceInputsChannelPrivate
+</SECTION>
+
+<SECTION>
+<FILE>channel-smartcard</FILE>
+<TITLE>SpiceSmartcardChannel</TITLE>
+SpiceSmartcardChannel
+SpiceSmartcardChannelClass
+<SUBSECTION Standard>
+SPICE_SMARTCARD_CHANNEL
+SPICE_IS_SMARTCARD_CHANNEL
+SPICE_TYPE_SMARTCARD_CHANNEL
+spice_smartcard_channel_get_type
+SPICE_SMARTCARD_CHANNEL_CLASS
+SPICE_IS_SMARTCARD_CHANNEL_CLASS
+SPICE_SMARTCARD_CHANNEL_GET_CLASS
+<SUBSECTION Private>
+SpiceSmartcardChannelPrivate
+</SECTION>
+
+<SECTION>
+<FILE>smartcard-manager</FILE>
+<TITLE>SpiceSmartcardManager</TITLE>
+SpiceSmartcardManager
+SpiceSmartcardManagerClass
+SpiceSmartcardReader
+<SUBSECTION>
+spice_smartcard_manager_get
+spice_smartcard_manager_get_readers
+spice_smartcard_manager_insert_card
+spice_smartcard_manager_remove_card
+<SUBSECTION>
+spice_smartcard_reader_is_software
+spice_smartcard_reader_insert_card
+spice_smartcard_reader_remove_card
+<SUBSECTION Standard>
+SPICE_SMARTCARD_MANAGER
+SPICE_IS_SMARTCARD_MANAGER
+SPICE_TYPE_SMARTCARD_MANAGER
+spice_smartcard_manager_get_type
+SPICE_SMARTCARD_MANAGER_CLASS
+SPICE_IS_SMARTCARD_MANAGER_CLASS
+SPICE_SMARTCARD_MANAGER_GET_CLASS
+SPICE_TYPE_SMARTCARD_READER
+spice_smartcard_reader_get_type
+<SUBSECTION Private>
+SpiceSmartcardManagerPrivate
+</SECTION>
+
+<SECTION>
+<FILE>channel-usbredir</FILE>
+<TITLE>SpiceUsbredirChannel</TITLE>
+SpiceUsbredirChannel
+SpiceUsbredirChannelClass
+<SUBSECTION Standard>
+SPICE_USBREDIR_CHANNEL
+SPICE_IS_USBREDIR_CHANNEL
+SPICE_TYPE_USBREDIR_CHANNEL
+spice_usbredir_channel_get_type
+SPICE_USBREDIR_CHANNEL_CLASS
+SPICE_IS_USBREDIR_CHANNEL_CLASS
+SPICE_USBREDIR_CHANNEL_GET_CLASS
+<SUBSECTION Private>
+SpiceUsbredirChannelPrivate
+</SECTION>
+
+<SECTION>
+<FILE>usb-device-manager</FILE>
+<TITLE>SpiceUsbDeviceManager</TITLE>
+SpiceUsbDeviceManager
+SpiceUsbDeviceManagerClass
+<SUBSECTION>
+spice_usb_device_manager_get
+spice_usb_device_manager_get_devices
+spice_usb_device_manager_get_devices_with_filter
+spice_usb_device_manager_is_device_connected
+spice_usb_device_manager_is_redirecting
+spice_usb_device_manager_can_redirect_device
+spice_usb_device_manager_connect_device_async
+spice_usb_device_manager_connect_device_finish
+spice_usb_device_manager_disconnect_device
+spice_usb_device_manager_disconnect_device_async
+spice_usb_device_manager_disconnect_device_finish
+<SUBSECTION>
+SpiceUsbDevice
+spice_usb_device_get_description
+spice_usb_device_get_libusb_device
+<SUBSECTION Standard>
+SPICE_USB_DEVICE_MANAGER
+SPICE_IS_USB_DEVICE_MANAGER
+SPICE_TYPE_USB_DEVICE
+SPICE_TYPE_USB_DEVICE_MANAGER
+spice_usb_device_manager_get_type
+spice_usb_device_get_type
+SPICE_USB_DEVICE_MANAGER_CLASS
+SPICE_IS_USB_DEVICE_MANAGER_CLASS
+SPICE_USB_DEVICE_MANAGER_GET_CLASS
+<SUBSECTION Private>
+SpiceUsbDeviceManagerPrivate
+</SECTION>
+
+<SECTION>
+<FILE>spice-gtk-session</FILE>
+<TITLE>SpiceGtkSession</TITLE>
+spice_gtk_session_get
+spice_gtk_session_copy_to_guest
+spice_gtk_session_paste_from_guest
+<SUBSECTION Standard>
+SPICE_GTK_SESSION
+SPICE_IS_GTK_SESSION
+SPICE_TYPE_GTK_SESSION
+spice_gtk_session_get_type
+SPICE_GTK_SESSION_CLASS
+SPICE_IS_GTK_SESSION_CLASS
+SPICE_GTK_SESSION_GET_CLASS
+<SUBSECTION Private>
+SpiceGtkSessionPrivate
+</SECTION>
+
+<SECTION>
+<FILE>spice-widget</FILE>
+<TITLE>SpiceDisplay</TITLE>
+SpiceDisplayKeyEvent
+spice_display_new
+spice_display_new_with_monitor
+spice_display_mouse_ungrab
+spice_display_set_grab_keys
+spice_display_get_grab_keys
+spice_display_send_keys
+spice_display_get_pixbuf
+<SUBSECTION>
+SpiceGrabSequence
+spice_grab_sequence_new
+spice_grab_sequence_new_from_string
+spice_grab_sequence_copy
+spice_grab_sequence_free
+spice_grab_sequence_as_string
+<SUBSECTION Standard>
+SPICE_DISPLAY
+SPICE_IS_DISPLAY
+SPICE_TYPE_DISPLAY
+spice_display_get_type
+SPICE_DISPLAY_CLASS
+SPICE_IS_DISPLAY_CLASS
+SPICE_DISPLAY_GET_CLASS
+SPICE_TYPE_GRAB_SEQUENCE
+spice_grab_sequence_get_type
+SPICE_TYPE_DISPLAY_KEY_EVENT
+spice_display_key_event_get_type
+<SUBSECTION Private>
+SpiceDisplayPrivate
+</SECTION>
+
+<SECTION>
+<FILE>usb-device-widget</FILE>
+<TITLE>SpiceUsbDeviceWidget</TITLE>
+<SUBSECTION>
+spice_usb_device_widget_new
+<SUBSECTION Standard>
+SPICE_USB_DEVICE_WIDGET
+SPICE_IS_USB_DEVICE_WIDGET
+spice_usb_device_widget_get_type
+SPICE_USB_DEVICE_WIDGET_CLASS
+SPICE_IS_USB_DEVICE_WIDGET_CLASS
+SPICE_USB_DEVICE_WIDGET_GET_CLASS
+SPICE_TYPE_USB_DEVICE_WIDGET
+<SUBSECTION Private>
+SpiceUsbDeviceWidgetPrivate
+SpiceGtkBox
+SpiceGtkBoxClass
+</SECTION>
+
+<SECTION>
+<FILE>spice-util</FILE>
+spice_util_set_debug
+spice_util_get_version_string
+spice_uuid_to_string
+<SUBSECTION Private>
+SPICE_DEBUG
+spice_util_get_debug
+SPICE_RESERVED_PADDING
+SPICE_DEPRECATED_FOR
+spice_g_signal_connect_object
+SPICE_DEPRECATED
+SPICE_GNUC_DEPRECATED_FOR
+</SECTION>
+
+<SECTION>
+<FILE>spice-version</FILE>
+SPICE_GTK_CHECK_VERSION
+SPICE_GTK_MAJOR_VERSION
+SPICE_GTK_MICRO_VERSION
+SPICE_GTK_MINOR_VERSION
+</SECTION>
+
+<SECTION>
+<FILE>channel-port</FILE>
+<TITLE>SpicePortChannel</TITLE>
+SpicePortChannel
+SpicePortChannelClass
+<SUBSECTION>
+spice_port_event
+spice_port_write_async
+spice_port_write_finish
+<SUBSECTION Standard>
+SPICE_PORT_CHANNEL
+SPICE_IS_PORT_CHANNEL
+SPICE_TYPE_PORT_CHANNEL
+spice_port_channel_get_type
+SPICE_PORT_CHANNEL_CLASS
+SPICE_IS_PORT_CHANNEL_CLASS
+SPICE_PORT_CHANNEL_GET_CLASS
+<SUBSECTION Private>
+SpicePortChannelPrivate
+</SECTION>
+
+<SECTION>
+<FILE>spice-uri</FILE>
+spice_uri_get_scheme
+spice_uri_set_scheme
+spice_uri_get_hostname
+spice_uri_set_hostname
+spice_uri_get_port
+spice_uri_set_port
+spice_uri_get_user
+spice_uri_set_user
+spice_uri_get_password
+spice_uri_set_password
+spice_uri_to_string
+SpiceURIClass
+SpiceURI
+<SUBSECTION Standard>
+SPICE_IS_URI
+SPICE_IS_URI_CLASS
+SPICE_TYPE_URI
+SPICE_URI
+SPICE_URI_CLASS
+SPICE_URI_GET_CLASS
+spice_uri_get_type
+<SUBSECTION Private>
+SpiceURIPrivate
+</SECTION>
+
+<SECTION>
+<FILE>channel-webdav</FILE>
+<TITLE>SpiceWebdavChannel</TITLE>
+SpiceWebdavChannel
+SpiceWebdavChannelClass
+<SUBSECTION Standard>
+SPICE_IS_WEBDAV_CHANNEL
+SPICE_IS_WEBDAV_CHANNEL_CLASS
+SPICE_TYPE_WEBDAV_CHANNEL
+SPICE_WEBDAV_CHANNEL
+SPICE_WEBDAV_CHANNEL_CLASS
+SPICE_WEBDAV_CHANNEL_GET_CLASS
+spice_webdav_channel_get_type
+<SUBSECTION Private>
+SpiceWebdavChannelPrivate
+</SECTION>
+
+<SECTION>
+<FILE>file-transfer-task</FILE>
+<TITLE>SpiceFileTransferTask</TITLE>
+<SUBSECTION>
+spice_file_transfer_task_get_progress
+spice_file_transfer_task_get_filename
+spice_file_transfer_task_get_total_bytes
+spice_file_transfer_task_get_transferred_bytes
+spice_file_transfer_task_cancel
+<SUBSECTION Standard>
+SPICE_FILE_TRANSFER_TASK
+SPICE_IS_FILE_TRANSFER_TASK
+SPICE_TYPE_FILE_TRANSFER_TASK
+spice_file_transfer_task_get_type
+SPICE_FILE_TRANSFER_TASK_CLASS
+SPICE_IS_FILE_TRANSFER_TASK_CLASS
+SPICE_FILE_TRANSFER_TASK_GET_CLASS
+<SUBSECTION Private>
+SpiceFileTransferTask
+SpiceFileTransferTaskClass
+SpiceFileTransferTaskPrivate
+</SECTION>
--- /dev/null
+#include "spice-audio.h"
+#include "spice-client.h"
+#include "spice-types.h"
+#include "spice-session.h"
+#include "spice-channel.h"
+#include "spice-glib-enums.h"
+#include "spice-util.h"
+#include "channel-main.h"
+#include "channel-display.h"
+#include "channel-cursor.h"
+#include "channel-inputs.h"
+#include "channel-playback.h"
+#include "channel-record.h"
+#include "channel-smartcard.h"
+#include "channel-usbredir.h"
+#include "channel-webdav.h"
+#include "spice-gtk-session.h"
+#include "spice-widget.h"
+#include "spice-grabsequence.h"
+#include "smartcard-manager.h"
+#include "usb-device-manager.h"
+#include "usb-device-widget.h"
+#include "spice-file-transfer-task.h"
+
+spice_audio_get_type
+spice_channel_event_get_type
+spice_channel_get_type
+spice_cursor_channel_get_type
+spice_display_channel_get_type
+spice_display_get_type
+spice_grab_sequence_get_type
+spice_gtk_session_get_type
+spice_inputs_channel_get_type
+spice_inputs_lock_get_type
+spice_main_channel_get_type
+spice_playback_channel_get_type
+spice_record_channel_get_type
+spice_session_get_type
+spice_session_verify_get_type
+spice_smartcard_channel_get_type
+spice_smartcard_manager_get_type
+spice_session_verify_get_type
+spice_usbredir_channel_get_type
+spice_usb_device_get_type
+spice_usb_device_manager_get_type
+spice_usb_device_widget_get_type
+spice_port_channel_get_type
+spice_webdav_channel_get_type
+spice_file_transfer_task_get_type
--- /dev/null
+# -*- mode: makefile -*-
+
+####################################
+# Everything below here is generic #
+####################################
+
+if GTK_DOC_USE_LIBTOOL
+GTKDOC_CC = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(INCLUDES) $(GTKDOC_DEPS_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+GTKDOC_LD = $(LIBTOOL) --tag=CC --mode=link $(CC) $(GTKDOC_DEPS_LIBS) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS)
+GTKDOC_RUN = $(LIBTOOL) --mode=execute
+else
+GTKDOC_CC = $(CC) $(INCLUDES) $(GTKDOC_DEPS_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+GTKDOC_LD = $(CC) $(GTKDOC_DEPS_LIBS) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS)
+GTKDOC_RUN =
+endif
+
+# We set GPATH here; this gives us semantics for GNU make
+# which are more like other make's VPATH, when it comes to
+# whether a source that is a target of one rule is then
+# searched for in VPATH/GPATH.
+#
+GPATH = $(srcdir)
+
+TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE)
+
+SETUP_FILES = \
+ $(content_files) \
+ $(expand_content_files) \
+ $(DOC_MAIN_SGML_FILE) \
+ $(DOC_MODULE)-sections.txt \
+ $(DOC_MODULE)-overrides.txt
+
+EXTRA_DIST = \
+ $(HTML_IMAGES) \
+ $(SETUP_FILES)
+
+DOC_STAMPS=setup-build.stamp scan-build.stamp sgml-build.stamp \
+ html-build.stamp pdf-build.stamp \
+ sgml.stamp html.stamp pdf.stamp
+
+SCANOBJ_FILES = \
+ $(DOC_MODULE).args \
+ $(DOC_MODULE).hierarchy \
+ $(DOC_MODULE).interfaces \
+ $(DOC_MODULE).prerequisites \
+ $(DOC_MODULE).signals
+
+REPORT_FILES = \
+ $(DOC_MODULE)-undocumented.txt \
+ $(DOC_MODULE)-undeclared.txt \
+ $(DOC_MODULE)-unused.txt
+
+gtkdoc-check.test: Makefile
+ $(AM_V_GEN)echo "#!/bin/sh -e" > $@; \
+ echo "$(GTKDOC_CHECK_PATH) || exit 1" >> $@; \
+ chmod +x $@
+
+CLEANFILES = $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS) gtkdoc-check.test
+
+if GTK_DOC_BUILD_HTML
+HTML_BUILD_STAMP=html-build.stamp
+else
+HTML_BUILD_STAMP=
+endif
+if GTK_DOC_BUILD_PDF
+PDF_BUILD_STAMP=pdf-build.stamp
+else
+PDF_BUILD_STAMP=
+endif
+
+all-gtk-doc: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP)
+.PHONY: all-gtk-doc
+
+if ENABLE_GTK_DOC
+all-local: all-gtk-doc
+endif
+
+docs: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP)
+
+$(REPORT_FILES): sgml-build.stamp
+
+#### setup ####
+
+GTK_DOC_V_SETUP=$(GTK_DOC_V_SETUP_$(V))
+GTK_DOC_V_SETUP_=$(GTK_DOC_V_SETUP_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_SETUP_0=@echo " DOC Preparing build";
+
+setup-build.stamp:
+ -$(GTK_DOC_V_SETUP)if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \
+ files=`echo $(SETUP_FILES) $(DOC_MODULE).types`; \
+ if test "x$$files" != "x" ; then \
+ for file in $$files ; do \
+ destdir=`dirname $(abs_builddir)/$$file`; \
+ test -d "$$destdir" || mkdir -p "$$destdir"; \
+ test -f $(abs_srcdir)/$$file && \
+ cp -pf $(abs_srcdir)/$$file $(abs_builddir)/$$file || true; \
+ done; \
+ fi; \
+ fi
+ $(AM_V_at)touch setup-build.stamp
+
+
+#### scan ####
+
+GTK_DOC_V_SCAN=$(GTK_DOC_V_SCAN_$(V))
+GTK_DOC_V_SCAN_=$(GTK_DOC_V_SCAN_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_SCAN_0=@echo " DOC Scanning header files";
+
+GTK_DOC_V_INTROSPECT=$(GTK_DOC_V_INTROSPECT_$(V))
+GTK_DOC_V_INTROSPECT_=$(GTK_DOC_V_INTROSPECT_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_INTROSPECT_0=@echo " DOC Introspecting gobjects";
+
+scan-build.stamp: setup-build.stamp $(HFILE_GLOB) $(CFILE_GLOB)
+ $(GTK_DOC_V_SCAN)_source_dir='' ; \
+ for i in $(DOC_SOURCE_DIR) ; do \
+ _source_dir="$${_source_dir} --source-dir=$$i" ; \
+ done ; \
+ gtkdoc-scan --module=$(DOC_MODULE) --ignore-headers="$(IGNORE_HFILES)" $${_source_dir} $(SCAN_OPTIONS) $(EXTRA_HFILES)
+ $(GTK_DOC_V_INTROSPECT)if grep -l '^..*$$' $(DOC_MODULE).types > /dev/null 2>&1 ; then \
+ scanobj_options=""; \
+ gtkdoc-scangobj 2>&1 --help | grep >/dev/null "\-\-verbose"; \
+ if test "$$?" = "0"; then \
+ if test "x$(V)" = "x1"; then \
+ scanobj_options="--verbose"; \
+ fi; \
+ fi; \
+ CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" RUN="$(GTKDOC_RUN)" CFLAGS="$(GTKDOC_CFLAGS) $(CFLAGS)" LDFLAGS="$(GTKDOC_LIBS) $(LDFLAGS)" \
+ gtkdoc-scangobj $(SCANGOBJ_OPTIONS) $$scanobj_options --module=$(DOC_MODULE); \
+ else \
+ for i in $(SCANOBJ_FILES) ; do \
+ test -f $$i || touch $$i ; \
+ done \
+ fi
+ $(AM_V_at)touch scan-build.stamp
+
+$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp
+ @true
+
+#### xml ####
+
+GTK_DOC_V_XML=$(GTK_DOC_V_XML_$(V))
+GTK_DOC_V_XML_=$(GTK_DOC_V_XML_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_XML_0=@echo " DOC Building XML";
+
+sgml-build.stamp: setup-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(HFILE_GLOB) $(CFILE_GLOB) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt $(expand_content_files) xml/gtkdocentities.ent
+ $(GTK_DOC_V_XML)_source_dir='' ; \
+ for i in $(DOC_SOURCE_DIR) ; do \
+ _source_dir="$${_source_dir} --source-dir=$$i" ; \
+ done ; \
+ gtkdoc-mkdb --module=$(DOC_MODULE) --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $${_source_dir} $(MKDB_OPTIONS)
+ $(AM_V_at)touch sgml-build.stamp
+
+sgml.stamp: sgml-build.stamp
+ @true
+
+xml/gtkdocentities.ent: Makefile
+ $(GTK_DOC_V_XML)$(MKDIR_P) $(@D) && ( \
+ echo "<!ENTITY package \"$(PACKAGE)\">"; \
+ echo "<!ENTITY package_bugreport \"$(PACKAGE_BUGREPORT)\">"; \
+ echo "<!ENTITY package_name \"$(PACKAGE_NAME)\">"; \
+ echo "<!ENTITY package_string \"$(PACKAGE_STRING)\">"; \
+ echo "<!ENTITY package_tarname \"$(PACKAGE_TARNAME)\">"; \
+ echo "<!ENTITY package_url \"$(PACKAGE_URL)\">"; \
+ echo "<!ENTITY package_version \"$(PACKAGE_VERSION)\">"; \
+ ) > $@
+
+#### html ####
+
+GTK_DOC_V_HTML=$(GTK_DOC_V_HTML_$(V))
+GTK_DOC_V_HTML_=$(GTK_DOC_V_HTML_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_HTML_0=@echo " DOC Building HTML";
+
+GTK_DOC_V_XREF=$(GTK_DOC_V_XREF_$(V))
+GTK_DOC_V_XREF_=$(GTK_DOC_V_XREF_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_XREF_0=@echo " DOC Fixing cross-references";
+
+html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files)
+ $(GTK_DOC_V_HTML)rm -rf html && mkdir html && \
+ mkhtml_options=""; \
+ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-verbose"; \
+ if test "$$?" = "0"; then \
+ if test "x$(V)" = "x1"; then \
+ mkhtml_options="$$mkhtml_options --verbose"; \
+ fi; \
+ fi; \
+ gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \
+ if test "$$?" = "0"; then \
+ mkhtml_options="$$mkhtml_options --path=\"$(abs_srcdir)\""; \
+ fi; \
+ cd html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
+ -@test "x$(HTML_IMAGES)" = "x" || \
+ for file in $(HTML_IMAGES) ; do \
+ if test -f $(abs_srcdir)/$$file ; then \
+ cp $(abs_srcdir)/$$file $(abs_builddir)/html; \
+ fi; \
+ if test -f $(abs_builddir)/$$file ; then \
+ cp $(abs_builddir)/$$file $(abs_builddir)/html; \
+ fi; \
+ done;
+ $(GTK_DOC_V_XREF)gtkdoc-fixxref --module=$(DOC_MODULE) --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
+ $(AM_V_at)touch html-build.stamp
+
+#### pdf ####
+
+GTK_DOC_V_PDF=$(GTK_DOC_V_PDF_$(V))
+GTK_DOC_V_PDF_=$(GTK_DOC_V_PDF_$(AM_DEFAULT_VERBOSITY))
+GTK_DOC_V_PDF_0=@echo " DOC Building PDF";
+
+pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) $(expand_content_files)
+ $(GTK_DOC_V_PDF)rm -f $(DOC_MODULE).pdf && \
+ mkpdf_options=""; \
+ gtkdoc-mkpdf 2>&1 --help | grep >/dev/null "\-\-verbose"; \
+ if test "$$?" = "0"; then \
+ if test "x$(V)" = "x1"; then \
+ mkpdf_options="$$mkpdf_options --verbose"; \
+ fi; \
+ fi; \
+ if test "x$(HTML_IMAGES)" != "x"; then \
+ for img in $(HTML_IMAGES); do \
+ part=`dirname $$img`; \
+ echo $$mkpdf_options | grep >/dev/null "\-\-imgdir=$$part "; \
+ if test $$? != 0; then \
+ mkpdf_options="$$mkpdf_options --imgdir=$$part"; \
+ fi; \
+ done; \
+ fi; \
+ gtkdoc-mkpdf --path="$(abs_srcdir)" $$mkpdf_options $(DOC_MODULE) $(DOC_MAIN_SGML_FILE) $(MKPDF_OPTIONS)
+ $(AM_V_at)touch pdf-build.stamp
+
+##############
+
+clean-local:
+ @rm -f *~ *.bak
+ @rm -rf .libs
+ @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-types" ; then \
+ rm -f $(DOC_MODULE).types; \
+ fi
+ @if echo $(SCAN_OPTIONS) | grep -q "\-\-rebuild-sections" ; then \
+ rm -f $(DOC_MODULE)-sections.txt; \
+ fi
+
+distclean-local:
+ @rm -rf xml html $(REPORT_FILES) $(DOC_MODULE).pdf \
+ $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt
+ @if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \
+ rm -f $(SETUP_FILES) $(DOC_MODULE).types; \
+ fi
+
+maintainer-clean-local:
+ @rm -rf xml html
+
+install-data-local:
+ @installfiles=`echo $(builddir)/html/*`; \
+ if test "$$installfiles" = '$(builddir)/html/*'; \
+ then echo 1>&2 'Nothing to install' ; \
+ else \
+ if test -n "$(DOC_MODULE_VERSION)"; then \
+ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \
+ else \
+ installdir="$(DESTDIR)$(TARGET_DIR)"; \
+ fi; \
+ $(mkinstalldirs) $${installdir} ; \
+ for i in $$installfiles; do \
+ echo ' $(INSTALL_DATA) '$$i ; \
+ $(INSTALL_DATA) $$i $${installdir}; \
+ done; \
+ if test -n "$(DOC_MODULE_VERSION)"; then \
+ mv -f $${installdir}/$(DOC_MODULE).devhelp2 \
+ $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp2; \
+ fi; \
+ $(GTKDOC_REBASE) --relative --dest-dir=$(DESTDIR) --html-dir=$${installdir}; \
+ fi
+
+uninstall-local:
+ @if test -n "$(DOC_MODULE_VERSION)"; then \
+ installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \
+ else \
+ installdir="$(DESTDIR)$(TARGET_DIR)"; \
+ fi; \
+ rm -rf $${installdir}
+
+#
+# Require gtk-doc when making dist
+#
+if HAVE_GTK_DOC
+dist-check-gtkdoc: docs
+else
+dist-check-gtkdoc:
+ @echo "*** gtk-doc is needed to run 'make dist'. ***"
+ @echo "*** gtk-doc was not found when 'configure' ran. ***"
+ @echo "*** please install gtk-doc and rerun 'configure'. ***"
+ @false
+endif
+
+dist-hook: dist-check-gtkdoc all-gtk-doc dist-hook-local
+ @mkdir $(distdir)/html
+ @cp ./html/* $(distdir)/html
+ @-cp ./$(DOC_MODULE).pdf $(distdir)/
+ @-cp ./$(DOC_MODULE).types $(distdir)/
+ @-cp ./$(DOC_MODULE)-sections.txt $(distdir)/
+ @cd $(distdir) && rm -f $(DISTCLEANFILES)
+ @$(GTKDOC_REBASE) --online --relative --html-dir=$(distdir)/html
+
+.PHONY : dist-hook-local docs
--- /dev/null
+dnl -*- mode: autoconf -*-
+
+# serial 2
+
+dnl Usage:
+dnl GTK_DOC_CHECK([minimum-gtk-doc-version])
+AC_DEFUN([GTK_DOC_CHECK],
+[
+ AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+ AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
+ AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
+
+ ifelse([$1],[],[gtk_doc_requires="gtk-doc"],[gtk_doc_requires="gtk-doc >= $1"])
+ AC_MSG_CHECKING([for gtk-doc])
+ PKG_CHECK_EXISTS([$gtk_doc_requires],[have_gtk_doc=yes],[have_gtk_doc=no])
+ AC_MSG_RESULT($have_gtk_doc)
+
+ if test "$have_gtk_doc" = "no"; then
+ AC_MSG_WARN([
+ You will not be able to create source packages with 'make dist'
+ because $gtk_doc_requires is not found.])
+ fi
+
+ dnl check for tools we added during development
+ dnl Use AC_CHECK_PROG to avoid the check target using an absolute path that
+ dnl may not be writable by the user. Currently, automake requires that the
+ dnl test name must end in '.test'.
+ dnl https://bugzilla.gnome.org/show_bug.cgi?id=701638
+ AC_CHECK_PROG([GTKDOC_CHECK],[gtkdoc-check],[gtkdoc-check.test])
+ AC_PATH_PROG([GTKDOC_CHECK_PATH],[gtkdoc-check])
+ AC_PATH_PROGS([GTKDOC_REBASE],[gtkdoc-rebase],[true])
+ AC_PATH_PROG([GTKDOC_MKPDF],[gtkdoc-mkpdf])
+
+ dnl for overriding the documentation installation directory
+ AC_ARG_WITH([html-dir],
+ AS_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),,
+ [with_html_dir='${datadir}/gtk-doc/html'])
+ HTML_DIR="$with_html_dir"
+ AC_SUBST([HTML_DIR])
+
+ dnl enable/disable documentation building
+ AC_ARG_ENABLE([gtk-doc],
+ AS_HELP_STRING([--enable-gtk-doc],
+ [use gtk-doc to build documentation [[default=no]]]),,
+ [enable_gtk_doc=no])
+
+ AC_MSG_CHECKING([whether to build gtk-doc documentation])
+ AC_MSG_RESULT($enable_gtk_doc)
+
+ if test "x$enable_gtk_doc" = "xyes" && test "$have_gtk_doc" = "no"; then
+ AC_MSG_ERROR([
+ You must have $gtk_doc_requires installed to build documentation for
+ $PACKAGE_NAME. Please install gtk-doc or disable building the
+ documentation by adding '--disable-gtk-doc' to '[$]0'.])
+ fi
+
+ dnl don't check for glib if we build glib
+ if test "x$PACKAGE_NAME" != "xglib"; then
+ dnl don't fail if someone does not have glib
+ PKG_CHECK_MODULES(GTKDOC_DEPS, glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0,,[:])
+ fi
+
+ dnl enable/disable output formats
+ AC_ARG_ENABLE([gtk-doc-html],
+ AS_HELP_STRING([--enable-gtk-doc-html],
+ [build documentation in html format [[default=yes]]]),,
+ [enable_gtk_doc_html=yes])
+ AC_ARG_ENABLE([gtk-doc-pdf],
+ AS_HELP_STRING([--enable-gtk-doc-pdf],
+ [build documentation in pdf format [[default=no]]]),,
+ [enable_gtk_doc_pdf=no])
+
+ if test -z "$GTKDOC_MKPDF"; then
+ enable_gtk_doc_pdf=no
+ fi
+
+ if test -z "$AM_DEFAULT_VERBOSITY"; then
+ AM_DEFAULT_VERBOSITY=1
+ fi
+ AC_SUBST([AM_DEFAULT_VERBOSITY])
+
+ AM_CONDITIONAL([HAVE_GTK_DOC], [test x$have_gtk_doc = xyes])
+ AM_CONDITIONAL([ENABLE_GTK_DOC], [test x$enable_gtk_doc = xyes])
+ AM_CONDITIONAL([GTK_DOC_BUILD_HTML], [test x$enable_gtk_doc_html = xyes])
+ AM_CONDITIONAL([GTK_DOC_BUILD_PDF], [test x$enable_gtk_doc_pdf = xyes])
+ AM_CONDITIONAL([GTK_DOC_USE_LIBTOOL], [test -n "$LIBTOOL"])
+ AM_CONDITIONAL([GTK_DOC_USE_REBASE], [test -n "$GTKDOC_REBASE"])
+])
--- /dev/null
+## intltool.m4 - Configure intltool for the target system. -*-Shell-script-*-
+## Copyright (C) 2001 Eazel, Inc.
+## Author: Maciej Stachowiak <mjs@noisehavoc.org>
+## Kenneth Christiansen <kenneth@gnu.org>
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+## As a special exception to the GNU General Public License, if you
+## distribute this file as part of a program that contains a
+## configuration script generated by Autoconf, you may include it under
+## the same distribution terms that you use for the rest of that program.
+
+dnl IT_PROG_INTLTOOL([MINIMUM-VERSION], [no-xml])
+# serial 42 IT_PROG_INTLTOOL
+AC_DEFUN([IT_PROG_INTLTOOL], [
+AC_PREREQ([2.50])dnl
+AC_REQUIRE([AM_NLS])dnl
+
+case "$am__api_version" in
+ 1.[01234])
+ AC_MSG_ERROR([Automake 1.5 or newer is required to use intltool])
+ ;;
+ *)
+ ;;
+esac
+
+INTLTOOL_REQUIRED_VERSION_AS_INT=`echo $1 | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'`
+INTLTOOL_APPLIED_VERSION=`intltool-update --version | head -1 | cut -d" " -f3`
+INTLTOOL_APPLIED_VERSION_AS_INT=`echo $INTLTOOL_APPLIED_VERSION | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'`
+if test -n "$1"; then
+ AC_MSG_CHECKING([for intltool >= $1])
+ AC_MSG_RESULT([$INTLTOOL_APPLIED_VERSION found])
+ test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT" ||
+ AC_MSG_ERROR([Your intltool is too old. You need intltool $1 or later.])
+fi
+
+AC_PATH_PROG(INTLTOOL_UPDATE, [intltool-update])
+AC_PATH_PROG(INTLTOOL_MERGE, [intltool-merge])
+AC_PATH_PROG(INTLTOOL_EXTRACT, [intltool-extract])
+if test -z "$INTLTOOL_UPDATE" -o -z "$INTLTOOL_MERGE" -o -z "$INTLTOOL_EXTRACT"; then
+ AC_MSG_ERROR([The intltool scripts were not found. Please install intltool.])
+fi
+
+if test -z "$AM_DEFAULT_VERBOSITY"; then
+ AM_DEFAULT_VERBOSITY=1
+fi
+AC_SUBST([AM_DEFAULT_VERBOSITY])
+
+INTLTOOL_V_MERGE='$(INTLTOOL__v_MERGE_$(V))'
+INTLTOOL__v_MERGE_='$(INTLTOOL__v_MERGE_$(AM_DEFAULT_VERBOSITY))'
+INTLTOOL__v_MERGE_0='@echo " ITMRG " [$]@;'
+AC_SUBST(INTLTOOL_V_MERGE)
+AC_SUBST(INTLTOOL__v_MERGE_)
+AC_SUBST(INTLTOOL__v_MERGE_0)
+
+INTLTOOL_V_MERGE_OPTIONS='$(intltool__v_merge_options_$(V))'
+intltool__v_merge_options_='$(intltool__v_merge_options_$(AM_DEFAULT_VERBOSITY))'
+intltool__v_merge_options_0='-q'
+AC_SUBST(INTLTOOL_V_MERGE_OPTIONS)
+AC_SUBST(intltool__v_merge_options_)
+AC_SUBST(intltool__v_merge_options_0)
+
+ INTLTOOL_DESKTOP_RULE='%.desktop: %.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_KEYS_RULE='%.keys: %.keys.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_PROP_RULE='%.prop: %.prop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_OAF_RULE='%.oaf: %.oaf.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -o -p $(top_srcdir)/po $< [$]@'
+ INTLTOOL_PONG_RULE='%.pong: %.pong.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_SERVER_RULE='%.server: %.server.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_SHEET_RULE='%.sheet: %.sheet.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_UI_RULE='%.ui: %.ui.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_XML_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+if test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge 5000; then
+ INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u --no-translations $< [$]@'
+else
+ INTLTOOL_XML_NOMERGE_RULE='%.xml: %.xml.in $(INTLTOOL_MERGE) ; $(INTLTOOL_V_MERGE)_it_tmp_dir=tmp.intltool.[$][$]RANDOM && mkdir [$][$]_it_tmp_dir && LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u [$][$]_it_tmp_dir $< [$]@ && rmdir [$][$]_it_tmp_dir'
+fi
+ INTLTOOL_XAM_RULE='%.xam: %.xml.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_KBD_RULE='%.kbd: %.kbd.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_CAVES_RULE='%.caves: %.caves.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_SCHEMAS_RULE='%.schemas: %.schemas.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_THEME_RULE='%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_SERVICE_RULE='%.service: %.service.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+ INTLTOOL_POLICY_RULE='%.policy: %.policy.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; $(INTLTOOL_V_MERGE)LC_ALL=C $(INTLTOOL_MERGE) $(INTLTOOL_V_MERGE_OPTIONS) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+
+_IT_SUBST(INTLTOOL_DESKTOP_RULE)
+_IT_SUBST(INTLTOOL_DIRECTORY_RULE)
+_IT_SUBST(INTLTOOL_KEYS_RULE)
+_IT_SUBST(INTLTOOL_PROP_RULE)
+_IT_SUBST(INTLTOOL_OAF_RULE)
+_IT_SUBST(INTLTOOL_PONG_RULE)
+_IT_SUBST(INTLTOOL_SERVER_RULE)
+_IT_SUBST(INTLTOOL_SHEET_RULE)
+_IT_SUBST(INTLTOOL_SOUNDLIST_RULE)
+_IT_SUBST(INTLTOOL_UI_RULE)
+_IT_SUBST(INTLTOOL_XAM_RULE)
+_IT_SUBST(INTLTOOL_KBD_RULE)
+_IT_SUBST(INTLTOOL_XML_RULE)
+_IT_SUBST(INTLTOOL_XML_NOMERGE_RULE)
+_IT_SUBST(INTLTOOL_CAVES_RULE)
+_IT_SUBST(INTLTOOL_SCHEMAS_RULE)
+_IT_SUBST(INTLTOOL_THEME_RULE)
+_IT_SUBST(INTLTOOL_SERVICE_RULE)
+_IT_SUBST(INTLTOOL_POLICY_RULE)
+
+# Check the gettext tools to make sure they are GNU
+AC_PATH_PROG(XGETTEXT, xgettext)
+AC_PATH_PROG(MSGMERGE, msgmerge)
+AC_PATH_PROG(MSGFMT, msgfmt)
+AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+if test -z "$XGETTEXT" -o -z "$MSGMERGE" -o -z "$MSGFMT"; then
+ AC_MSG_ERROR([GNU gettext tools not found; required for intltool])
+fi
+xgversion="`$XGETTEXT --version|grep '(GNU ' 2> /dev/null`"
+mmversion="`$MSGMERGE --version|grep '(GNU ' 2> /dev/null`"
+mfversion="`$MSGFMT --version|grep '(GNU ' 2> /dev/null`"
+if test -z "$xgversion" -o -z "$mmversion" -o -z "$mfversion"; then
+ AC_MSG_ERROR([GNU gettext tools not found; required for intltool])
+fi
+
+AC_PATH_PROG(INTLTOOL_PERL, perl)
+if test -z "$INTLTOOL_PERL"; then
+ AC_MSG_ERROR([perl not found])
+fi
+AC_MSG_CHECKING([for perl >= 5.8.1])
+$INTLTOOL_PERL -e "use 5.8.1;" > /dev/null 2>&1
+if test $? -ne 0; then
+ AC_MSG_ERROR([perl 5.8.1 is required for intltool])
+else
+ IT_PERL_VERSION=`$INTLTOOL_PERL -e "printf '%vd', $^V"`
+ AC_MSG_RESULT([$IT_PERL_VERSION])
+fi
+if test "x$2" != "xno-xml"; then
+ AC_MSG_CHECKING([for XML::Parser])
+ if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then
+ AC_MSG_RESULT([ok])
+ else
+ AC_MSG_ERROR([XML::Parser perl module is required for intltool])
+ fi
+fi
+
+# Substitute ALL_LINGUAS so we can use it in po/Makefile
+AC_SUBST(ALL_LINGUAS)
+
+IT_PO_SUBDIR([po])
+
+])
+
+
+# IT_PO_SUBDIR(DIRNAME)
+# ---------------------
+# All po subdirs have to be declared with this macro; the subdir "po" is
+# declared by IT_PROG_INTLTOOL.
+#
+AC_DEFUN([IT_PO_SUBDIR],
+[AC_PREREQ([2.53])dnl We use ac_top_srcdir inside AC_CONFIG_COMMANDS.
+dnl
+dnl The following CONFIG_COMMANDS should be executed at the very end
+dnl of config.status.
+AC_CONFIG_COMMANDS_PRE([
+ AC_CONFIG_COMMANDS([$1/stamp-it], [
+ if [ ! grep "^# INTLTOOL_MAKEFILE$" "$1/Makefile.in" > /dev/null ]; then
+ AC_MSG_ERROR([$1/Makefile.in.in was not created by intltoolize.])
+ fi
+ rm -f "$1/stamp-it" "$1/stamp-it.tmp" "$1/POTFILES" "$1/Makefile.tmp"
+ >"$1/stamp-it.tmp"
+ [sed '/^#/d
+ s/^[[].*] *//
+ /^[ ]*$/d
+ '"s|^| $ac_top_srcdir/|" \
+ "$srcdir/$1/POTFILES.in" | sed '$!s/$/ \\/' >"$1/POTFILES"
+ ]
+ [sed '/^POTFILES =/,/[^\\]$/ {
+ /^POTFILES =/!d
+ r $1/POTFILES
+ }
+ ' "$1/Makefile.in" >"$1/Makefile"]
+ rm -f "$1/Makefile.tmp"
+ mv "$1/stamp-it.tmp" "$1/stamp-it"
+ ])
+])dnl
+])
+
+# _IT_SUBST(VARIABLE)
+# -------------------
+# Abstract macro to do either _AM_SUBST_NOTMAKE or AC_SUBST
+#
+AC_DEFUN([_IT_SUBST],
+[
+AC_SUBST([$1])
+m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([$1])])
+]
+)
+
+# deprecated macros
+AU_ALIAS([AC_PROG_INTLTOOL], [IT_PROG_INTLTOOL])
+# A hint is needed for aclocal from Automake <= 1.9.4:
+# AC_DEFUN([AC_PROG_INTLTOOL], ...)
+
--- /dev/null
+dnl Check whether the linker supports --version-script.
+dnl
+dnl Probes whether the linker supports --version-script with a simple version
+dnl script that only defines a single version. Sets the Automake conditional
+dnl HAVE_LD_VERSION_SCRIPT based on whether it is supported.
+dnl
+dnl Written by Russ Allbery <rra@stanford.edu>
+dnl Based on the gnulib ld-version-script macro from Simon Josefsson
+dnl Copyright 2010 Board of Trustees, Leland Stanford Jr. University
+dnl Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+dnl
+dnl This file is free software; the Free Software Foundation gives unlimited
+dnl permission to copy and/or distribute it, with or without modifications, as
+dnl long as this notice is preserved.
+
+AC_DEFUN([RRA_LD_VERSION_SCRIPT],
+[AC_CACHE_CHECK([if -Wl,--version-script works], [rra_cv_ld_version_script],
+ [save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map"
+ cat > conftest.map <<EOF
+VERSION_1 {
+ global:
+ sym;
+
+ local:
+ *;
+};
+EOF
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
+ [rra_cv_ld_version_script=yes], [rra_cv_ld_version_script=no])
+ rm -f conftest.map
+ LDFLAGS="$save_LDFLAGS"])
+ AM_CONDITIONAL([HAVE_LD_VERSION_SCRIPT],
+ [test x"$rra_cv_ld_version_script" = xyes])])
--- /dev/null
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+])
+
+# serial 58 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_PREPARE_CC_BASENAME
+# -----------------------
+m4_defun([_LT_PREPARE_CC_BASENAME], [
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in @S|@*""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+])# _LT_PREPARE_CC_BASENAME
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
+# but that macro is also expanded into generated libtool script, which
+# arranges for $SED and $ECHO to be set by different means.
+m4_defun([_LT_CC_BASENAME],
+[m4_require([_LT_PREPARE_CC_BASENAME])dnl
+AC_REQUIRE([_LT_DECL_SED])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+func_cc_basename $1
+cc_basename=$func_cc_basename_result
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+m4_require([_LT_CMD_TRUNCATE])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from 'configure', and 'config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain=$ac_aux_dir/ltmain.sh
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the 'libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to 'config.status' so that its
+# declaration there will have the same value as in 'configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags='_LT_TAGS'dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into 'config.status', and then the shell code to quote escape them in
+# for loops in 'config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# '#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+'$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test 0 != $[#]
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try '$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try '$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test yes = "$silent" &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_PREPARE_MUNGE_PATH_LIST
+_LT_PREPARE_CC_BASENAME
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Go], [_LT_LANG(GO)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_GO. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC], [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+ fi
+fi
+if test -z "$GOC"; then
+ AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+ [LT_LANG(GO)],
+ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS=$save_LDFLAGS
+ ])
+
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]][[,.]]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+ m4_if([$1], [CXX],
+[ if test yes != "$lt_cv_apple_cc_single_mod"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script that will find a shell with a builtin
+# printf (that we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+case $ECHO in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
+ [Search for dependent libraries within DIR (or the compiler's sysroot
+ if not specified).])],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([$with_sysroot])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and where our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test yes = "[$]$2"; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+])
+
+if test yes = "[$]$2"; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes = "$cross_compiling"; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen=shl_load],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen=dlopen],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links=nottested
+if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test no = "$hard_links"; then
+ AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
+ [Define to the sub-directory where libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
+ test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
+ test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_PREPARE_MUNGE_PATH_LIST
+# ---------------------------
+# Make sure func_munge_path_list() is defined correctly.
+m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
+[[# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x@S|@2 in
+ x)
+ ;;
+ *:)
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
+ ;;
+ x:*)
+ eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
+ ;;
+ *)
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+]])# _LT_PREPARE_PATH_LIST
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
+[User-defined run-time library search path.])
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a[(]lib.so.V[)]'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[23]].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Add ABI-specific directories to the system library path.
+ sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
+ [Detected run-time system search path for libraries])
+_LT_DECL([], [configure_time_lt_sys_library_path], [2],
+ [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program that can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$1"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac])
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program that can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test no = "$withval" || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi])
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_PATH_DD
+# -----------
+# find a working dd
+m4_defun([_LT_PATH_DD],
+[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
+[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi])
+rm -f conftest.i conftest2.i conftest.out])
+])# _LT_PATH_DD
+
+
+# _LT_CMD_TRUNCATE
+# ----------------
+# find command to truncate a binary pipe
+m4_defun([_LT_CMD_TRUNCATE],
+[m4_require([_LT_PATH_DD])
+AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
+_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
+ [Command to truncate a binary pipe])
+])# _LT_CMD_TRUNCATE
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+os2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+ AC_SUBST([DUMPBIN])
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# _LT_DLL_DEF_P([FILE])
+# ---------------------
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with func_dll_def_p in the libtool script
+AC_DEFUN([_LT_DLL_DEF_P],
+[dnl
+ test DEF = "`$SED -n dnl
+ -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace
+ -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments
+ -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl
+ -e q dnl Only consider the first "real" line
+ $1`" dnl
+])# _LT_DLL_DEF_P
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM=-lm)
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT@&t@_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
+ [Transform the output of nm into a list of symbols to manually relocate])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
+ [The name lister interface])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64, which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Intel*\ [[CF]]*Compiler*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ *Portland\ Group*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ tcc*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
+ ;;
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # traditional, no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ ;;
+ esac
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS=$save_LDFLAGS])
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ linux*)
+ case $cc_basename in
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting $shlibpath_var if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC=$CC
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report what library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC=$lt_save_CC
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test no != "$CXX" &&
+ ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
+ (test g++ != "$CXX"))); then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_caught_CXX_error"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test yes = "$GXX"; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test yes = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='$wl'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ ;;
+ esac
+
+ if test yes = "$GXX"; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag=$shared_flag' $wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ # The "-G" linker flag allows undefined symbols.
+ _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared
+ # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require '-G' NOT '-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)=$GXX
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test yes != "$_lt_caught_CXX_error"
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case @S|@2 in
+ .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
+ *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $prev$p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test x-L = "$p" ||
+ test x-R = "$p"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test no = "$pre_test_object_deps_done"; then
+ case $prev in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)=$prev$p
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test no = "$pre_test_object_deps_done"; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)=$p
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)=$p
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test no = "$F77"; then
+ _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_F77"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)=$G77
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_F77"
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test no = "$FC"; then
+ _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_FC"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_FC"
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code=$lt_simple_compile_test_code
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f "$lt_ac_sed" && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test 10 -lt "$lt_ac_count" && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test "$lt_ac_count" -gt "$lt_ac_max"; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine what file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
--- /dev/null
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 8 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option '$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
+ [_LT_WITH_AIX_SONAME([aix])])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the 'shared' and
+# 'disable-shared' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the 'static' and
+# 'disable-static' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the 'fast-install'
+# and 'disable-fast-install' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_AIX_SONAME([DEFAULT])
+# ----------------------------------
+# implement the --with-aix-soname flag, and support the `aix-soname=aix'
+# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
+# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
+m4_define([_LT_WITH_AIX_SONAME],
+[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
+shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[[5-9]]*,yes)
+ AC_MSG_CHECKING([which variant of shared library versioning to provide])
+ AC_ARG_WITH([aix-soname],
+ [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
+ [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
+ [case $withval in
+ aix|svr4|both)
+ ;;
+ *)
+ AC_MSG_ERROR([Unknown argument to --with-aix-soname])
+ ;;
+ esac
+ lt_cv_with_aix_soname=$with_aix_soname],
+ [AC_CACHE_VAL([lt_cv_with_aix_soname],
+ [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
+ with_aix_soname=$lt_cv_with_aix_soname])
+ AC_MSG_RESULT([$with_aix_soname])
+ if test aix != "$with_aix_soname"; then
+ # For the AIX way of multilib, we name the shared archive member
+ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+ # the AIX toolchain works better with OBJECT_MODE set (default 32).
+ if test 64 = "${OBJECT_MODE-32}"; then
+ shared_archive_member_spec=shr_64
+ else
+ shared_archive_member_spec=shr
+ fi
+ fi
+ ;;
+*)
+ with_aix_soname=aix
+ ;;
+esac
+
+_LT_DECL([], [shared_archive_member_spec], [0],
+ [Shared archive member basename, for filename based shared library versioning on AIX])dnl
+])# _LT_WITH_AIX_SONAME
+
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# LT_INIT options.
+# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [pic_mode=m4_default([$1], [default])])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
--- /dev/null
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59, which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
--- /dev/null
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 4179 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.6])
+m4_define([LT_PACKAGE_REVISION], [2.4.6])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.6'
+macro_revision='2.4.6'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
--- /dev/null
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
--- /dev/null
+# manywarnings.m4 serial 8
+dnl Copyright (C) 2008-2016 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Simon Josefsson
+
+# gl_MANYWARN_COMPLEMENT(OUTVAR, LISTVAR, REMOVEVAR)
+# --------------------------------------------------
+# Copy LISTVAR to OUTVAR except for the entries in REMOVEVAR.
+# Elements separated by whitespace. In set logic terms, the function
+# does OUTVAR = LISTVAR \ REMOVEVAR.
+AC_DEFUN([gl_MANYWARN_COMPLEMENT],
+[
+ gl_warn_set=
+ set x $2; shift
+ for gl_warn_item
+ do
+ case " $3 " in
+ *" $gl_warn_item "*)
+ ;;
+ *)
+ gl_warn_set="$gl_warn_set $gl_warn_item"
+ ;;
+ esac
+ done
+ $1=$gl_warn_set
+])
+
+# gl_MANYWARN_ALL_GCC(VARIABLE)
+# -----------------------------
+# Add all documented GCC warning parameters to variable VARIABLE.
+# Note that you need to test them using gl_WARN_ADD if you want to
+# make sure your gcc understands it.
+AC_DEFUN([gl_MANYWARN_ALL_GCC],
+[
+ dnl First, check for some issues that only occur when combining multiple
+ dnl gcc warning categories.
+ AC_REQUIRE([AC_PROG_CC])
+ if test -n "$GCC"; then
+
+ dnl Check if -W -Werror -Wno-missing-field-initializers is supported
+ dnl with the current $CC $CFLAGS $CPPFLAGS.
+ AC_MSG_CHECKING([whether -Wno-missing-field-initializers is supported])
+ AC_CACHE_VAL([gl_cv_cc_nomfi_supported], [
+ gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -W -Werror -Wno-missing-field-initializers"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[]], [[]])],
+ [gl_cv_cc_nomfi_supported=yes],
+ [gl_cv_cc_nomfi_supported=no])
+ CFLAGS="$gl_save_CFLAGS"])
+ AC_MSG_RESULT([$gl_cv_cc_nomfi_supported])
+
+ if test "$gl_cv_cc_nomfi_supported" = yes; then
+ dnl Now check whether -Wno-missing-field-initializers is needed
+ dnl for the { 0, } construct.
+ AC_MSG_CHECKING([whether -Wno-missing-field-initializers is needed])
+ AC_CACHE_VAL([gl_cv_cc_nomfi_needed], [
+ gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -W -Werror"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[void f (void)
+ {
+ typedef struct { int a; int b; } s_t;
+ s_t s1 = { 0, };
+ }
+ ]],
+ [[]])],
+ [gl_cv_cc_nomfi_needed=no],
+ [gl_cv_cc_nomfi_needed=yes])
+ CFLAGS="$gl_save_CFLAGS"
+ ])
+ AC_MSG_RESULT([$gl_cv_cc_nomfi_needed])
+ fi
+
+ dnl Next, check if -Werror -Wuninitialized is useful with the
+ dnl user's choice of $CFLAGS; some versions of gcc warn that it
+ dnl has no effect if -O is not also used
+ AC_MSG_CHECKING([whether -Wuninitialized is supported])
+ AC_CACHE_VAL([gl_cv_cc_uninitialized_supported], [
+ gl_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Werror -Wuninitialized"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[]], [[]])],
+ [gl_cv_cc_uninitialized_supported=yes],
+ [gl_cv_cc_uninitialized_supported=no])
+ CFLAGS="$gl_save_CFLAGS"])
+ AC_MSG_RESULT([$gl_cv_cc_uninitialized_supported])
+
+ fi
+
+ # List all gcc warning categories.
+ # To compare this list to your installed GCC's, run this Bash command:
+ #
+ # comm -3 \
+ # <(sed -n 's/^ *\(-[^ ]*\) .*/\1/p' manywarnings.m4 | sort) \
+ # <(gcc --help=warnings | sed -n 's/^ \(-[^ ]*\) .*/\1/p' | sort |
+ # grep -v -x -f <(
+ # awk '/^[^#]/ {print $1}' ../build-aux/gcc-warning.spec))
+
+ gl_manywarn_set=
+ for gl_manywarn_item in \
+ -W \
+ -Wabi \
+ -Waddress \
+ -Waggressive-loop-optimizations \
+ -Wall \
+ -Wattributes \
+ -Wbad-function-cast \
+ -Wbool-compare \
+ -Wbuiltin-macro-redefined \
+ -Wcast-align \
+ -Wchar-subscripts \
+ -Wchkp \
+ -Wclobbered \
+ -Wcomment \
+ -Wcomments \
+ -Wcoverage-mismatch \
+ -Wcpp \
+ -Wdate-time \
+ -Wdeprecated \
+ -Wdeprecated-declarations \
+ -Wdesignated-init \
+ -Wdisabled-optimization \
+ -Wdiscarded-array-qualifiers \
+ -Wdiscarded-qualifiers \
+ -Wdiv-by-zero \
+ -Wdouble-promotion \
+ -Wduplicated-cond \
+ -Wempty-body \
+ -Wendif-labels \
+ -Wenum-compare \
+ -Wextra \
+ -Wformat-contains-nul \
+ -Wformat-extra-args \
+ -Wformat-nonliteral \
+ -Wformat-security \
+ -Wformat-signedness \
+ -Wformat-y2k \
+ -Wformat-zero-length \
+ -Wframe-address \
+ -Wfree-nonheap-object \
+ -Whsa \
+ -Wignored-attributes \
+ -Wignored-qualifiers \
+ -Wimplicit \
+ -Wimplicit-function-declaration \
+ -Wimplicit-int \
+ -Wincompatible-pointer-types \
+ -Winit-self \
+ -Winline \
+ -Wint-conversion \
+ -Wint-to-pointer-cast \
+ -Winvalid-memory-model \
+ -Winvalid-pch \
+ -Wjump-misses-init \
+ -Wlogical-not-parentheses \
+ -Wlogical-op \
+ -Wmain \
+ -Wmaybe-uninitialized \
+ -Wmemset-transposed-args \
+ -Wmisleading-indentation \
+ -Wmissing-braces \
+ -Wmissing-declarations \
+ -Wmissing-field-initializers \
+ -Wmissing-include-dirs \
+ -Wmissing-parameter-type \
+ -Wmissing-prototypes \
+ -Wmultichar \
+ -Wnarrowing \
+ -Wnested-externs \
+ -Wnonnull \
+ -Wnonnull-compare \
+ -Wnull-dereference \
+ -Wodr \
+ -Wold-style-declaration \
+ -Wold-style-definition \
+ -Wopenmp-simd \
+ -Woverflow \
+ -Woverlength-strings \
+ -Woverride-init \
+ -Wpacked \
+ -Wpacked-bitfield-compat \
+ -Wparentheses \
+ -Wpointer-arith \
+ -Wpointer-sign \
+ -Wpointer-to-int-cast \
+ -Wpragmas \
+ -Wreturn-local-addr \
+ -Wreturn-type \
+ -Wscalar-storage-order \
+ -Wsequence-point \
+ -Wshadow \
+ -Wshift-count-negative \
+ -Wshift-count-overflow \
+ -Wshift-negative-value \
+ -Wsizeof-array-argument \
+ -Wsizeof-pointer-memaccess \
+ -Wstack-protector \
+ -Wstrict-aliasing \
+ -Wstrict-overflow \
+ -Wstrict-prototypes \
+ -Wsuggest-attribute=const \
+ -Wsuggest-attribute=format \
+ -Wsuggest-attribute=noreturn \
+ -Wsuggest-attribute=pure \
+ -Wsuggest-final-methods \
+ -Wsuggest-final-types \
+ -Wswitch \
+ -Wswitch-bool \
+ -Wswitch-default \
+ -Wsync-nand \
+ -Wsystem-headers \
+ -Wtautological-compare \
+ -Wtrampolines \
+ -Wtrigraphs \
+ -Wtype-limits \
+ -Wuninitialized \
+ -Wunknown-pragmas \
+ -Wunsafe-loop-optimizations \
+ -Wunused \
+ -Wunused-but-set-parameter \
+ -Wunused-but-set-variable \
+ -Wunused-function \
+ -Wunused-label \
+ -Wunused-local-typedefs \
+ -Wunused-macros \
+ -Wunused-parameter \
+ -Wunused-result \
+ -Wunused-value \
+ -Wunused-variable \
+ -Wvarargs \
+ -Wvariadic-macros \
+ -Wvector-operation-performance \
+ -Wvla \
+ -Wvolatile-register-var \
+ -Wwrite-strings \
+ \
+ ; do
+ gl_manywarn_set="$gl_manywarn_set $gl_manywarn_item"
+ done
+
+ # gcc --help=warnings outputs an unusual form for these options; list
+ # them here so that the above 'comm' command doesn't report a false match.
+ gl_manywarn_set="$gl_manywarn_set -Warray-bounds=2"
+ gl_manywarn_set="$gl_manywarn_set -Wnormalized=nfc"
+ gl_manywarn_set="$gl_manywarn_set -Wshift-overflow=2"
+ gl_manywarn_set="$gl_manywarn_set -Wunused-const-variable=2"
+
+ # These are needed for older GCC versions.
+ if test -n "$GCC"; then
+ case `($CC --version) 2>/dev/null` in
+ 'gcc (GCC) '[[0-3]].* | \
+ 'gcc (GCC) '4.[[0-7]].*)
+ gl_manywarn_set="$gl_manywarn_set -fdiagnostics-show-option"
+ gl_manywarn_set="$gl_manywarn_set -funit-at-a-time"
+ ;;
+ esac
+ fi
+
+ # Disable specific options as needed.
+ if test "$gl_cv_cc_nomfi_needed" = yes; then
+ gl_manywarn_set="$gl_manywarn_set -Wno-missing-field-initializers"
+ fi
+
+ if test "$gl_cv_cc_uninitialized_supported" = no; then
+ gl_manywarn_set="$gl_manywarn_set -Wno-uninitialized"
+ fi
+
+ $1=$gl_manywarn_set
+])
--- /dev/null
+# SPICE_COMPILE_WARNINGS(DONTWARN)
+# --------------------------------------------------------
+# Enable all known GCC compiler warnings, except for those
+# we can't yet cope with
+#
+AC_DEFUN([SPICE_COMPILE_WARNINGS],[
+ dnl ******************************
+ dnl More compiler warnings
+ dnl ******************************
+
+ AC_ARG_ENABLE([werror],
+ AS_HELP_STRING([--enable-werror], [Use -Werror (if supported)]),
+ [set_werror="$enableval"],
+ [if test -d $srcdir/.git; then
+ is_git_version=true
+ set_werror=yes
+ else
+ set_werror=no
+ fi])
+
+ # List of warnings that are not relevant / wanted
+
+ dontwarn=$1
+
+ # Don't care about C++ compiler compat
+ dontwarn="$dontwarn -Wc++-compat"
+ dontwarn="$dontwarn -Wabi"
+ dontwarn="$dontwarn -Wdeprecated"
+ # Don't care about ancient C standard compat
+ dontwarn="$dontwarn -Wtraditional"
+ # Don't care about ancient C standard compat
+ dontwarn="$dontwarn -Wtraditional-conversion"
+ # Ignore warnings in /usr/include
+ dontwarn="$dontwarn -Wsystem-headers"
+ # Happy for compiler to add struct padding
+ dontwarn="$dontwarn -Wpadded"
+ # GCC very confused with -O2
+ dontwarn="$dontwarn -Wunreachable-code"
+
+
+ dontwarn="$dontwarn -Wconversion"
+ dontwarn="$dontwarn -Wsign-conversion"
+ dontwarn="$dontwarn -Wvla"
+ dontwarn="$dontwarn -Wundef"
+ dontwarn="$dontwarn -Wcast-qual"
+ dontwarn="$dontwarn -Wlong-long"
+ dontwarn="$dontwarn -Wswitch-default"
+ dontwarn="$dontwarn -Wswitch-enum"
+ dontwarn="$dontwarn -Wstrict-overflow"
+ dontwarn="$dontwarn -Wunsafe-loop-optimizations"
+ dontwarn="$dontwarn -Wformat-nonliteral"
+ dontwarn="$dontwarn -Wfloat-equal"
+ dontwarn="$dontwarn -Wdeclaration-after-statement"
+ dontwarn="$dontwarn -Wcast-qual"
+ dontwarn="$dontwarn -Wconversion"
+ dontwarn="$dontwarn -Wsign-conversion"
+ dontwarn="$dontwarn -Wpacked"
+ dontwarn="$dontwarn -Wunused-macros"
+ dontwarn="$dontwarn -Woverlength-strings"
+ dontwarn="$dontwarn -Wstack-protector"
+ dontwarn="$dontwarn -Winline"
+ dontwarn="$dontwarn -Wbad-function-cast"
+ dontwarn="$dontwarn -Wshadow"
+
+ # Get all possible GCC warnings
+ gl_MANYWARN_ALL_GCC([maybewarn])
+
+ # Remove the ones we don't want, blacklisted earlier
+ gl_MANYWARN_COMPLEMENT([wantwarn], [$maybewarn], [$dontwarn])
+
+ # Check for $CC support of each warning
+ for w in $wantwarn; do
+ gl_WARN_ADD([$w])
+ done
+
+ # GNULIB uses '-W' (aka -Wextra) which includes a bunch of stuff.
+ # Unfortunately, this means you can't simply use '-Wsign-compare'
+ # with gl_MANYWARN_COMPLEMENT
+ # So we have -W enabled, and then have to explicitly turn off...
+ gl_WARN_ADD([-Wno-sign-compare])
+ gl_WARN_ADD([-Wno-unused-parameter])
+ gl_WARN_ADD([-Wno-missing-field-initializers])
+ # We can't enable this due to horrible spice_usb_device_get_description
+ # signature
+ gl_WARN_ADD([-Wno-format-nonliteral])
+ # We use some deprecated functions to avoid #ifdef hell while maintaining
+ # compat with older gtk / glib versions
+ gl_WARN_ADD([-Wno-deprecated-declarations])
+
+
+
+ # GNULIB expects this to be part of -Wc++-compat, but we turn
+ # that one off, so we need to manually enable this again
+ gl_WARN_ADD([-Wjump-misses-init])
+
+ # GNULIB turns on -Wformat=2 which implies -Wformat-nonliteral,
+ # so we need to manually re-exclude it.
+ gl_WARN_ADD([-Wno-format-nonliteral])
+
+ # This should be < 1024 really. pixman_utils is the blackspot
+ # preventing lower usage
+ gl_WARN_ADD([-Wframe-larger-than=9216])
+
+ # Use improved glibc headers
+ AH_VERBATIM([FORTIFY_SOURCE],
+ [/* Enable compile-time and run-time bounds-checking, and some warnings. */
+ #if !defined _FORTIFY_SOURCE && defined __OPTIMIZE__ && __OPTIMIZE__
+ # define _FORTIFY_SOURCE 2
+ #endif
+ ])
+
+ # Extra special flags
+ dnl -fstack-protector stuff passes gl_WARN_ADD with gcc
+ dnl on Mingw32, but fails when actually used
+ case $host in
+ *-*-linux*)
+ dnl Fedora only uses -fstack-protector, but doesn't seem to
+ dnl be great overhead in adding -fstack-protector-all instead
+ dnl gl_WARN_ADD([-fstack-protector])
+ gl_WARN_ADD([-fstack-protector-all])
+ gl_WARN_ADD([--param=ssp-buffer-size=4])
+ ;;
+ esac
+ gl_WARN_ADD([-fexceptions])
+ gl_WARN_ADD([-fasynchronous-unwind-tables])
+ gl_WARN_ADD([-fdiagnostics-show-option])
+ gl_WARN_ADD([-funit-at-a-time])
+
+ # Need -fipa-pure-const in order to make -Wsuggest-attribute=pure
+ # fire even without -O.
+ gl_WARN_ADD([-fipa-pure-const])
+
+ # We should eventually enable this, but right now there are at
+ # least 75 functions triggering warnings.
+ gl_WARN_ADD([-Wno-suggest-attribute=pure])
+ gl_WARN_ADD([-Wno-suggest-attribute=const])
+
+ if test "$set_werror" = "yes"
+ then
+ gl_WARN_ADD([-Werror])
+ fi
+
+ WARN_LDFLAGS=$WARN_CFLAGS
+ AC_SUBST([WARN_CFLAGS])
+ AC_SUBST([WARN_LDFLAGS])
+
+ gl_WARN_ADD([-Wno-write-strings])
+ WARN_PYFLAGS=$WARN_CFLAGS
+ AC_SUBST([WARN_PYFLAGS])
+])
--- /dev/null
+# warnings.m4 serial 11
+dnl Copyright (C) 2008-2013 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Simon Josefsson
+
+# gl_AS_VAR_APPEND(VAR, VALUE)
+# ----------------------------
+# Provide the functionality of AS_VAR_APPEND if Autoconf does not have it.
+m4_ifdef([AS_VAR_APPEND],
+[m4_copy([AS_VAR_APPEND], [gl_AS_VAR_APPEND])],
+[m4_define([gl_AS_VAR_APPEND],
+[AS_VAR_SET([$1], [AS_VAR_GET([$1])$2])])])
+
+
+# gl_COMPILER_OPTION_IF(OPTION, [IF-SUPPORTED], [IF-NOT-SUPPORTED],
+# [PROGRAM = AC_LANG_PROGRAM()])
+# -----------------------------------------------------------------
+# Check if the compiler supports OPTION when compiling PROGRAM.
+#
+# FIXME: gl_Warn must be used unquoted until we can assume Autoconf
+# 2.64 or newer.
+AC_DEFUN([gl_COMPILER_OPTION_IF],
+[AS_VAR_PUSHDEF([gl_Warn], [gl_cv_warn_[]_AC_LANG_ABBREV[]_$1])dnl
+AS_VAR_PUSHDEF([gl_Flags], [_AC_LANG_PREFIX[]FLAGS])dnl
+AS_LITERAL_IF([$1],
+ [m4_pushdef([gl_Positive], m4_bpatsubst([$1], [^-Wno-], [-W]))],
+ [gl_positive="$1"
+case $gl_positive in
+ -Wno-*) gl_positive=-W`expr "X$gl_positive" : 'X-Wno-\(.*\)'` ;;
+esac
+m4_pushdef([gl_Positive], [$gl_positive])])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler handles $1], m4_defn([gl_Warn]), [
+ gl_save_compiler_FLAGS="$gl_Flags"
+ gl_AS_VAR_APPEND(m4_defn([gl_Flags]),
+ [" $gl_unknown_warnings_are_errors ]m4_defn([gl_Positive])["])
+ AC_LINK_IFELSE([m4_default([$4], [AC_LANG_PROGRAM([])])],
+ [AS_VAR_SET(gl_Warn, [yes])],
+ [AS_VAR_SET(gl_Warn, [no])])
+ gl_Flags="$gl_save_compiler_FLAGS"
+])
+AS_VAR_IF(gl_Warn, [yes], [$2], [$3])
+m4_popdef([gl_Positive])dnl
+AS_VAR_POPDEF([gl_Flags])dnl
+AS_VAR_POPDEF([gl_Warn])dnl
+])
+
+# gl_UNKNOWN_WARNINGS_ARE_ERRORS
+# ------------------------------
+# Clang doesn't complain about unknown warning options unless one also
+# specifies -Wunknown-warning-option -Werror. Detect this.
+AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS],
+[gl_COMPILER_OPTION_IF([-Werror -Wunknown-warning-option],
+ [gl_unknown_warnings_are_errors='-Wunknown-warning-option -Werror'],
+ [gl_unknown_warnings_are_errors=])])
+
+# gl_WARN_ADD(OPTION, [VARIABLE = WARN_CFLAGS],
+# [PROGRAM = AC_LANG_PROGRAM()])
+# ---------------------------------------------
+# Adds parameter to WARN_CFLAGS if the compiler supports it when
+# compiling PROGRAM. For example, gl_WARN_ADD([-Wparentheses]).
+#
+# If VARIABLE is a variable name, AC_SUBST it.
+AC_DEFUN([gl_WARN_ADD],
+[AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS])
+gl_COMPILER_OPTION_IF([$1],
+ [gl_AS_VAR_APPEND(m4_if([$2], [], [[WARN_CFLAGS]], [[$2]]), [" $1"])],
+ [],
+ [$3])
+m4_ifval([$2],
+ [AS_LITERAL_IF([$2], [AC_SUBST([$2])])],
+ [AC_SUBST([WARN_CFLAGS])])dnl
+])
+
+# Local Variables:
+# mode: autoconf
+# End:
--- /dev/null
+NULL =
+
+dist_man_MANS = \
+ spice-client.1 \
+ $(NULL)
+
+EXTRA_DIST = \
+ spice-client.pod \
+ $(NULL)
+
+MAINTAINERCLEANFILES = $(dist_man_MANS)
+
+%.1: %.pod
+ $(AM_V_GEN)pod2man -c "Spice-GTK Documentation" $< > $@
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = man
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/ld-version.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/manywarnings.m4 \
+ $(top_srcdir)/m4/spice-compile-warnings.m4 \
+ $(top_srcdir)/m4/warnings.m4 \
+ $(top_srcdir)/spice-common/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man1dir = $(mandir)/man1
+am__installdirs = "$(DESTDIR)$(man1dir)"
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACL_HELPER_DIR = @ACL_HELPER_DIR@
+ACL_LIBS = @ACL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMMON_CFLAGS = @COMMON_CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GOBJECT2_CFLAGS = @GOBJECT2_CFLAGS@
+GOBJECT2_LIBS = @GOBJECT2_LIBS@
+GREP = @GREP@
+GSTAUDIO_CFLAGS = @GSTAUDIO_CFLAGS@
+GSTAUDIO_LIBS = @GSTAUDIO_LIBS@
+GSTVIDEO_CFLAGS = @GSTVIDEO_CFLAGS@
+GSTVIDEO_LIBS = @GSTVIDEO_LIBS@
+GST_INSPECT_1_0 = @GST_INSPECT_1_0@
+GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
+GTHREAD_LIBS = @GTHREAD_LIBS@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_REQUIRED = @GTK_REQUIRED@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+JPEG_LIBS = @JPEG_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUSB_HOTPLUG_CFLAGS = @LIBUSB_HOTPLUG_CFLAGS@
+LIBUSB_HOTPLUG_LIBS = @LIBUSB_HOTPLUG_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PHODAV_CFLAGS = @PHODAV_CFLAGS@
+PHODAV_LIBS = @PHODAV_LIBS@
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PNP_IDS = @PNP_IDS@
+POFILES = @POFILES@
+POLICYDIR = @POLICYDIR@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PULSE_CFLAGS = @PULSE_CFLAGS@
+PULSE_LIBS = @PULSE_LIBS@
+PYTHON = @PYTHON@
+RANLIB = @RANLIB@
+SASL_CFLAGS = @SASL_CFLAGS@
+SASL_LIBS = @SASL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_CFLAGS = @SPICE_CFLAGS@
+SPICE_GLIB_CFLAGS = @SPICE_GLIB_CFLAGS@
+SPICE_GLIB_REQUIRES = @SPICE_GLIB_REQUIRES@
+SPICE_GTK_CFLAGS = @SPICE_GTK_CFLAGS@
+SPICE_GTK_LOCALEDIR = @SPICE_GTK_LOCALEDIR@
+SPICE_GTK_MAJOR_VERSION = @SPICE_GTK_MAJOR_VERSION@
+SPICE_GTK_MICRO_VERSION = @SPICE_GTK_MICRO_VERSION@
+SPICE_GTK_MINOR_VERSION = @SPICE_GTK_MINOR_VERSION@
+SPICE_GTK_REQUIRES = @SPICE_GTK_REQUIRES@
+SPICE_PROTOCOL_CFLAGS = @SPICE_PROTOCOL_CFLAGS@
+SPICE_PROTOCOL_LIBS = @SPICE_PROTOCOL_LIBS@
+SSL_CFLAGS = @SSL_CFLAGS@
+SSL_LIBS = @SSL_LIBS@
+STOW = @STOW@
+STRIP = @STRIP@
+USBREDIR_CFLAGS = @USBREDIR_CFLAGS@
+USBREDIR_LIBS = @USBREDIR_LIBS@
+USB_IDS = @USB_IDS@
+USE_NLS = @USE_NLS@
+VALAC = @VALAC@
+VAPIDIR = @VAPIDIR@
+VAPIGEN = @VAPIGEN@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_LDFLAGS = @WARN_LDFLAGS@
+WARN_PYFLAGS = @WARN_PYFLAGS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+XGETTEXT = @XGETTEXT@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+dist_man_MANS = \
+ spice-client.1 \
+ $(NULL)
+
+EXTRA_DIST = \
+ spice-client.pod \
+ $(NULL)
+
+MAINTAINERCLEANFILES = $(dist_man_MANS)
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign man/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man1: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man1dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.1[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(MANS)
+installdirs:
+ for dir in "$(DESTDIR)$(man1dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man1
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man
+
+uninstall-man: uninstall-man1
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-man1 install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man1
+
+.PRECIOUS: Makefile
+
+
+%.1: %.pod
+ $(AM_V_GEN)pod2man -c "Spice-GTK Documentation" $< > $@
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+. ds C`
+. ds C'
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is >0, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.if !\nF .nr F 0
+.if \nF>0 \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "SPICE-CLIENT 1"
+.TH SPICE-CLIENT 1 "2015-11-10" "perl v5.22.2" "Spice-GTK Documentation"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+Spice\-GTK \- a client\-side library to access remote SPICE displays
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+Spice-GTK is a library allowing access to remote displays over the \s-1SPICE\s0
+protocol. At the moment It's mainly used to access remote virtual machines.
+.PP
+The Spice-GTK library provides a set of command line options which
+can be used to tweak some SPICE-specific option.
+.SH "URI"
+.IX Header "URI"
+The most basic \s-1SPICE URI\s0 which can be used is in the form
+ spice://hostname.example.com:5900
+.PP
+This will try to initiate a \s-1SPICE\s0 connection to hostname.example.com
+to port 5900. This connection will be unencrypted. This \s-1URI\s0 is
+equivalent to
+ spice://hostname.example.com?port=5900
+.PP
+In order to start a \s-1TLS\s0 connection, one would use
+ spice://hostname.example.com?tls\-port=5900
+.PP
+Other valid \s-1URI\s0 parameters are 'username' and 'password'. Be careful that
+passing a password through a \s-1SPICE URI\s0 might cause the password to be
+visible by any local user through 'ps'.
+.PP
+Several parameters can be specified at once if they are separated
+by & or ;
+ spice://hostname.example.com?port=5900;tls\-port=5901
+.PP
+When using 'tls\-port', it's recommended to not specify any non-TLS port.
+If you give both 'port' and 'tls\-port', make sure you use the
+\&\-\-spice\-secure\-channels options to indicate which channels must be secure.
+Otherwise, Spice-GTK first attempts a connection to the non-TLS port, and
+then try to use the \s-1TLS\s0 port. This means a man-in-the-middle could force
+the whole \s-1SPICE\s0 session to go in clear text regardless of the \s-1TLS\s0 settings
+of the \s-1SPICE\s0 server.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+The following options are accepted when running a \s-1SPICE\s0 client which
+makes use of the default Spice-GTK options:
+.IP "\-\-spice\-secure\-channels=<main,display,inputs,...,all>" 4
+.IX Item "--spice-secure-channels=<main,display,inputs,...,all>"
+Force the specified channels to be secured
+.Sp
+This instructs the \s-1SPICE\s0 client that it must use a \s-1TLS\s0 connection for these
+channels. If the server only offers non-TLS connections for these channels,
+the client will not use these. If the special value \*(L"all\*(R" is used, this
+indicates that all \s-1SPICE\s0 channels must be encrypted.
+.Sp
+The current \s-1SPICE\s0 channels are: main, display, inputs, cursor, playback,
+record, smartcard, usbredir.
+.IP "\-\-spice\-disable\-effects=<wallpaper,font\-smooth,animation,all>" 4
+.IX Item "--spice-disable-effects=<wallpaper,font-smooth,animation,all>"
+Disable guest display effects
+.Sp
+This tells the \s-1SPICE\s0 client that it should attempt to disable some guest
+features in order to lower bandwidth usage. This requires guest support,
+usually through a \s-1SPICE\s0 agent. This is currently only supported on Windows
+guests.
+.Sp
+\&\*(L"wallpaper\*(R" will disable the guest wallpaper, \*(L"font-smooth\*(R" will disable
+font antialiasing, \*(L"animation\*(R" will try to disable some of the desktop
+environment animations. \*(L"all\*(R" will attempt to disable everything which
+can be disabled.
+.IP "\-\-spice\-color\-depth=<16,32>" 4
+.IX Item "--spice-color-depth=<16,32>"
+Guest display color depth
+.Sp
+This tells the \s-1SPICE\s0 client that it should attempt to force the guest \s-1OS\s0
+color depth. A lower color depth should lower bandwith usage. This requires
+guest support, usually through a \s-1SPICE\s0 agent. This is currently only
+supported on Windows guests.
+.IP "\-\-spice\-ca\-file=<file>" 4
+.IX Item "--spice-ca-file=<file>"
+Truststore file for secure connections
+.Sp
+This option is used to specify a .crt file containing the \s-1CA\s0 certificate with which
+the \s-1SPICE\s0 server \s-1TLS\s0 certificates are signed. This is useful when using self-signed
+\&\s-1TLS\s0 certificates rather than certificates signed by an official \s-1CA.\s0
+.IP "\-\-spice\-host\-subject=<host\-subject>" 4
+.IX Item "--spice-host-subject=<host-subject>"
+Subject of the host certificate (field=value pairs separated by commas)
+.Sp
+When using self-signed certificates, or when the guest is migrated between
+different hosts, the subject/altSubject of the \s-1TLS\s0 certificate the \s-1SPICE\s0
+server will provide will not necessarily match the hostname we are connecting to.
+This option makes it possible to override the expected subject of the \s-1TLS\s0 certificate.
+.Sp
+The subject must correspond to the \*(L"Subject:\*(R" line returned by:
+ openssl x509 \-noout \-text \-in server\-cert.pem
+.IP "\-\-spice\-debug" 4
+.IX Item "--spice-debug"
+Enable Spice-GTK debugging. This can also be toggled on with the
+\&\s-1SPICE_DEBUG\s0 environment variable, or using G_MESSAGES_DEBUG=all
+.IP "\-\-spice\-disable\-audio" 4
+.IX Item "--spice-disable-audio"
+Disable audio support
+.IP "\-\-spice\-disable\-usbredir" 4
+.IX Item "--spice-disable-usbredir"
+Disable \s-1USB\s0 redirection support
+.IP "\-\-spice\-usbredir\-auto\-redirect\-filter=<filter\-string>" 4
+.IX Item "--spice-usbredir-auto-redirect-filter=<filter-string>"
+Filter selecting \s-1USB\s0 devices to be auto-redirected when plugged in
+.Sp
+This filter specifies which \s-1USB\s0 devices should be automatically redirected
+when they are plugged in during the lifetime of a \s-1SPICE\s0 session.
+.Sp
+A rule has the form of:
+\&\f(CW\*(C`class,vendor,product,version,allow\*(C'\fR
+.Sp
+\&\-1 can be used instead of class, vendor, product or version in order to accept
+any value. Several rules can be concatenated with '|':
+\&\f(CW\*(C`rule1|rule2|rule3\*(C'\fR
+.IP "\-\-spice\-usbredir\-redirect\-on\-connect=<filter\-string>" 4
+.IX Item "--spice-usbredir-redirect-on-connect=<filter-string>"
+Filter selecting \s-1USB\s0 devices to redirect on connect
+.Sp
+This filter specifies which \s-1USB\s0 devices should be automatically redirected
+when a \s-1SPICE\s0 connection to a remote display has been established.
+.IP "\-\-spice\-gtk\-version" 4
+.IX Item "--spice-gtk-version"
+Display Spice-GTK version information
+.IP "\-\-spice\-smartcard" 4
+.IX Item "--spice-smartcard"
+Enable smartcard support
+.IP "\-\-spice\-smartcard\-db=<certificate\-db>" 4
+.IX Item "--spice-smartcard-db=<certificate-db>"
+Path to the local certificate database to use for software smartcard certificates
+.Sp
+This option is only useful for testing purpose. Instead of having a hardware
+smartcard reader, and a physical smartcard, you can specify a file containing 3
+certificates which will be used to emulate a smartcard in software. See
+\&\f(CW\*(C`http://www.spice\-space.org/page/SmartcardUsage#Using_a_software_smartcard\*(C'\fR
+for more details about how to generate these certificates.
+.IP "\-\-spice\-smartcard\-certificates=<certificates>" 4
+.IX Item "--spice-smartcard-certificates=<certificates>"
+Certificates to use for software smartcards (field=values separated by commas)
+.Sp
+This option is only useful for testing purpose. This allows to specify which
+certificates from the certificate database specified with \-\-spice\-smartcard\-db
+should be used for smartcard emulation.
+.IP "\-\-spice\-cache\-size=<bytes>" 4
+.IX Item "--spice-cache-size=<bytes>"
+Image cache size
+.Sp
+This option should only be used for testing/debugging.
+.IP "\-\-spice\-glz\-window\-size=<bytes>" 4
+.IX Item "--spice-glz-window-size=<bytes>"
+Glz compression history size
+.Sp
+This option should only be used for testing/debugging.
+.SH "BUGS"
+.IX Header "BUGS"
+Report bugs to the mailing list \f(CW\*(C`http://lists.freedesktop.org/mailman/listinfo/spice\-devel\*(C'\fR
+.SH "COPYRIGHT"
+.IX Header "COPYRIGHT"
+Copyright (C) 2011, 2014 Red Hat, Inc., and various contributors.
+This is free software. You may redistribute copies of it under the terms of
+the \s-1GNU\s0 Lesser General Public License
+\&\f(CW\*(C`https://www.gnu.org/licenses/old\-licenses/lgpl\-2.1.html\*(C'\fR.
+There is \s-1NO WARRANTY,\s0 to the extent permitted by law.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\f(CW\*(C`virt\-viewer(1)\*(C'\fR, the project website \f(CW\*(C`http://spice\-space.org\*(C'\fR
--- /dev/null
+=head1 NAME
+
+Spice-GTK - a client-side library to access remote SPICE displays
+
+=head1 DESCRIPTION
+
+Spice-GTK is a library allowing access to remote displays over the SPICE
+protocol. At the moment It's mainly used to access remote virtual machines.
+
+The Spice-GTK library provides a set of command line options which
+can be used to tweak some SPICE-specific option.
+
+=head1 URI
+
+The most basic SPICE URI which can be used is in the form
+ spice://hostname.example.com:5900
+
+This will try to initiate a SPICE connection to hostname.example.com
+to port 5900. This connection will be unencrypted. This URI is
+equivalent to
+ spice://hostname.example.com?port=5900
+
+In order to start a TLS connection, one would use
+ spice://hostname.example.com?tls-port=5900
+
+Other valid URI parameters are 'username' and 'password'. Be careful that
+passing a password through a SPICE URI might cause the password to be
+visible by any local user through 'ps'.
+
+Several parameters can be specified at once if they are separated
+by & or ;
+ spice://hostname.example.com?port=5900;tls-port=5901
+
+When using 'tls-port', it's recommended to not specify any non-TLS port.
+If you give both 'port' and 'tls-port', make sure you use the
+--spice-secure-channels options to indicate which channels must be secure.
+Otherwise, Spice-GTK first attempts a connection to the non-TLS port, and
+then try to use the TLS port. This means a man-in-the-middle could force
+the whole SPICE session to go in clear text regardless of the TLS settings
+of the SPICE server.
+
+=head1 OPTIONS
+
+The following options are accepted when running a SPICE client which
+makes use of the default Spice-GTK options:
+
+=over 4
+
+=item --spice-secure-channels=<main,display,inputs,...,all>
+
+Force the specified channels to be secured
+
+This instructs the SPICE client that it must use a TLS connection for these
+channels. If the server only offers non-TLS connections for these channels,
+the client will not use these. If the special value "all" is used, this
+indicates that all SPICE channels must be encrypted.
+
+The current SPICE channels are: main, display, inputs, cursor, playback,
+record, smartcard, usbredir.
+
+=item --spice-disable-effects=<wallpaper,font-smooth,animation,all>
+
+Disable guest display effects
+
+This tells the SPICE client that it should attempt to disable some guest
+features in order to lower bandwidth usage. This requires guest support,
+usually through a SPICE agent. This is currently only supported on Windows
+guests.
+
+"wallpaper" will disable the guest wallpaper, "font-smooth" will disable
+font antialiasing, "animation" will try to disable some of the desktop
+environment animations. "all" will attempt to disable everything which
+can be disabled.
+
+=item --spice-color-depth=<16,32>
+
+Guest display color depth
+
+This tells the SPICE client that it should attempt to force the guest OS
+color depth. A lower color depth should lower bandwith usage. This requires
+guest support, usually through a SPICE agent. This is currently only
+supported on Windows guests.
+
+=item --spice-ca-file=<file>
+
+Truststore file for secure connections
+
+This option is used to specify a .crt file containing the CA certificate with which
+the SPICE server TLS certificates are signed. This is useful when using self-signed
+TLS certificates rather than certificates signed by an official CA.
+
+
+=item --spice-host-subject=<host-subject>
+
+Subject of the host certificate (field=value pairs separated by commas)
+
+When using self-signed certificates, or when the guest is migrated between
+different hosts, the subject/altSubject of the TLS certificate the SPICE
+server will provide will not necessarily match the hostname we are connecting to.
+This option makes it possible to override the expected subject of the TLS certificate.
+
+The subject must correspond to the "Subject:" line returned by:
+ openssl x509 -noout -text -in server-cert.pem
+
+=item --spice-debug
+
+Enable Spice-GTK debugging. This can also be toggled on with the
+SPICE_DEBUG environment variable, or using G_MESSAGES_DEBUG=all
+
+=item --spice-disable-audio
+
+Disable audio support
+
+=item --spice-disable-usbredir
+
+Disable USB redirection support
+
+=item --spice-usbredir-auto-redirect-filter=<filter-string>
+
+Filter selecting USB devices to be auto-redirected when plugged in
+
+This filter specifies which USB devices should be automatically redirected
+when they are plugged in during the lifetime of a SPICE session.
+
+A rule has the form of:
+C<class,vendor,product,version,allow>
+
+-1 can be used instead of class, vendor, product or version in order to accept
+any value. Several rules can be concatenated with '|':
+C<rule1|rule2|rule3>
+
+=item --spice-usbredir-redirect-on-connect=<filter-string>
+
+Filter selecting USB devices to redirect on connect
+
+This filter specifies which USB devices should be automatically redirected
+when a SPICE connection to a remote display has been established.
+
+=item --spice-gtk-version
+
+Display Spice-GTK version information
+
+=item --spice-smartcard
+
+Enable smartcard support
+
+=item --spice-smartcard-db=<certificate-db>
+
+Path to the local certificate database to use for software smartcard certificates
+
+This option is only useful for testing purpose. Instead of having a hardware
+smartcard reader, and a physical smartcard, you can specify a file containing 3
+certificates which will be used to emulate a smartcard in software. See
+C<http://www.spice-space.org/page/SmartcardUsage#Using_a_software_smartcard>
+for more details about how to generate these certificates.
+
+=item --spice-smartcard-certificates=<certificates>
+
+Certificates to use for software smartcards (field=values separated by commas)
+
+This option is only useful for testing purpose. This allows to specify which
+certificates from the certificate database specified with --spice-smartcard-db
+should be used for smartcard emulation.
+
+=item --spice-cache-size=<bytes>
+
+Image cache size
+
+This option should only be used for testing/debugging.
+
+=item --spice-glz-window-size=<bytes>
+
+Glz compression history size
+
+This option should only be used for testing/debugging.
+
+=back
+
+=head1 BUGS
+
+Report bugs to the mailing list C<http://lists.freedesktop.org/mailman/listinfo/spice-devel>
+
+=head1 COPYRIGHT
+
+Copyright (C) 2011, 2014 Red Hat, Inc., and various contributors.
+This is free software. You may redistribute copies of it under the terms of
+the GNU Lesser General Public License
+C<https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html>.
+There is NO WARRANTY, to the extent permitted by law.
+
+=head1 SEE ALSO
+
+C<virt-viewer(1)>, the project website C<http://spice-space.org>
+
+=cut
--- /dev/null
+2010-11-25 Marc-Andre Lureau <marcandre.lureau@redhat.com>
+
+ * Added initial french translation for spicy and snappy.
+
+2010-11-24 Marc-Andre Lureau <marcandre.lureau@redhat.com>
+
+ * Initial translation support.
+
--- /dev/null
+# keep this file sorted alphabetically, one language code per line
+fr
+it
--- /dev/null
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+# Copyright (C) 2004-2008 Rodney Dawes <dobey.pwns@gmail.com>
+#
+# This file may be copied and used freely without restrictions. It may
+# be used in projects which are not available under a GNU Public License,
+# but which still want to provide support for the GNU gettext functionality.
+#
+# - Modified by Owen Taylor <otaylor@redhat.com> to use GETTEXT_PACKAGE
+# instead of PACKAGE and to look for po2tbl in ./ not in intl/
+#
+# - Modified by jacob berkman <jacob@ximian.com> to install
+# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize
+#
+# - Modified by Rodney Dawes <dobey.pwns@gmail.com> for use with intltool
+#
+# We have the following line for use by intltoolize:
+# INTLTOOL_MAKEFILE
+
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = @top_builddir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = @datadir@
+datarootdir = @datarootdir@
+libdir = @libdir@
+localedir = @localedir@
+subdir = po
+install_sh = @install_sh@
+# Automake >= 1.8 provides @mkdir_p@.
+# Until it can be supposed, use the safe fallback:
+mkdir_p = $(install_sh) -d
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+
+GMSGFMT = @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = @XGETTEXT@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+MSGMERGE = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist
+GENPOT = INTLTOOL_EXTRACT="$(INTLTOOL_EXTRACT)" XGETTEXT="$(XGETTEXT)" srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot
+
+ALL_LINGUAS = @ALL_LINGUAS@
+
+PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; else echo "$(ALL_LINGUAS)"; fi)
+
+USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep \^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep \^$$lang$$`"; then printf "$$lang "; fi; done; fi)
+
+USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)" -o -n "$(LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done)
+
+POFILES=$(shell LINGUAS="$(PO_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done)
+
+DISTFILES = Makefile.in.in POTFILES.in $(POFILES)
+EXTRA_DISTFILES = ChangeLog POTFILES.skip Makevars LINGUAS
+
+POTFILES = \
+# This comment gets stripped out
+
+CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.gmo "; done)
+
+.SUFFIXES:
+.SUFFIXES: .po .pox .gmo .mo .msg .cat
+
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+INTLTOOL_V_MSGFMT = $(INTLTOOL__v_MSGFMT_$(V))
+INTLTOOL__v_MSGFMT_= $(INTLTOOL__v_MSGFMT_$(AM_DEFAULT_VERBOSITY))
+INTLTOOL__v_MSGFMT_0 = @echo " MSGFMT" $@;
+
+.po.pox:
+ $(MAKE) $(GETTEXT_PACKAGE).pot
+ $(MSGMERGE) $* $(GETTEXT_PACKAGE).pot -o $*.pox
+
+.po.mo:
+ $(INTLTOOL_V_MSGFMT)$(MSGFMT) -o $@ $<
+
+.po.gmo:
+ $(INTLTOOL_V_MSGFMT)file=`echo $* | sed 's,.*/,,'`.gmo \
+ && rm -f $$file && $(GMSGFMT) -o $$file $<
+
+.po.cat:
+ sed -f ../intl/po2msg.sed < $< > $*.msg \
+ && rm -f $@ && gencat $@ $*.msg
+
+
+all: all-@USE_NLS@
+
+all-yes: $(CATALOGS)
+all-no:
+
+$(GETTEXT_PACKAGE).pot: $(POTFILES)
+ $(GENPOT)
+
+install: install-data
+install-data: install-data-@USE_NLS@
+install-data-no: all
+install-data-yes: all
+ linguas="$(USE_LINGUAS)"; \
+ for lang in $$linguas; do \
+ dir=$(DESTDIR)$(localedir)/$$lang/LC_MESSAGES; \
+ $(mkdir_p) $$dir; \
+ if test -r $$lang.gmo; then \
+ $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
+ echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
+ echo "installing $(srcdir)/$$lang.gmo as" \
+ "$$dir/$(GETTEXT_PACKAGE).mo"; \
+ fi; \
+ if test -r $$lang.gmo.m; then \
+ $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \
+ echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \
+ else \
+ if test -r $(srcdir)/$$lang.gmo.m ; then \
+ $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \
+ $$dir/$(GETTEXT_PACKAGE).mo.m; \
+ echo "installing $(srcdir)/$$lang.gmo.m as" \
+ "$$dir/$(GETTEXT_PACKAGE).mo.m"; \
+ else \
+ true; \
+ fi; \
+ fi; \
+ done
+
+# Empty stubs to satisfy archaic automake needs
+dvi info ctags tags CTAGS TAGS ID:
+
+# Define this as empty until I found a useful application.
+install-exec installcheck:
+
+uninstall:
+ linguas="$(USE_LINGUAS)"; \
+ for lang in $$linguas; do \
+ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \
+ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \
+ done
+
+check: all $(GETTEXT_PACKAGE).pot
+ rm -f missing notexist
+ srcdir=$(srcdir) $(INTLTOOL_UPDATE) -m
+ if [ -r missing -o -r notexist ]; then \
+ exit 1; \
+ fi
+
+mostlyclean:
+ rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp
+ rm -f .intltool-merge-cache
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES stamp-it
+ rm -f *.mo *.msg *.cat *.cat.m *.gmo
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f Makefile.in.in
+
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ extra_dists="$(EXTRA_DISTFILES)"; \
+ for file in $$extra_dists; do \
+ test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \
+ done; \
+ for file in $$dists; do \
+ test -f $$file || file="$(srcdir)/$$file"; \
+ ln $$file $(distdir) 2> /dev/null \
+ || cp -p $$file $(distdir); \
+ done
+
+update-po: Makefile
+ $(MAKE) $(GETTEXT_PACKAGE).pot
+ tmpdir=`pwd`; \
+ linguas="$(USE_LINGUAS)"; \
+ for lang in $$linguas; do \
+ echo "$$lang:"; \
+ result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \
+ if $$result; then \
+ if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
+ rm -f $$tmpdir/$$lang.new.po; \
+ else \
+ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
+ :; \
+ else \
+ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
+ rm -f $$tmpdir/$$lang.new.po; \
+ exit 1; \
+ fi; \
+ fi; \
+ else \
+ echo "msgmerge for $$lang.gmo failed!"; \
+ rm -f $$tmpdir/$$lang.new.po; \
+ fi; \
+ done
+
+Makefile POTFILES: stamp-it
+ @if test ! -f $@; then \
+ rm -f stamp-it; \
+ $(MAKE) stamp-it; \
+ fi
+
+stamp-it: Makefile.in.in $(top_builddir)/config.status POTFILES.in
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \
+ $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+src/channel-main.c
+src/channel-usbredir.c
+src/desktop-integration.c
+src/spice-channel.c
+src/spice-cmdline.c
+src/spice-option.c
+src/usb-device-manager.c
+src/usb-device-widget.c
+src/usbutil.c
--- /dev/null
+spice-common/python_modules/spice_parser.py
+spice-common/spice_codegen.py
--- /dev/null
+# French translation for spice.
+# Copyright (C) 2010 Listed translators
+# This file is distributed under the same license as the gtk-vnc package.
+#
+# Marc-André Lureau <marcandre.lureau@redhat.com>, 2010
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: spice master fr\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-11-25 03:25+0100\n"
+"PO-Revision-Date: 2010-11-25 03:43+0100\n"
+"Last-Translator: Marc-André Lureau <marcandre.lureau@redhat.com>\n"
+"Language-Team: GNOME French Team <gnomefr@traduc.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: ../gtk/spicy.c:129
+msgid "Hostname"
+msgstr "Nom de l'hôte"
+
+#: ../gtk/spicy.c:130
+msgid "Port"
+msgstr "Port"
+
+#: ../gtk/spicy.c:131
+msgid "TLS Port"
+msgstr "Port TLS"
+
+#. Create the widgets
+#: ../gtk/spicy.c:140
+msgid "Connect"
+msgstr "Connexion"
+
+#: ../gtk/spicy.c:196
+#, c-format
+msgid "Use Shift+F12 to ungrab mouse."
+msgstr "Utiliser Shift+F12 pour désaisir la souris."
+
+#: ../gtk/spicy.c:198
+#, c-format
+msgid "mouse: %s, agent: %s"
+msgstr "souris: %s, agent: %s"
+
+#: ../gtk/spicy.c:257 ../gtk/spicy.c:683
+msgid "yes"
+msgstr "oui"
+
+#: ../gtk/spicy.c:257 ../gtk/spicy.c:683
+msgid "no"
+msgstr "non"
+
+#: ../gtk/spicy.c:265
+msgid ""
+"gtk client app for the\n"
+"spice remote desktop protocol"
+msgstr ""
+"Application Gtk de connexion\n"
+"au serveur de bureau spice"
+
+#: ../gtk/spicy.c:360
+msgid "_Connect ..."
+msgstr "_Ouvrir une session..."
+
+#: ../gtk/spicy.c:366
+msgid "_Close"
+msgstr "_Quitter"
+
+#: ../gtk/spicy.c:374
+msgid "_Copy to guest"
+msgstr "_Copier dans l'invité"
+
+#: ../gtk/spicy.c:380
+msgid "_Paste from guest"
+msgstr "Coller dans l'invité"
+
+#: ../gtk/spicy.c:388
+msgid "_Fullscreen"
+msgstr "_Plein écran"
+
+#: ../gtk/spicy.c:395
+msgid "_Ungrab mouse"
+msgstr "_Désaisir la souris"
+
+#: ../gtk/spicy.c:403
+msgid "_About ..."
+msgstr "_À propos"
+
+#: ../gtk/spicy.c:411
+msgid "Grab keyboard when active and focused"
+msgstr "Saisir le clavier après focus"
+
+#: ../gtk/spicy.c:415
+msgid "Grab mouse in server mode (no tablet/vdagent)"
+msgstr "Saisir la souris en mode serveur (pas d'agent)"
+
+#: ../gtk/spicy.c:419
+msgid "Resize guest to match window size"
+msgstr "Redimensionner l'invité à la taille de fenêtre"
+
+#: ../gtk/spicy.c:423
+msgid "Automagic clipboard sharing between host and guest"
+msgstr "Partage de presse-papiers automatique"
+
+#: ../gtk/spicy.c:485
+#, c-format
+msgid "spice display %d"
+msgstr "écran spice %d"
+
+#: ../gtk/spicy.c:542
+msgid "?"
+msgstr "?"
+
+#. FIXME i18
+#: ../gtk/spicy.c:639
+msgid "Authentication"
+msgstr "Authentification"
+
+#: ../gtk/spicy.c:640
+msgid "Please enter the spice server password"
+msgstr "Entrez le mot de passe du serveur spice"
+
+#: ../gtk/spicy.c:694
+msgid "SCROLL"
+msgstr "DÉFIL"
+
+#: ../gtk/spicy.c:696
+msgid "CAPS"
+msgstr "VERR.MAJ"
+
+#: ../gtk/spicy.c:698
+msgid "NUM"
+msgstr "VERR.NUM"
+
+#: ../gtk/spicy.c:831
+msgid "open in full screen mode"
+msgstr "Ouvrir en plein-écran"
+
+#: ../gtk/spicy.c:849
+msgid "- spice client application"
+msgstr "- application client spice"
+
+#: ../gtk/spicy.c:854 ../gtk/snappy.c:144
+#, c-format
+msgid "option parsing failed: %s\n"
+msgstr "échec d'analyse des options: %s\n"
+
+#: ../gtk/snappy.c:60
+#, c-format
+msgid "snappy: can't open %s: %s\n"
+msgstr "snappy: impossible d'ouvrir %s: %s\n"
+
+#: ../gtk/snappy.c:88
+#, c-format
+msgid "unsupported spice surface format %d\n"
+msgstr "format de surface spice non supporté %d\n"
+
+#: ../gtk/snappy.c:93
+#, c-format
+msgid "wrote screen shot to %s\n"
+msgstr "capture d'écran sauvée dans %s\n"
+
+#: ../gtk/snappy.c:123
+msgid "output file name (*.ppm)"
+msgstr "nom de fichier d'enregistrement (*.ppm)"
+
+#: ../gtk/snappy.c:124
+msgid "<filename>"
+msgstr "<nom de fichier>"
+
+#. parse opts
+#: ../gtk/snappy.c:140
+msgid " - write screen shots in ppm format"
+msgstr " - sauve des capture d'écran au format ppm"
+
+#: ../gtk/snappy.c:157
+#, c-format
+msgid "spice_session_connect failed\n"
+msgstr "spice_session_connect a échoué\n"
+
+#: ../gtk/spice-cmdline.c:39
+msgid "spice server uri"
+msgstr "uri du serveur spice"
+
+#: ../gtk/spice-cmdline.c:40
+msgid "<uri>"
+msgstr "<uri>"
+
+#: ../gtk/spice-cmdline.c:46
+msgid "spice server address"
+msgstr "adresse du serveur spice"
+
+#: ../gtk/spice-cmdline.c:47
+msgid "<host>"
+msgstr "<hôte>"
+
+#: ../gtk/spice-cmdline.c:53
+msgid "spice server port"
+msgstr "port du serveur spice"
+
+#: ../gtk/spice-cmdline.c:54 ../gtk/spice-cmdline.c:61
+msgid "<port>"
+msgstr "<port>"
+
+#: ../gtk/spice-cmdline.c:60
+msgid "spice server secure port"
+msgstr "port sécurisé du serveur spice"
+
+#: ../gtk/spice-cmdline.c:66
+msgid "truststore file for secure connections"
+msgstr "fichier truststore pour les connexions sécurisées"
+
+#: ../gtk/spice-cmdline.c:67
+#, fuzzy
+msgid "<file>"
+msgstr "<nom de fichier>"
+
+#: ../gtk/spice-cmdline.c:73
+msgid "server password"
+msgstr "mot de passe du serveur"
+
+#: ../gtk/spice-cmdline.c:74
+msgid "<password>"
+msgstr "<mot de passe>"
+
+#: ../gtk/spice-cmdline.c:86
+msgid "Spice Options:"
+msgstr "Options Spice:"
+
+#: ../gtk/spice-cmdline.c:87
+msgid "Show spice Options"
+msgstr "Affiche les options de spice"
--- /dev/null
+# Italian translation for spice.
+# Copyright (C) 2016 RedHat
+# This file is distributed under the same license as the spice-gtk package.
+#
+# Frediano Ziglio <fziglio@redhat.com>, 2016.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: spice master it\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2016-08-17 08:38+0100\n"
+"PO-Revision-Date: 2016-08-17 08:57+0100\n"
+"Last-Translator: Frediano Ziglio <fziglio@redhat.com>\n"
+"Language-Team: \n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.8\n"
+
+#: ../src/channel-usbredir.c:890
+#, c-format
+msgid "usbredir protocol parse error for %s"
+msgstr "errore di formato nel protocollo usbredir per %s"
+
+#: ../src/channel-usbredir.c:895
+#, c-format
+msgid "%s rejected by host"
+msgstr "%s rifiutato dall'host"
+
+#: ../src/channel-usbredir.c:900
+#, c-format
+msgid "%s disconnected (fatal IO error)"
+msgstr "%s disconnesso (errore I/O fatale)"
+
+#: ../src/channel-usbredir.c:904
+#, c-format
+msgid "Unknown error (%d) for %s"
+msgstr "Errore sconosciuto (%d) per %s"
+
+#: ../src/desktop-integration.c:104
+msgid "Automounting has been inhibited for USB auto-redirecting"
+msgstr ""
+"L'automontatura è stata disabilitata per consentire l'autoredirezione USB"
+
+#: ../src/spice-channel.c:1094
+msgid "Authentication failed: password and username are required"
+msgstr "Autenticazione fallita: note utente e password sono necessari"
+
+#: ../src/spice-channel.c:1099
+msgid "Authentication failed: username is required"
+msgstr "Autenticazione fallita: note utente necessario"
+
+#: ../src/spice-channel.c:1104 ../src/spice-channel.c:1114
+msgid "Authentication failed: password is required"
+msgstr "Autenticazione fallita: password necessaria"
+
+#: ../src/spice-channel.c:1109
+msgid "Authentication failed: password is too long"
+msgstr "Autenticazione fallita: password troppo lunga"
+
+#: ../src/spice-cmdline.c:36
+msgid "Spice server uri"
+msgstr "URI Spice server"
+
+#: ../src/spice-cmdline.c:37
+msgid "<uri>"
+msgstr "<uri>"
+
+#: ../src/spice-cmdline.c:43
+msgid "Spice server address"
+msgstr "Indirizzo Spice server"
+
+#: ../src/spice-cmdline.c:44
+msgid "<host>"
+msgstr "<host>"
+
+#: ../src/spice-cmdline.c:50
+msgid "Spice server port"
+msgstr "Porta Spice server"
+
+#: ../src/spice-cmdline.c:51 ../src/spice-cmdline.c:58
+msgid "<port>"
+msgstr "<porta>"
+
+#: ../src/spice-cmdline.c:57
+msgid "Spice server secure port"
+msgstr "Porta sicura Spice server"
+
+#: ../src/spice-cmdline.c:64
+msgid "Server password"
+msgstr "Password server"
+
+#: ../src/spice-cmdline.c:65
+msgid "<password>"
+msgstr "<password>"
+
+#: ../src/spice-cmdline.c:76
+msgid "Spice connection options:"
+msgstr "Opzioni connessione Spice:"
+
+#: ../src/spice-cmdline.c:77
+msgid "Show Spice options"
+msgstr "Mostra opzioni Spice"
+
+#: ../src/spice-option.c:65
+#, c-format
+msgid "missing color depth, must be 16 or 32"
+msgstr "profondità colore assente, deve essere 16 o 32"
+
+#: ../src/spice-option.c:81
+#, c-format
+msgid "invalid color depth (%s), must be 16 or 32"
+msgstr "profondità di colore invalida (%s), deve essere 16 o 32"
+
+#: ../src/spice-option.c:101
+#, c-format
+msgid ""
+"invalid effect name (%s), must be 'wallpaper', 'font-smooth', 'animation' or "
+"'all'"
+msgstr ""
+"nome effetto invalido (%s), deve essere 'wallpaper', 'font-smooth', "
+"'animation' oppure 'all'"
+
+#: ../src/spice-option.c:125
+#, c-format
+msgid "invalid channel name (%s), valid names: all, %s"
+msgstr "nome del canale invalido (%s), nomi validi: all, %s"
+
+#: ../src/spice-option.c:173
+#, c-format
+msgid "Image compression algorithm %s not supported"
+msgstr "Algoritmo di compressione %s non supportato"
+
+#: ../src/spice-option.c:195
+msgid "Force the specified channels to be secured"
+msgstr "Forza il canale specificato ad essere sicuro"
+
+#: ../src/spice-option.c:197
+msgid "Disable guest display effects"
+msgstr "Disabilita effetti grafici guest"
+
+#: ../src/spice-option.c:199
+msgid "Guest display color depth"
+msgstr "Profondità di colore guest"
+
+#: ../src/spice-option.c:201
+msgid "Truststore file for secure connections"
+msgstr "Archivio certificatori per connessioni sicure"
+
+#: ../src/spice-option.c:201
+msgid "<file>"
+msgstr "<file>"
+
+#: ../src/spice-option.c:203
+msgid "Subject of the host certificate (field=value pairs separated by commas)"
+msgstr ""
+"Oggetto del certificato dell'host (campo=paia di valori separati da virgola)"
+
+#: ../src/spice-option.c:203
+msgid "<host-subject>"
+msgstr "<oggetto-host>"
+
+#: ../src/spice-option.c:205
+msgid "Disable audio support"
+msgstr "Disabilita supporto audio"
+
+#: ../src/spice-option.c:207
+msgid "Enable smartcard support"
+msgstr "Abilita supporto smartcard"
+
+#: ../src/spice-option.c:209
+msgid ""
+"Certificates to use for software smartcards (field=values separated by "
+"commas)"
+msgstr ""
+"Certificati da usare per smartcard software (campo=valori separati da "
+"virgola)"
+
+#: ../src/spice-option.c:209
+msgid "<certificates>"
+msgstr "<certificati>"
+
+#: ../src/spice-option.c:211
+msgid ""
+"Path to the local certificate database to use for software smartcard "
+"certificates"
+msgstr ""
+"Percorso del database di certificati locali da usare per i certificati delle "
+"smartcard software"
+
+#: ../src/spice-option.c:211
+msgid "<certificate-db>"
+msgstr "<database-certificati>"
+
+#: ../src/spice-option.c:213
+msgid "Disable USB redirection support"
+msgstr "Disabilita supporto redirezione USB"
+
+#: ../src/spice-option.c:218
+msgid "Filter selecting USB devices to be auto-redirected when plugged in"
+msgstr ""
+"Filtro per la selezione dispositivi USB che devono essere rediretti quando "
+"inseriti"
+
+#: ../src/spice-option.c:218 ../src/spice-option.c:220
+msgid "<filter-string>"
+msgstr "<stringa-filtro>"
+
+#: ../src/spice-option.c:220
+msgid "Filter selecting USB devices to redirect on connect"
+msgstr ""
+"Filtro per la selezione dispositivi USB che devono essere rediretti alla "
+"connessione"
+
+#: ../src/spice-option.c:222
+msgid "Image cache size"
+msgstr "Dimensione cache immagini"
+
+#: ../src/spice-option.c:222 ../src/spice-option.c:224
+msgid "<bytes>"
+msgstr "<byte>"
+
+#: ../src/spice-option.c:224
+msgid "Glz compression history size"
+msgstr "Dimensione finestra di compressione glz"
+
+#: ../src/spice-option.c:226
+msgid "Shared directory"
+msgstr "Cartella condivisa"
+
+#: ../src/spice-option.c:226
+msgid "<dir>"
+msgstr "<cartella>"
+
+#: ../src/spice-option.c:228
+msgid "Preferred image compression algorithm"
+msgstr "Algoritmo compressione immagini preferito"
+
+#: ../src/spice-option.c:236
+msgid "Enable Spice-GTK debugging"
+msgstr "Abilita debugging Spice-GTK"
+
+#: ../src/spice-option.c:238
+msgid "Display Spice-GTK version information"
+msgstr "Mostra informazioni versione Spice-GTK"
+
+#: ../src/spice-option.c:243
+msgid "Spice Options:"
+msgstr "Opzioni Spice:"
+
+#: ../src/spice-option.c:243
+msgid "Show Spice Options"
+msgstr "Mostra opzioni Spice"
+
+#: ../src/usb-device-manager.c:364 ../src/usb-device-manager.c:1954
+msgid "USB redirection support not compiled in"
+msgstr "Supporto redirezione USB non compilato"
+
+#: ../src/usb-device-manager.c:1640
+msgid "Device was not found"
+msgstr "Dispositivo non trovato"
+
+#: ../src/usb-device-manager.c:1656
+msgid "No free USB channel"
+msgstr "Nessun canale USB libero"
+
+#: ../src/usb-device-manager.c:1891
+msgid "USB redirection is disabled"
+msgstr "Redirezione USB disabilitata"
+
+#: ../src/usb-device-manager.c:1897
+msgid "The connected VM is not configured for USB redirection"
+msgstr ""
+"La macchina a cui siete connessi non è configurata per la redirezione USB"
+
+#: ../src/usb-device-manager.c:1919
+msgid "Some USB devices were not found"
+msgstr "Qualche dispositivo USB non è stato trovato"
+
+#: ../src/usb-device-manager.c:1929
+msgid "Some USB devices are blocked by host policy"
+msgstr "Qualche dispositivo USB è bloccato da una politica host"
+
+#: ../src/usb-device-manager.c:1947
+msgid "There are no free USB channels"
+msgstr "Non ci sono canali USB liberi"
+
+#: ../src/usb-device-manager.c:2003
+#, c-format
+msgid "%s %s %s at %d-%d"
+msgstr "%s %s %s a %d-%d"
+
+#: ../src/usb-device-widget.c:207
+msgid "Select USB devices to redirect"
+msgstr "Selezionare dispositivo USB da redirigere"
+
+#: ../src/usb-device-widget.c:420
+#, c-format
+msgid "Select USB devices to redirect (%d free channel)"
+msgstr "Selezionare dispositivo USB da redirigere (%d canale libero)"
+
+#: ../src/usb-device-widget.c:421
+#, c-format
+msgid "Select USB devices to redirect (%d free channels)"
+msgstr "Selezionare dispositivo USB da redirigere (%d canali liberi)"
+
+#: ../src/usb-device-widget.c:439
+msgid "Redirecting USB Device..."
+msgstr "Reindirizzando dispositivo USB..."
+
+#: ../src/usb-device-widget.c:447
+msgid "No USB devices detected"
+msgstr "Dispositivo USB non rilevato"
+
+#: ../src/usbutil.c:293
+msgid "USB"
+msgstr "USB"
+
+#: ../src/usbutil.c:295
+msgid "Device"
+msgstr "Dispositivo"
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: spice-client-glib-2.0
+Description: SPICE Client GLib 2.0 library
+Version: @VERSION@
+
+Requires: spice-protocol
+Requires.private: @SPICE_GLIB_REQUIRES@
+Libs: -L${libdir} -lspice-client-glib-2.0
+Cflags: -I${includedir}/spice-client-glib-2.0
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: spice-client-gtk-3.0
+Description: SPICE Client Gtk 3.0 library
+Version: @VERSION@
+
+Requires: @SPICE_GTK_REQUIRES@ spice-client-glib-2.0
+Libs: -L${libdir} -lspice-client-gtk-3.0
+Cflags: -I${includedir}/spice-client-gtk-3.0
--- /dev/null
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
--- /dev/null
+NULL =
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = python_modules common tests
+
+EXTRA_DIST = \
+ spice_codegen.py \
+ spice.proto \
+ spice1.proto \
+ $(NULL)
+
+DISTCLEANFILES = *.pyc
+
+MAINTAINERCLEANFILES = \
+ $(srcdir)/INSTALL \
+ $(srcdir)/aclocal.m4 \
+ $(srcdir)/autoscan.log \
+ $(srcdir)/build-aux \
+ $(srcdir)/config.h.in \
+ $(srcdir)/m4/libtool.m4 \
+ $(srcdir)/m4/ltoptions.m4 \
+ $(srcdir)/m4/ltsugar.m4 \
+ $(srcdir)/m4/ltversion.m4 \
+ $(srcdir)/m4/lt~obsolete.m4 \
+ `find "$(srcdir)" -type f -name Makefile.in -print` \
+ $(NULL)
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_module.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps) $(am__DIST_COMMON)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+ $(LISP)config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+ $(top_srcdir)/build-aux/ar-lib $(top_srcdir)/build-aux/compile \
+ $(top_srcdir)/build-aux/config.guess \
+ $(top_srcdir)/build-aux/config.sub \
+ $(top_srcdir)/build-aux/install-sh \
+ $(top_srcdir)/build-aux/ltmain.sh \
+ $(top_srcdir)/build-aux/missing COPYING build-aux/ar-lib \
+ build-aux/compile build-aux/config.guess build-aux/config.sub \
+ build-aux/install-sh build-aux/ltmain.sh build-aux/missing
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ if test -d "$(distdir)"; then \
+ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -rf "$(distdir)" \
+ || { sleep 5 && rm -rf "$(distdir)"; }; \
+ else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+GZIP_ENV = --best
+DIST_ARCHIVES = $(distdir).tar.xz
+DIST_TARGETS = dist-xz
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CELT051_CFLAGS = @CELT051_CFLAGS@
+CELT051_LIBS = @CELT051_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPUS_CFLAGS = @OPUS_CFLAGS@
+OPUS_LIBS = @OPUS_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PROTOCOL_CFLAGS = @PROTOCOL_CFLAGS@
+PROTOCOL_LIBS = @PROTOCOL_LIBS@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_COMMON_CFLAGS = @SPICE_COMMON_CFLAGS@
+SPICE_COMMON_LIBS = @SPICE_COMMON_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+ACLOCAL_AMFLAGS = -I m4
+SUBDIRS = python_modules common tests
+EXTRA_DIST = \
+ spice_codegen.py \
+ spice.proto \
+ spice1.proto \
+ $(NULL)
+
+DISTCLEANFILES = *.pyc
+MAINTAINERCLEANFILES = \
+ $(srcdir)/INSTALL \
+ $(srcdir)/aclocal.m4 \
+ $(srcdir)/autoscan.log \
+ $(srcdir)/build-aux \
+ $(srcdir)/config.h.in \
+ $(srcdir)/m4/libtool.m4 \
+ $(srcdir)/m4/ltoptions.m4 \
+ $(srcdir)/m4/ltsugar.m4 \
+ $(srcdir)/m4/ltversion.m4 \
+ $(srcdir)/m4/lt~obsolete.m4 \
+ `find "$(srcdir)" -type f -name Makefile.in -print` \
+ $(NULL)
+
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @test -f $@ || rm -f stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+ test ! -s cscope.files \
+ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+ -rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+ -rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__post_remove_distdir)
+
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+ $(am__post_remove_distdir)
+
+dist-lzip: distdir
+ tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+ $(am__post_remove_distdir)
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+ $(am__post_remove_distdir)
+
+dist-tarZ: distdir
+ @echo WARNING: "Support for distribution archives compressed with" \
+ "legacy program 'compress' is deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__post_remove_distdir)
+
+dist-shar: distdir
+ @echo WARNING: "Support for shar distribution archives is" \
+ "deprecated." >&2
+ @echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__post_remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__post_remove_distdir)
+
+dist dist-all:
+ $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+ $(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lz*) \
+ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir)
+ chmod u+w $(distdir)
+ mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build/sub \
+ && ../../configure \
+ $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ --srcdir=../.. --prefix="$$dc_install_base" \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__post_remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @test -n '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: trying to run $@ with an empty' \
+ '$$(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ $(am__cd) '$(distuninstallcheck_dir)' || { \
+ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+ exit 1; \
+ }; \
+ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile config.h
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) all install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+ am--refresh check check-am clean clean-cscope clean-generic \
+ clean-libtool cscope cscopelist-am ctags ctags-am dist \
+ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
+ dist-xz dist-zip distcheck distclean distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags distcleancheck \
+ distdir distuninstallcheck dvi dvi-am html html-am info \
+ info-am install install-am install-data install-data-am \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am
+
+.PRECIOUS: Makefile
+
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+# generated automatically by aclocal 1.15 -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+dnl serial 11 (pkg-config-0.29)
+dnl
+dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+dnl 02111-1307, USA.
+dnl
+dnl As a special exception to the GNU General Public License, if you
+dnl distribute this file as part of a program that contains a
+dnl configuration script generated by Autoconf, you may include it under
+dnl the same distribution terms that you use for the rest of that
+dnl program.
+
+dnl PKG_PREREQ(MIN-VERSION)
+dnl -----------------------
+dnl Since: 0.29
+dnl
+dnl Verify that the version of the pkg-config macros are at least
+dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
+dnl installed version of pkg-config, this checks the developer's version
+dnl of pkg.m4 when generating configure.
+dnl
+dnl To ensure that this macro is defined, also add:
+dnl m4_ifndef([PKG_PREREQ],
+dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
+dnl
+dnl See the "Since" comment for each macro you use to see what version
+dnl of the macros you require.
+m4_defun([PKG_PREREQ],
+[m4_define([PKG_MACROS_VERSION], [0.29])
+m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
+ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
+])dnl PKG_PREREQ
+
+dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
+dnl ----------------------------------
+dnl Since: 0.16
+dnl
+dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
+dnl first found in the path. Checks that the version of pkg-config found
+dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
+dnl used since that's the first version where most current features of
+dnl pkg-config existed.
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=m4_default([$1], [0.9.0])
+ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ PKG_CONFIG=""
+ fi
+fi[]dnl
+])dnl PKG_PROG_PKG_CONFIG
+
+dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------------------------------
+dnl Since: 0.18
+dnl
+dnl Check to see whether a particular set of modules exists. Similar to
+dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
+dnl
+dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+dnl only at the first occurence in configure.ac, so if the first place
+dnl it's called might be skipped (such as if it is within an "if", you
+dnl have to call PKG_CHECK_EXISTS manually
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+ m4_default([$2], [:])
+m4_ifvaln([$3], [else
+ $3])dnl
+fi])
+
+dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+dnl ---------------------------------------------
+dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
+dnl pkg_failed based on the result.
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+ pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+ PKG_CHECK_EXISTS([$3],
+ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes ],
+ [pkg_failed=yes])
+ else
+ pkg_failed=untried
+fi[]dnl
+])dnl _PKG_CONFIG
+
+dnl _PKG_SHORT_ERRORS_SUPPORTED
+dnl ---------------------------
+dnl Internal check to see if pkg-config supports short errors.
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi[]dnl
+])dnl _PKG_SHORT_ERRORS_SUPPORTED
+
+
+dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl --------------------------------------------------------------
+dnl Since: 0.4.0
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
+dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+ AC_MSG_RESULT([no])
+ _PKG_SHORT_ERRORS_SUPPORTED
+ if test $_pkg_short_errors_supported = yes; then
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+ else
+ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+ m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+ ])
+elif test $pkg_failed = untried; then
+ AC_MSG_RESULT([no])
+ m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
+ ])
+else
+ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+ AC_MSG_RESULT([yes])
+ $3
+fi[]dnl
+])dnl PKG_CHECK_MODULES
+
+
+dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl ---------------------------------------------------------------------
+dnl Since: 0.29
+dnl
+dnl Checks for existence of MODULES and gathers its build flags with
+dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
+dnl and VARIABLE-PREFIX_LIBS from --libs.
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
+dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
+dnl configure.ac.
+AC_DEFUN([PKG_CHECK_MODULES_STATIC],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+_save_PKG_CONFIG=$PKG_CONFIG
+PKG_CONFIG="$PKG_CONFIG --static"
+PKG_CHECK_MODULES($@)
+PKG_CONFIG=$_save_PKG_CONFIG[]dnl
+])dnl PKG_CHECK_MODULES_STATIC
+
+
+dnl PKG_INSTALLDIR([DIRECTORY])
+dnl -------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable pkgconfigdir as the location where a module
+dnl should install pkg-config .pc files. By default the directory is
+dnl $libdir/pkgconfig, but the default can be changed by passing
+dnl DIRECTORY. The user can override through the --with-pkgconfigdir
+dnl parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+ [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_INSTALLDIR
+
+
+dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
+dnl --------------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable noarch_pkgconfigdir as the location where a
+dnl module should install arch-independent pkg-config .pc files. By
+dnl default the directory is $datadir/pkgconfig, but the default can be
+dnl changed by passing DIRECTORY. The user can override through the
+dnl --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+ [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_NOARCH_INSTALLDIR
+
+
+dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------
+dnl Since: 0.28
+dnl
+dnl Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])dnl PKG_CHECK_VAR
+
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.15'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.15], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.15])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_AR([ACT-IF-FAIL])
+# -------------------------
+# Try to determine the archiver interface, and trigger the ar-lib wrapper
+# if it is needed. If the detection of archiver interface fails, run
+# ACT-IF-FAIL (default is to abort configure with a proper error message).
+AC_DEFUN([AM_PROG_AR],
+[AC_BEFORE([$0], [LT_INIT])dnl
+AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([ar-lib])dnl
+AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
+: ${AR=ar}
+
+AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
+ [AC_LANG_PUSH([C])
+ am_cv_ar_interface=ar
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
+ [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([am_ar_try])
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=ar
+ else
+ am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([am_ar_try])
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=lib
+ else
+ am_cv_ar_interface=unknown
+ fi
+ fi
+ rm -f conftest.lib libconftest.a
+ ])
+ AC_LANG_POP([C])])
+
+case $am_cv_ar_interface in
+ar)
+ ;;
+lib)
+ # Microsoft lib, so override with the ar-lib wrapper script.
+ # FIXME: It is wrong to rewrite AR.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__AR in this case,
+ # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+ # similar.
+ AR="$am_aux_dir/ar-lib $AR"
+ ;;
+unknown)
+ m4_default([$1],
+ [AC_MSG_ERROR([could not determine $AR interface])])
+ ;;
+esac
+AC_SUBST([AR])dnl
+])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+])
+
+# AM_COND_IF -*- Autoconf -*-
+
+# Copyright (C) 2008-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_COND_IF
+# _AM_COND_ELSE
+# _AM_COND_ENDIF
+# --------------
+# These macros are only used for tracing.
+m4_define([_AM_COND_IF])
+m4_define([_AM_COND_ELSE])
+m4_define([_AM_COND_ENDIF])
+
+# AM_COND_IF(COND, [IF-TRUE], [IF-FALSE])
+# ---------------------------------------
+# If the shell condition COND is true, execute IF-TRUE, otherwise execute
+# IF-FALSE. Allow automake to learn about conditional instantiating macros
+# (the AC_CONFIG_FOOS).
+AC_DEFUN([AM_COND_IF],
+[m4_ifndef([_AM_COND_VALUE_$1],
+ [m4_fatal([$0: no such condition "$1"])])dnl
+_AM_COND_IF([$1])dnl
+if test -z "$$1_TRUE"; then :
+ m4_n([$2])[]dnl
+m4_ifval([$3],
+[_AM_COND_ELSE([$1])dnl
+else
+ $3
+])dnl
+_AM_COND_ENDIF([$1])dnl
+fi[]dnl
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC], [depcc="$CC" am_compiler_list=],
+ [$1], [CXX], [depcc="$CXX" am_compiler_list=],
+ [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+ [$1], [UPC], [depcc="$UPC" am_compiler_list=],
+ [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+ [--enable-dependency-tracking],
+ [do not reject slow dependency extractors])
+AS_HELP_STRING(
+ [--disable-dependency-tracking],
+ [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "$am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each '.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+ [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+ m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+ [ok:ok],,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES([CC])],
+ [m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES([CXX])],
+ [m4_define([AC_PROG_CXX],
+ m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES([OBJC])],
+ [m4_define([AC_PROG_OBJC],
+ m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+ [_AM_DEPENDENCIES([OBJCXX])],
+ [m4_define([AC_PROG_OBJCXX],
+ m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+ fi
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
+])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+ [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+ am_maintainer_other[ make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer])],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# -*- Autoconf -*-
+# Obsolete and "removed" macros, that must however still report explicit
+# error messages when used, to smooth transition.
+#
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([AM_CONFIG_HEADER],
+[AC_DIAGNOSE([obsolete],
+['$0': this macro is obsolete.
+You should use the 'AC][_CONFIG_HEADERS' macro instead.])dnl
+AC_CONFIG_HEADERS($@)])
+
+AC_DEFUN([AM_PROG_CC_STDC],
+[AC_PROG_CC
+am_cv_prog_cc_stdc=$ac_cv_prog_cc_stdc
+AC_DIAGNOSE([obsolete],
+['$0': this macro is obsolete.
+You should simply use the 'AC][_PROG_CC' macro instead.
+Also, your code should no longer depend upon 'am_cv_prog_cc_stdc',
+but upon 'ac_cv_prog_cc_stdc'.])])
+
+AC_DEFUN([AM_C_PROTOTYPES],
+ [AC_FATAL([automatic de-ANSI-fication support has been removed])])
+AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+ [whether $CC understands -c and -o together],
+ [am_cv_prog_cc_c_o],
+ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# ---------------------------------------------------------------------------
+# Adds support for distributing Python modules and packages. To
+# install modules, copy them to $(pythondir), using the python_PYTHON
+# automake variable. To install a package with the same name as the
+# automake package, install to $(pkgpythondir), or use the
+# pkgpython_PYTHON automake variable.
+#
+# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as
+# locations to install python extension modules (shared libraries).
+# Another macro is required to find the appropriate flags to compile
+# extension modules.
+#
+# If your package is configured with a different prefix to python,
+# users will have to add the install directory to the PYTHONPATH
+# environment variable, or create a .pth file (see the python
+# documentation for details).
+#
+# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will
+# cause an error if the version of python installed on the system
+# doesn't meet the requirement. MINIMUM-VERSION should consist of
+# numbers and dots only.
+AC_DEFUN([AM_PATH_PYTHON],
+ [
+ dnl Find a Python interpreter. Python versions prior to 2.0 are not
+ dnl supported. (2.0 was released on October 16, 2000).
+ m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
+[python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 dnl
+ python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0])
+
+ AC_ARG_VAR([PYTHON], [the Python interpreter])
+
+ m4_if([$1],[],[
+ dnl No version check is needed.
+ # Find any Python interpreter.
+ if test -z "$PYTHON"; then
+ AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :)
+ fi
+ am_display_PYTHON=python
+ ], [
+ dnl A version check is needed.
+ if test -n "$PYTHON"; then
+ # If the user set $PYTHON, use it and don't search something else.
+ AC_MSG_CHECKING([whether $PYTHON version is >= $1])
+ AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
+ [AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])
+ AC_MSG_ERROR([Python interpreter is too old])])
+ am_display_PYTHON=$PYTHON
+ else
+ # Otherwise, try each interpreter until we find one that satisfies
+ # VERSION.
+ AC_CACHE_CHECK([for a Python interpreter with version >= $1],
+ [am_cv_pathless_PYTHON],[
+ for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do
+ test "$am_cv_pathless_PYTHON" = none && break
+ AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break])
+ done])
+ # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON.
+ if test "$am_cv_pathless_PYTHON" = none; then
+ PYTHON=:
+ else
+ AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON])
+ fi
+ am_display_PYTHON=$am_cv_pathless_PYTHON
+ fi
+ ])
+
+ if test "$PYTHON" = :; then
+ dnl Run any user-specified action, or abort.
+ m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
+ else
+
+ dnl Query Python for its version number. Getting [:3] seems to be
+ dnl the best way to do this; it's what "site.py" does in the standard
+ dnl library.
+
+ AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
+ [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`])
+ AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
+
+ dnl Use the values of $prefix and $exec_prefix for the corresponding
+ dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made
+ dnl distinct variables so they can be overridden if need be. However,
+ dnl general consensus is that you shouldn't need this ability.
+
+ AC_SUBST([PYTHON_PREFIX], ['${prefix}'])
+ AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}'])
+
+ dnl At times (like when building shared libraries) you may want
+ dnl to know which OS platform Python thinks this is.
+
+ AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform],
+ [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
+ AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform])
+
+ # Just factor out some code duplication.
+ am_python_setup_sysconfig="\
+import sys
+# Prefer sysconfig over distutils.sysconfig, for better compatibility
+# with python 3.x. See automake bug#10227.
+try:
+ import sysconfig
+except ImportError:
+ can_use_sysconfig = 0
+else:
+ can_use_sysconfig = 1
+# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs:
+# <https://github.com/pypa/virtualenv/issues/118>
+try:
+ from platform import python_implementation
+ if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7':
+ can_use_sysconfig = 0
+except ImportError:
+ pass"
+
+ dnl Set up 4 directories:
+
+ dnl pythondir -- where to install python scripts. This is the
+ dnl site-packages directory, not the python standard library
+ dnl directory like in previous automake betas. This behavior
+ dnl is more consistent with lispdir.m4 for example.
+ dnl Query distutils for this directory.
+ AC_CACHE_CHECK([for $am_display_PYTHON script directory],
+ [am_cv_python_pythondir],
+ [if test "x$prefix" = xNONE
+ then
+ am_py_prefix=$ac_default_prefix
+ else
+ am_py_prefix=$prefix
+ fi
+ am_cv_python_pythondir=`$PYTHON -c "
+$am_python_setup_sysconfig
+if can_use_sysconfig:
+ sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
+else:
+ from distutils import sysconfig
+ sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
+sys.stdout.write(sitedir)"`
+ case $am_cv_python_pythondir in
+ $am_py_prefix*)
+ am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
+ am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"`
+ ;;
+ *)
+ case $am_py_prefix in
+ /usr|/System*) ;;
+ *)
+ am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages
+ ;;
+ esac
+ ;;
+ esac
+ ])
+ AC_SUBST([pythondir], [$am_cv_python_pythondir])
+
+ dnl pkgpythondir -- $PACKAGE directory under pythondir. Was
+ dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is
+ dnl more consistent with the rest of automake.
+
+ AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE])
+
+ dnl pyexecdir -- directory for installing python extension modules
+ dnl (shared libraries)
+ dnl Query distutils for this directory.
+ AC_CACHE_CHECK([for $am_display_PYTHON extension module directory],
+ [am_cv_python_pyexecdir],
+ [if test "x$exec_prefix" = xNONE
+ then
+ am_py_exec_prefix=$am_py_prefix
+ else
+ am_py_exec_prefix=$exec_prefix
+ fi
+ am_cv_python_pyexecdir=`$PYTHON -c "
+$am_python_setup_sysconfig
+if can_use_sysconfig:
+ sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
+else:
+ from distutils import sysconfig
+ sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
+sys.stdout.write(sitedir)"`
+ case $am_cv_python_pyexecdir in
+ $am_py_exec_prefix*)
+ am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
+ am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"`
+ ;;
+ *)
+ case $am_py_exec_prefix in
+ /usr|/System*) ;;
+ *)
+ am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages
+ ;;
+ esac
+ ;;
+ esac
+ ])
+ AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir])
+
+ dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE)
+
+ AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE])
+
+ dnl Run any user-specified action.
+ $2
+ fi
+
+])
+
+
+# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+# ---------------------------------------------------------------------------
+# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION.
+# Run ACTION-IF-FALSE otherwise.
+# This test uses sys.hexversion instead of the string equivalent (first
+# word of sys.version), in order to cope with versions such as 2.2c1.
+# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000).
+AC_DEFUN([AM_PYTHON_CHECK_VERSION],
+ [prog="import sys
+# split strings by '.' and convert to numeric. Append some zeros
+# because we need at least 4 digits for the hex conversion.
+# map returns an iterator in Python 3.0 and a list in 2.x
+minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]]
+minverhex = 0
+# xrange is not present in Python 3.0 and range returns an iterator
+for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
+sys.exit(sys.hexversion < minverhex)"
+ AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+ alias in your environment])
+ fi
+ if test "$[2]" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+ [AC_MSG_CHECKING([that generated files are newer than configure])
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+ [--enable-silent-rules],
+ [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+ [--disable-silent-rules],
+ [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+ [am_cv_make_support_nested_variables],
+ [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+ dnl Using '$V' instead of '$(V)' breaks IRIX make.
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+ [m4_case([$1],
+ [ustar],
+ [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+ if test $am_uid -le $am_max_uid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi
+ AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+ if test $am_gid -le $am_max_gid; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ _am_tools=none
+ fi],
+
+ [pax],
+ [],
+
+ [m4_fatal([Unknown tar format])])
+
+ AC_MSG_CHECKING([how to create a $1 tar archive])
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ AM_RUN_LOG([cat conftest.dir/file])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
+ rm -rf conftest.dir
+
+ AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+ AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/ax_python_module.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
+m4_include([m4/spice-deps.m4])
--- /dev/null
+#! /bin/sh
+# Wrapper for Microsoft lib.exe
+
+me=ar-lib
+scriptversion=2012-03-01.08; # UTC
+
+# Copyright (C) 2010-2014 Free Software Foundation, Inc.
+# Written by Peter Rosin <peda@lysator.liu.se>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+
+# func_error message
+func_error ()
+{
+ echo "$me: $1" 1>&2
+ exit 1
+}
+
+file_conv=
+
+# func_file_conv build_file
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv in
+ mingw)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_at_file at_file operation archive
+# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
+# for each of them.
+# When interpreting the content of the @FILE, do NOT use func_file_conv,
+# since the user would need to supply preconverted file names to
+# binutils ar, at least for MinGW.
+func_at_file ()
+{
+ operation=$2
+ archive=$3
+ at_file_contents=`cat "$1"`
+ eval set x "$at_file_contents"
+ shift
+
+ for member
+ do
+ $AR -NOLOGO $operation:"$member" "$archive" || exit $?
+ done
+}
+
+case $1 in
+ '')
+ func_error "no command. Try '$0 --help' for more information."
+ ;;
+ -h | --h*)
+ cat <<EOF
+Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
+
+Members may be specified in a file named with @FILE.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "$me, version $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test $# -lt 3; then
+ func_error "you must specify a program, an action and an archive"
+fi
+
+AR=$1
+shift
+while :
+do
+ if test $# -lt 2; then
+ func_error "you must specify a program, an action and an archive"
+ fi
+ case $1 in
+ -lib | -LIB \
+ | -ltcg | -LTCG \
+ | -machine* | -MACHINE* \
+ | -subsystem* | -SUBSYSTEM* \
+ | -verbose | -VERBOSE \
+ | -wx* | -WX* )
+ AR="$AR $1"
+ shift
+ ;;
+ *)
+ action=$1
+ shift
+ break
+ ;;
+ esac
+done
+orig_archive=$1
+shift
+func_file_conv "$orig_archive"
+archive=$file
+
+# strip leading dash in $action
+action=${action#-}
+
+delete=
+extract=
+list=
+quick=
+replace=
+index=
+create=
+
+while test -n "$action"
+do
+ case $action in
+ d*) delete=yes ;;
+ x*) extract=yes ;;
+ t*) list=yes ;;
+ q*) quick=yes ;;
+ r*) replace=yes ;;
+ s*) index=yes ;;
+ S*) ;; # the index is always updated implicitly
+ c*) create=yes ;;
+ u*) ;; # TODO: don't ignore the update modifier
+ v*) ;; # TODO: don't ignore the verbose modifier
+ *)
+ func_error "unknown action specified"
+ ;;
+ esac
+ action=${action#?}
+done
+
+case $delete$extract$list$quick$replace,$index in
+ yes,* | ,yes)
+ ;;
+ yesyes*)
+ func_error "more than one action specified"
+ ;;
+ *)
+ func_error "no action specified"
+ ;;
+esac
+
+if test -n "$delete"; then
+ if test ! -f "$orig_archive"; then
+ func_error "archive not found"
+ fi
+ for member
+ do
+ case $1 in
+ @*)
+ func_at_file "${1#@}" -REMOVE "$archive"
+ ;;
+ *)
+ func_file_conv "$1"
+ $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
+ ;;
+ esac
+ done
+
+elif test -n "$extract"; then
+ if test ! -f "$orig_archive"; then
+ func_error "archive not found"
+ fi
+ if test $# -gt 0; then
+ for member
+ do
+ case $1 in
+ @*)
+ func_at_file "${1#@}" -EXTRACT "$archive"
+ ;;
+ *)
+ func_file_conv "$1"
+ $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
+ ;;
+ esac
+ done
+ else
+ $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
+ do
+ $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
+ done
+ fi
+
+elif test -n "$quick$replace"; then
+ if test ! -f "$orig_archive"; then
+ if test -z "$create"; then
+ echo "$me: creating $orig_archive"
+ fi
+ orig_archive=
+ else
+ orig_archive=$archive
+ fi
+
+ for member
+ do
+ case $1 in
+ @*)
+ func_file_conv "${1#@}"
+ set x "$@" "@$file"
+ ;;
+ *)
+ func_file_conv "$1"
+ set x "$@" "$file"
+ ;;
+ esac
+ shift
+ shift
+ done
+
+ if test -n "$orig_archive"; then
+ $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
+ else
+ $AR -NOLOGO -OUT:"$archive" "$@" || exit $?
+ fi
+
+elif test -n "$list"; then
+ if test ! -f "$orig_archive"; then
+ func_error "archive not found"
+ fi
+ $AR -NOLOGO -LIST "$archive" || exit $?
+fi
--- /dev/null
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" "" $nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+ file=$1
+ case $file in
+ / | /[!/]*) # absolute file, and not a UNC file
+ if test -z "$file_conv"; then
+ # lazily determine how to convert abs files
+ case `uname -s` in
+ MINGW*)
+ file_conv=mingw
+ ;;
+ CYGWIN*)
+ file_conv=cygwin
+ ;;
+ *)
+ file_conv=wine
+ ;;
+ esac
+ fi
+ case $file_conv/,$2, in
+ *,$file_conv,*)
+ ;;
+ mingw/*)
+ file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+ ;;
+ cygwin/*)
+ file=`cygpath -m "$file" || echo "$file"`
+ ;;
+ wine/*)
+ file=`winepath -w "$file" || echo "$file"`
+ ;;
+ esac
+ ;;
+ esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+ func_file_conv "$1"
+ if test -z "$lib_path"; then
+ lib_path=$file
+ else
+ lib_path="$lib_path;$file"
+ fi
+ linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+ lib=$1
+ found=no
+ save_IFS=$IFS
+ IFS=';'
+ for dir in $lib_path $LIB
+ do
+ IFS=$save_IFS
+ if $shared && test -f "$dir/$lib.dll.lib"; then
+ found=yes
+ lib=$dir/$lib.dll.lib
+ break
+ fi
+ if test -f "$dir/$lib.lib"; then
+ found=yes
+ lib=$dir/$lib.lib
+ break
+ fi
+ if test -f "$dir/lib$lib.a"; then
+ found=yes
+ lib=$dir/lib$lib.a
+ break
+ fi
+ done
+ IFS=$save_IFS
+
+ if test "$found" != yes; then
+ lib=$lib.lib
+ fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+ # Assume a capable shell
+ lib_path=
+ shared=:
+ linker_opts=
+ for arg
+ do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ eat=1
+ case $2 in
+ *.o | *.[oO][bB][jJ])
+ func_file_conv "$2"
+ set x "$@" -Fo"$file"
+ shift
+ ;;
+ *)
+ func_file_conv "$2"
+ set x "$@" -Fe"$file"
+ shift
+ ;;
+ esac
+ ;;
+ -I)
+ eat=1
+ func_file_conv "$2" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -I*)
+ func_file_conv "${1#-I}" mingw
+ set x "$@" -I"$file"
+ shift
+ ;;
+ -l)
+ eat=1
+ func_cl_dashl "$2"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -l*)
+ func_cl_dashl "${1#-l}"
+ set x "$@" "$lib"
+ shift
+ ;;
+ -L)
+ eat=1
+ func_cl_dashL "$2"
+ ;;
+ -L*)
+ func_cl_dashL "${1#-L}"
+ ;;
+ -static)
+ shared=false
+ ;;
+ -Wl,*)
+ arg=${1#-Wl,}
+ save_ifs="$IFS"; IFS=','
+ for flag in $arg; do
+ IFS="$save_ifs"
+ linker_opts="$linker_opts $flag"
+ done
+ IFS="$save_ifs"
+ ;;
+ -Xlinker)
+ eat=1
+ linker_opts="$linker_opts $2"
+ ;;
+ -*)
+ set x "$@" "$1"
+ shift
+ ;;
+ *.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+ func_file_conv "$1"
+ set x "$@" -Tp"$file"
+ shift
+ ;;
+ *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+ func_file_conv "$1" mingw
+ set x "$@" "$file"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+ done
+ if test -n "$linker_opts"; then
+ linker_opts="-link$linker_opts"
+ fi
+ exec "$@" $linker_opts
+ exit 1
+}
+
+eat=
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+ cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+ func_cl_wrapper "$@" # Doesn't return...
+ ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as 'compile cc -o foo foo.c'.
+ # So we strip '-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no '-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # '.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2015 Free Software Foundation, Inc.
+
+timestamp='2015-01-01'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches to <config-patches@gnu.org>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2015 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2015 Free Software Foundation, Inc.
+
+timestamp='2015-01-01'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2015 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv | ft32 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | riscv32 | riscv64 \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | visium-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2013-05-30.07; # UTC
+
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try '$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by 'PROGRAMS ARGS'.
+ object Object file output by 'PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputting dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'. Note that this directory component will
+# be either empty or ending with a '/' character. This is deliberate.
+set_dir_from ()
+{
+ case $1 in
+ */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+ *) dir=;;
+ esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+ base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+ echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+ # If the compiler actually managed to produce a dependency file,
+ # post-process it.
+ if test -f "$tmpdepfile"; then
+ # Each line is of the form 'foo.o: dependency.h'.
+ # Do two passes, one to just change these to
+ # $object: dependency.h
+ # and one to simply output
+ # dependency.h:
+ # which is needed to avoid the deleted-header problem.
+ { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+ sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+ } > "$depfile"
+ rm -f "$tmpdepfile"
+ else
+ make_dummy_depfile
+ fi
+}
+
+# A tabulation character.
+tab=' '
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+ # This is just like msvisualcpp but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+ # This is just like msvc7 but w/o cygpath translation.
+ # Just convert the backslash-escaped backslashes to single forward
+ # slashes to satisfy depend.m4
+ cygpath_u='sed s,\\\\,/,g'
+ depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+ # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+ gccflag=-qmakedep=gcc,-MF
+ depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say). Also, it might not be
+## supported by the other compilers which use the 'gcc' depmode.
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The second -e expression handles DOS-style file names with drive
+ # letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+## Some versions of gcc put a space before the ':'. On the theory
+## that the space means something, we add a space to the output as
+## well. hp depmode also adds that space, but also prefixes the VPATH
+## to the object. Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like '#:fec' to the end of the
+ # dependency line.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+ | tr "$nl" ' ' >> "$depfile"
+ echo >> "$depfile"
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+xlc)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts '$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$base.u
+ tmpdepfile3=$dir.libs/$base.u
+ "$@" -Wc,-M
+ else
+ tmpdepfile1=$dir$base.u
+ tmpdepfile2=$dir$base.u
+ tmpdepfile3=$dir$base.u
+ "$@" -M
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ aix_post_process_depfile
+ ;;
+
+tcc)
+ # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+ # FIXME: That version still under development at the moment of writing.
+ # Make that this statement remains true also for stable, released
+ # versions.
+ # It will wrap lines (doesn't matter whether long or short) with a
+ # trailing '\', as in:
+ #
+ # foo.o : \
+ # foo.c \
+ # foo.h \
+ #
+ # It will put a trailing '\' even on the last line, and will use leading
+ # spaces rather than leading tabs (at least since its commit 0394caf7
+ # "Emit spaces for -MD").
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+ # We have to change lines of the first kind to '$object: \'.
+ sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+ # And for each line of the second kind, we have to emit a 'dep.h:'
+ # dummy dependency, to avoid the deleted-header problem.
+ sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file. A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+ # Portland's C compiler understands '-MD'.
+ # Will always output deps to 'file.d' where file is the root name of the
+ # source file under compilation, even if file resides in a subdirectory.
+ # The object file name does not affect the name of the '.d' file.
+ # pgcc 10.2 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using '\' :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+ set_dir_from "$object"
+ # Use the source, not the object, to determine the base name, since
+ # that's sadly what pgcc will do too.
+ set_base_from "$source"
+ tmpdepfile=$base.d
+
+ # For projects that build the same source file twice into different object
+ # files, the pgcc approach of using the *source* file root name can cause
+ # problems in parallel builds. Use a locking strategy to avoid stomping on
+ # the same $tmpdepfile.
+ lockdir=$base.d-lock
+ trap "
+ echo '$0: caught signal, cleaning up...' >&2
+ rmdir '$lockdir'
+ exit 1
+ " 1 2 13 15
+ numtries=100
+ i=$numtries
+ while test $i -gt 0; do
+ # mkdir is a portable test-and-set.
+ if mkdir "$lockdir" 2>/dev/null; then
+ # This process acquired the lock.
+ "$@" -MD
+ stat=$?
+ # Release the lock.
+ rmdir "$lockdir"
+ break
+ else
+ # If the lock is being held by a different process, wait
+ # until the winning process is done or we timeout.
+ while test -d "$lockdir" && test $i -gt 0; do
+ sleep 1
+ i=`expr $i - 1`
+ done
+ fi
+ i=`expr $i - 1`
+ done
+ trap - 1 2 13 15
+ if test $i -le 0; then
+ echo "$0: failed to acquire lock after $numtries attempts" >&2
+ echo "$0: check lockdir '$lockdir'" >&2
+ exit 1
+ fi
+
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ set_dir_from "$object"
+ set_base_from "$object"
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add 'dependent.h:' lines.
+ sed -ne '2,${
+ s/^ *//
+ s/ \\*$//
+ s/$/:/
+ p
+ }' "$tmpdepfile" >> "$depfile"
+ else
+ make_dummy_depfile
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in 'foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ set_dir_from "$object"
+ set_base_from "$object"
+
+ if test "$libtool" = yes; then
+ # Libtool generates 2 separate objects for the 2 libraries. These
+ # two compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir$base.o.d # libtool 1.5
+ tmpdepfile2=$dir.libs/$base.o.d # Likewise.
+ tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ # Same post-processing that is required for AIX mode.
+ aix_post_process_depfile
+ ;;
+
+msvc7)
+ if test "$libtool" = yes; then
+ showIncludes=-Wc,-showIncludes
+ else
+ showIncludes=-showIncludes
+ fi
+ "$@" $showIncludes > "$tmpdepfile"
+ stat=$?
+ grep -v '^Note: including file: ' "$tmpdepfile"
+ if test $stat -ne 0; then
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ # The first sed program below extracts the file names and escapes
+ # backslashes for cygpath. The second sed program outputs the file
+ # name when reading, but also accumulates all include files in the
+ # hold buffer in order to output them again at the end. This only
+ # works with sed implementations that can handle large buffers.
+ sed < "$tmpdepfile" -n '
+/^Note: including file: *\(.*\)/ {
+ s//\1/
+ s/\\/\\\\/g
+ p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+ s/.*/'"$tab"'/
+ G
+ p
+}' >> "$depfile"
+ echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+ rm -f "$tmpdepfile"
+ ;;
+
+msvc7msys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for ':'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+ "$@" $dashmflag |
+ sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this sed invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ tr ' ' "$nl" < "$tmpdepfile" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no eat=no
+ for arg
+ do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ if test $eat = yes; then
+ eat=no
+ continue
+ fi
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -arch)
+ eat=yes ;;
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix=`echo "$object" | sed 's/^.*\././'`
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ # makedepend may prepend the VPATH from the source file name to the object.
+ # No need to regex-escape $object, excess matching of '.' is harmless.
+ sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process the last invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed '1,2d' "$tmpdepfile" \
+ | tr ' ' "$nl" \
+ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+ | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove '-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E \
+ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ | sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test "X$1" != 'X--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E 2>/dev/null |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+ echo "$tab" >> "$depfile"
+ sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvcmsys)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2013-12-25.23; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# 'make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+tab=' '
+nl='
+'
+IFS=" $tab$nl"
+
+# Set DOITPROG to "echo" to test this script.
+
+doit=${DOITPROG-}
+doit_exec=${doit:-exec}
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+is_target_a_directory=possibly
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t)
+ is_target_a_directory=always
+ dst_arg=$2
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) is_target_a_directory=never;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+# We allow the use of options -d and -T together, by making -d
+# take the precedence; this is for compatibility with GNU install.
+
+if test -n "$dir_arg"; then
+ if test -n "$dst_arg"; then
+ echo "$0: target directory not allowed when installing a directory." >&2
+ exit 1
+ fi
+fi
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ # Protect names problematic for 'test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call 'install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ if test $# -gt 1 || test "$is_target_a_directory" = always; then
+ if test ! -d "$dst_arg"; then
+ echo "$0: $dst_arg: Is not a directory." >&2
+ exit 1
+ fi
+ fi
+fi
+
+if test -z "$dir_arg"; then
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names problematic for 'test' and other utilities.
+ case $src in
+ -* | [=\(\)!]) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+ dst=$dst_arg
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test "$is_target_a_directory" = never; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ dstdir=`dirname "$dst"`
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ oIFS=$IFS
+ IFS=/
+ set -f
+ set fnord $dstdir
+ shift
+ set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+ set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ set +f &&
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+#! /bin/sh
+## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
+## by inline-source v2014-01-03.01
+
+# libtool (GNU libtool) 2.4.6
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION=2.4.6
+package_revision=2.4.6
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Run './libtool --help' for help with using this script from the
+# command line.
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# After configure completes, it has a better idea of some of the
+# shell tools we need than the defaults used by the functions shared
+# with bootstrap, so set those here where they can still be over-
+# ridden by the user, but otherwise take precedence.
+
+: ${AUTOCONF="autoconf"}
+: ${AUTOMAKE="automake"}
+
+
+## -------------------------- ##
+## Source external libraries. ##
+## -------------------------- ##
+
+# Much of our low-level functionality needs to be sourced from external
+# libraries, which are installed to $pkgauxdir.
+
+# Set a version string for this script.
+scriptversion=2015-01-20.17; # UTC
+
+# General shell script boiler plate, and helper functions.
+# Written by Gary V. Vaughan, 2004
+
+# Copyright (C) 2004-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# As a special exception to the GNU General Public License, if you distribute
+# this file as part of a program or library that is built using GNU Libtool,
+# you may include this file under the same distribution terms that you use
+# for the rest of that program.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# Evaluate this file near the top of your script to gain access to
+# the functions and variables defined here:
+#
+# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
+#
+# If you need to override any of the default environment variable
+# settings, do that before evaluating this file.
+
+
+## -------------------- ##
+## Shell normalisation. ##
+## -------------------- ##
+
+# Some shells need a little help to be as Bourne compatible as possible.
+# Before doing anything else, make sure all that help has been provided!
+
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
+fi
+
+# NLS nuisances: We save the old values in case they are required later.
+_G_user_locale=
+_G_safe_locale=
+for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test set = \"\${$_G_var+set}\"; then
+ save_$_G_var=\$$_G_var
+ $_G_var=C
+ export $_G_var
+ _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
+ _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
+ fi"
+done
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Make sure IFS has a sensible default
+sp=' '
+nl='
+'
+IFS="$sp $nl"
+
+# There are apparently some retarded systems that use ';' as a PATH separator!
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+
+## ------------------------- ##
+## Locate command utilities. ##
+## ------------------------- ##
+
+
+# func_executable_p FILE
+# ----------------------
+# Check that FILE is an executable regular file.
+func_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+}
+
+
+# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
+# --------------------------------------------
+# Search for either a program that responds to --version with output
+# containing "GNU", or else returned by CHECK_FUNC otherwise, by
+# trying all the directories in PATH with each of the elements of
+# PROGS_LIST.
+#
+# CHECK_FUNC should accept the path to a candidate program, and
+# set $func_check_prog_result if it truncates its output less than
+# $_G_path_prog_max characters.
+func_path_progs ()
+{
+ _G_progs_list=$1
+ _G_check_func=$2
+ _G_PATH=${3-"$PATH"}
+
+ _G_path_prog_max=0
+ _G_path_prog_found=false
+ _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:}
+ for _G_dir in $_G_PATH; do
+ IFS=$_G_save_IFS
+ test -z "$_G_dir" && _G_dir=.
+ for _G_prog_name in $_G_progs_list; do
+ for _exeext in '' .EXE; do
+ _G_path_prog=$_G_dir/$_G_prog_name$_exeext
+ func_executable_p "$_G_path_prog" || continue
+ case `"$_G_path_prog" --version 2>&1` in
+ *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
+ *) $_G_check_func $_G_path_prog
+ func_path_progs_result=$func_check_prog_result
+ ;;
+ esac
+ $_G_path_prog_found && break 3
+ done
+ done
+ done
+ IFS=$_G_save_IFS
+ test -z "$func_path_progs_result" && {
+ echo "no acceptable sed could be found in \$PATH" >&2
+ exit 1
+ }
+}
+
+
+# We want to be able to use the functions in this file before configure
+# has figured out where the best binaries are kept, which means we have
+# to search for them ourselves - except when the results are already set
+# where we skip the searches.
+
+# Unless the user overrides by setting SED, search the path for either GNU
+# sed, or the sed that truncates its output the least.
+test -z "$SED" && {
+ _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for _G_i in 1 2 3 4 5 6 7; do
+ _G_sed_script=$_G_sed_script$nl$_G_sed_script
+ done
+ echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
+ _G_sed_script=
+
+ func_check_prog_sed ()
+ {
+ _G_path_prog=$1
+
+ _G_count=0
+ printf 0123456789 >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo '' >> conftest.nl
+ "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ _G_count=`expr $_G_count + 1`
+ if test "$_G_count" -gt "$_G_path_prog_max"; then
+ # Best one so far, save it but keep looking for a better one
+ func_check_prog_result=$_G_path_prog
+ _G_path_prog_max=$_G_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test 10 -lt "$_G_count" && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out
+ }
+
+ func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
+ rm -f conftest.sed
+ SED=$func_path_progs_result
+}
+
+
+# Unless the user overrides by setting GREP, search the path for either GNU
+# grep, or the grep that truncates its output the least.
+test -z "$GREP" && {
+ func_check_prog_grep ()
+ {
+ _G_path_prog=$1
+
+ _G_count=0
+ _G_path_prog_max=0
+ printf 0123456789 >conftest.in
+ while :
+ do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo 'GREP' >> conftest.nl
+ "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
+ diff conftest.out conftest.nl >/dev/null 2>&1 || break
+ _G_count=`expr $_G_count + 1`
+ if test "$_G_count" -gt "$_G_path_prog_max"; then
+ # Best one so far, save it but keep looking for a better one
+ func_check_prog_result=$_G_path_prog
+ _G_path_prog_max=$_G_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test 10 -lt "$_G_count" && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out
+ }
+
+ func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
+ GREP=$func_path_progs_result
+}
+
+
+## ------------------------------- ##
+## User overridable command paths. ##
+## ------------------------------- ##
+
+# All uppercase variable names are used for environment variables. These
+# variables can be overridden by the user before calling a script that
+# uses them if a suitable command of that name is not already available
+# in the command search PATH.
+
+: ${CP="cp -f"}
+: ${ECHO="printf %s\n"}
+: ${EGREP="$GREP -E"}
+: ${FGREP="$GREP -F"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+
+
+## -------------------- ##
+## Useful sed snippets. ##
+## -------------------- ##
+
+sed_dirname='s|/[^/]*$||'
+sed_basename='s|^.*/||'
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
+
+# Same as above, but do not quote variable references.
+sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
+
+# Sed substitution that converts a w32 file name or path
+# that contains forward slashes, into one that contains
+# (escaped) backslashes. A very naive implementation.
+sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-'\' parameter expansions in output of sed_double_quote_subst that
+# were '\'-ed in input to the same. If an odd number of '\' preceded a
+# '$' in input to sed_double_quote_subst, that '$' was protected from
+# expansion. Since each input '\' is now two '\'s, look for any number
+# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'.
+_G_bs='\\'
+_G_bs2='\\\\'
+_G_bs4='\\\\\\\\'
+_G_dollar='\$'
+sed_double_backslash="\
+ s/$_G_bs4/&\\
+/g
+ s/^$_G_bs2$_G_dollar/$_G_bs&/
+ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
+ s/\n//g"
+
+
+## ----------------- ##
+## Global variables. ##
+## ----------------- ##
+
+# Except for the global variables explicitly listed below, the following
+# functions in the '^func_' namespace, and the '^require_' namespace
+# variables initialised in the 'Resource management' section, sourcing
+# this file will not pollute your global namespace with anything
+# else. There's no portable way to scope variables in Bourne shell
+# though, so actually running these functions will sometimes place
+# results into a variable named after the function, and often use
+# temporary variables in the '^_G_' namespace. If you are careful to
+# avoid using those namespaces casually in your sourcing script, things
+# should continue to work as you expect. And, of course, you can freely
+# overwrite any of the functions or variables defined here before
+# calling anything to customize them.
+
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+# Allow overriding, eg assuming that you follow the convention of
+# putting '$debug_cmd' at the start of all your functions, you can get
+# bash to show function call trace with:
+#
+# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
+debug_cmd=${debug_cmd-":"}
+exit_cmd=:
+
+# By convention, finish your script with:
+#
+# exit $exit_status
+#
+# so that you can set exit_status to non-zero if you want to indicate
+# something went wrong during execution without actually bailing out at
+# the point of failure.
+exit_status=$EXIT_SUCCESS
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath=$0
+
+# The name of this program.
+progname=`$ECHO "$progpath" |$SED "$sed_basename"`
+
+# Make sure we have an absolute progpath for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
+ progdir=`cd "$progdir" && pwd`
+ progpath=$progdir/$progname
+ ;;
+ *)
+ _G_IFS=$IFS
+ IFS=${PATH_SEPARATOR-:}
+ for progdir in $PATH; do
+ IFS=$_G_IFS
+ test -x "$progdir/$progname" && break
+ done
+ IFS=$_G_IFS
+ test -n "$progdir" || progdir=`pwd`
+ progpath=$progdir/$progname
+ ;;
+esac
+
+
+## ----------------- ##
+## Standard options. ##
+## ----------------- ##
+
+# The following options affect the operation of the functions defined
+# below, and should be set appropriately depending on run-time para-
+# meters passed on the command line.
+
+opt_dry_run=false
+opt_quiet=false
+opt_verbose=false
+
+# Categories 'all' and 'none' are always available. Append any others
+# you will pass as the first argument to func_warning from your own
+# code.
+warning_categories=
+
+# By default, display warnings according to 'opt_warning_types'. Set
+# 'warning_func' to ':' to elide all warnings, or func_fatal_error to
+# treat the next displayed warning as a fatal error.
+warning_func=func_warn_and_continue
+
+# Set to 'all' to display all warnings, 'none' to suppress all
+# warnings, or a space delimited list of some subset of
+# 'warning_categories' to display only the listed warnings.
+opt_warning_types=all
+
+
+## -------------------- ##
+## Resource management. ##
+## -------------------- ##
+
+# This section contains definitions for functions that each ensure a
+# particular resource (a file, or a non-empty configuration variable for
+# example) is available, and if appropriate to extract default values
+# from pertinent package files. Call them using their associated
+# 'require_*' variable to ensure that they are executed, at most, once.
+#
+# It's entirely deliberate that calling these functions can set
+# variables that don't obey the namespace limitations obeyed by the rest
+# of this file, in order that that they be as useful as possible to
+# callers.
+
+
+# require_term_colors
+# -------------------
+# Allow display of bold text on terminals that support it.
+require_term_colors=func_require_term_colors
+func_require_term_colors ()
+{
+ $debug_cmd
+
+ test -t 1 && {
+ # COLORTERM and USE_ANSI_COLORS environment variables take
+ # precedence, because most terminfo databases neglect to describe
+ # whether color sequences are supported.
+ test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
+
+ if test 1 = "$USE_ANSI_COLORS"; then
+ # Standard ANSI escape sequences
+ tc_reset='\e[0m'
+ tc_bold='\e[1m'; tc_standout='\e[7m'
+ tc_red='\e[31m'; tc_green='\e[32m'
+ tc_blue='\e[34m'; tc_cyan='\e[36m'
+ else
+ # Otherwise trust the terminfo database after all.
+ test -n "`tput sgr0 2>/dev/null`" && {
+ tc_reset=`tput sgr0`
+ test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
+ tc_standout=$tc_bold
+ test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
+ test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
+ test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
+ test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
+ test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
+ }
+ fi
+ }
+
+ require_term_colors=:
+}
+
+
+## ----------------- ##
+## Function library. ##
+## ----------------- ##
+
+# This section contains a variety of useful functions to call in your
+# scripts. Take note of the portable wrappers for features provided by
+# some modern shells, which will fall back to slower equivalents on
+# less featureful shells.
+
+
+# func_append VAR VALUE
+# ---------------------
+# Append VALUE onto the existing contents of VAR.
+
+ # We should try to minimise forks, especially on Windows where they are
+ # unreasonably slow, so skip the feature probes when bash or zsh are
+ # being used:
+ if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
+ : ${_G_HAVE_ARITH_OP="yes"}
+ : ${_G_HAVE_XSI_OPS="yes"}
+ # The += operator was introduced in bash 3.1
+ case $BASH_VERSION in
+ [12].* | 3.0 | 3.0*) ;;
+ *)
+ : ${_G_HAVE_PLUSEQ_OP="yes"}
+ ;;
+ esac
+ fi
+
+ # _G_HAVE_PLUSEQ_OP
+ # Can be empty, in which case the shell is probed, "yes" if += is
+ # useable or anything else if it does not work.
+ test -z "$_G_HAVE_PLUSEQ_OP" \
+ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
+ && _G_HAVE_PLUSEQ_OP=yes
+
+if test yes = "$_G_HAVE_PLUSEQ_OP"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_append ()
+ {
+ $debug_cmd
+
+ eval "$1+=\$2"
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_append ()
+ {
+ $debug_cmd
+
+ eval "$1=\$$1\$2"
+ }
+fi
+
+
+# func_append_quoted VAR VALUE
+# ----------------------------
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+if test yes = "$_G_HAVE_PLUSEQ_OP"; then
+ eval 'func_append_quoted ()
+ {
+ $debug_cmd
+
+ func_quote_for_eval "$2"
+ eval "$1+=\\ \$func_quote_for_eval_result"
+ }'
+else
+ func_append_quoted ()
+ {
+ $debug_cmd
+
+ func_quote_for_eval "$2"
+ eval "$1=\$$1\\ \$func_quote_for_eval_result"
+ }
+fi
+
+
+# func_append_uniq VAR VALUE
+# --------------------------
+# Append unique VALUE onto the existing contents of VAR, assuming
+# entries are delimited by the first character of VALUE. For example:
+#
+# func_append_uniq options " --another-option option-argument"
+#
+# will only append to $options if " --another-option option-argument "
+# is not already present somewhere in $options already (note spaces at
+# each end implied by leading space in second argument).
+func_append_uniq ()
+{
+ $debug_cmd
+
+ eval _G_current_value='`$ECHO $'$1'`'
+ _G_delim=`expr "$2" : '\(.\)'`
+
+ case $_G_delim$_G_current_value$_G_delim in
+ *"$2$_G_delim"*) ;;
+ *) func_append "$@" ;;
+ esac
+}
+
+
+# func_arith TERM...
+# ------------------
+# Set func_arith_result to the result of evaluating TERMs.
+ test -z "$_G_HAVE_ARITH_OP" \
+ && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
+ && _G_HAVE_ARITH_OP=yes
+
+if test yes = "$_G_HAVE_ARITH_OP"; then
+ eval 'func_arith ()
+ {
+ $debug_cmd
+
+ func_arith_result=$(( $* ))
+ }'
+else
+ func_arith ()
+ {
+ $debug_cmd
+
+ func_arith_result=`expr "$@"`
+ }
+fi
+
+
+# func_basename FILE
+# ------------------
+# Set func_basename_result to FILE with everything up to and including
+# the last / stripped.
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ # If this shell supports suffix pattern removal, then use it to avoid
+ # forking. Hide the definitions single quotes in case the shell chokes
+ # on unsupported syntax...
+ _b='func_basename_result=${1##*/}'
+ _d='case $1 in
+ */*) func_dirname_result=${1%/*}$2 ;;
+ * ) func_dirname_result=$3 ;;
+ esac'
+
+else
+ # ...otherwise fall back to using sed.
+ _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
+ _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"`
+ if test "X$func_dirname_result" = "X$1"; then
+ func_dirname_result=$3
+ else
+ func_append func_dirname_result "$2"
+ fi'
+fi
+
+eval 'func_basename ()
+{
+ $debug_cmd
+
+ '"$_b"'
+}'
+
+
+# func_dirname FILE APPEND NONDIR_REPLACEMENT
+# -------------------------------------------
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+eval 'func_dirname ()
+{
+ $debug_cmd
+
+ '"$_d"'
+}'
+
+
+# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
+# --------------------------------------------------------
+# Perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# For efficiency, we do not delegate to the functions above but instead
+# duplicate the functionality here.
+eval 'func_dirname_and_basename ()
+{
+ $debug_cmd
+
+ '"$_b"'
+ '"$_d"'
+}'
+
+
+# func_echo ARG...
+# ----------------
+# Echo program name prefixed message.
+func_echo ()
+{
+ $debug_cmd
+
+ _G_message=$*
+
+ func_echo_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_IFS
+ $ECHO "$progname: $_G_line"
+ done
+ IFS=$func_echo_IFS
+}
+
+
+# func_echo_all ARG...
+# --------------------
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+
+# func_echo_infix_1 INFIX ARG...
+# ------------------------------
+# Echo program name, followed by INFIX on the first line, with any
+# additional lines not showing INFIX.
+func_echo_infix_1 ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ _G_infix=$1; shift
+ _G_indent=$_G_infix
+ _G_prefix="$progname: $_G_infix: "
+ _G_message=$*
+
+ # Strip color escape sequences before counting printable length
+ for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
+ do
+ test -n "$_G_tc" && {
+ _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
+ _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
+ }
+ done
+ _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes
+
+ func_echo_infix_1_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_infix_1_IFS
+ $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
+ _G_prefix=$_G_indent
+ done
+ IFS=$func_echo_infix_1_IFS
+}
+
+
+# func_error ARG...
+# -----------------
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2
+}
+
+
+# func_fatal_error ARG...
+# -----------------------
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ $debug_cmd
+
+ func_error "$*"
+ exit $EXIT_FAILURE
+}
+
+
+# func_grep EXPRESSION FILENAME
+# -----------------------------
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $debug_cmd
+
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_len STRING
+# ---------------
+# Set func_len_result to the length of STRING. STRING may not
+# start with a hyphen.
+ test -z "$_G_HAVE_XSI_OPS" \
+ && (eval 'x=a/b/c;
+ test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+ && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_len ()
+ {
+ $debug_cmd
+
+ func_len_result=${#1}
+ }'
+else
+ func_len ()
+ {
+ $debug_cmd
+
+ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+ }
+fi
+
+
+# func_mkdir_p DIRECTORY-PATH
+# ---------------------------
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ $debug_cmd
+
+ _G_directory_path=$1
+ _G_dir_list=
+
+ if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
+
+ # Protect directory names starting with '-'
+ case $_G_directory_path in
+ -*) _G_directory_path=./$_G_directory_path ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$_G_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ _G_dir_list=$_G_directory_path:$_G_dir_list
+
+ # If the last portion added has no slash in it, the list is done
+ case $_G_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
+ done
+ _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
+
+ func_mkdir_p_IFS=$IFS; IFS=:
+ for _G_dir in $_G_dir_list; do
+ IFS=$func_mkdir_p_IFS
+ # mkdir can fail with a 'File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$_G_dir" 2>/dev/null || :
+ done
+ IFS=$func_mkdir_p_IFS
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$_G_directory_path" || \
+ func_fatal_error "Failed to create '$1'"
+ fi
+}
+
+
+# func_mktempdir [BASENAME]
+# -------------------------
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, BASENAME is the basename for that directory.
+func_mktempdir ()
+{
+ $debug_cmd
+
+ _G_template=${TMPDIR-/tmp}/${1-$progname}
+
+ if test : = "$opt_dry_run"; then
+ # Return a directory name, but don't create it in dry-run mode
+ _G_tmpdir=$_G_template-$$
+ else
+
+ # If mktemp works, use that first and foremost
+ _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$_G_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ _G_tmpdir=$_G_template-${RANDOM-0}$$
+
+ func_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$_G_tmpdir"
+ umask $func_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$_G_tmpdir" || \
+ func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
+ fi
+
+ $ECHO "$_G_tmpdir"
+}
+
+
+# func_normal_abspath PATH
+# ------------------------
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+func_normal_abspath ()
+{
+ $debug_cmd
+
+ # These SED scripts presuppose an absolute path with a trailing slash.
+ _G_pathcar='s|^/\([^/]*\).*$|\1|'
+ _G_pathcdr='s|^/[^/]*||'
+ _G_removedotparts=':dotsl
+ s|/\./|/|g
+ t dotsl
+ s|/\.$|/|'
+ _G_collapseslashes='s|/\{1,\}|/|g'
+ _G_finalslash='s|/*$|/|'
+
+ # Start from root dir and reassemble the path.
+ func_normal_abspath_result=
+ func_normal_abspath_tpath=$1
+ func_normal_abspath_altnamespace=
+ case $func_normal_abspath_tpath in
+ "")
+ # Empty path, that just means $cwd.
+ func_stripname '' '/' "`pwd`"
+ func_normal_abspath_result=$func_stripname_result
+ return
+ ;;
+ # The next three entries are used to spot a run of precisely
+ # two leading slashes without using negated character classes;
+ # we take advantage of case's first-match behaviour.
+ ///*)
+ # Unusual form of absolute path, do nothing.
+ ;;
+ //*)
+ # Not necessarily an ordinary path; POSIX reserves leading '//'
+ # and for example Cygwin uses it to access remote file shares
+ # over CIFS/SMB, so we conserve a leading double slash if found.
+ func_normal_abspath_altnamespace=/
+ ;;
+ /*)
+ # Absolute path, do nothing.
+ ;;
+ *)
+ # Relative path, prepend $cwd.
+ func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+ ;;
+ esac
+
+ # Cancel out all the simple stuff to save iterations. We also want
+ # the path to end with a slash for ease of parsing, so make sure
+ # there is one (and only one) here.
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
+ while :; do
+ # Processed it all yet?
+ if test / = "$func_normal_abspath_tpath"; then
+ # If we ascended to the root using ".." the result may be empty now.
+ if test -z "$func_normal_abspath_result"; then
+ func_normal_abspath_result=/
+ fi
+ break
+ fi
+ func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_pathcar"`
+ func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+ -e "$_G_pathcdr"`
+ # Figure out what to do with it
+ case $func_normal_abspath_tcomponent in
+ "")
+ # Trailing empty path component, ignore it.
+ ;;
+ ..)
+ # Parent dir; strip last assembled component from result.
+ func_dirname "$func_normal_abspath_result"
+ func_normal_abspath_result=$func_dirname_result
+ ;;
+ *)
+ # Actual path component, append it.
+ func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
+ ;;
+ esac
+ done
+ # Restore leading double-slash if one was found on entry.
+ func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+
+# func_notquiet ARG...
+# --------------------
+# Echo program name prefixed message only when not in quiet mode.
+func_notquiet ()
+{
+ $debug_cmd
+
+ $opt_quiet || func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+
+# func_relative_path SRCDIR DSTDIR
+# --------------------------------
+# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
+func_relative_path ()
+{
+ $debug_cmd
+
+ func_relative_path_result=
+ func_normal_abspath "$1"
+ func_relative_path_tlibdir=$func_normal_abspath_result
+ func_normal_abspath "$2"
+ func_relative_path_tbindir=$func_normal_abspath_result
+
+ # Ascend the tree starting from libdir
+ while :; do
+ # check if we have found a prefix of bindir
+ case $func_relative_path_tbindir in
+ $func_relative_path_tlibdir)
+ # found an exact match
+ func_relative_path_tcancelled=
+ break
+ ;;
+ $func_relative_path_tlibdir*)
+ # found a matching prefix
+ func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+ func_relative_path_tcancelled=$func_stripname_result
+ if test -z "$func_relative_path_result"; then
+ func_relative_path_result=.
+ fi
+ break
+ ;;
+ *)
+ func_dirname $func_relative_path_tlibdir
+ func_relative_path_tlibdir=$func_dirname_result
+ if test -z "$func_relative_path_tlibdir"; then
+ # Have to descend all the way to the root!
+ func_relative_path_result=../$func_relative_path_result
+ func_relative_path_tcancelled=$func_relative_path_tbindir
+ break
+ fi
+ func_relative_path_result=../$func_relative_path_result
+ ;;
+ esac
+ done
+
+ # Now calculate path; take care to avoid doubling-up slashes.
+ func_stripname '' '/' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ func_stripname '/' '/' "$func_relative_path_tcancelled"
+ if test -n "$func_stripname_result"; then
+ func_append func_relative_path_result "/$func_stripname_result"
+ fi
+
+ # Normalisation. If bindir is libdir, return '.' else relative path.
+ if test -n "$func_relative_path_result"; then
+ func_stripname './' '' "$func_relative_path_result"
+ func_relative_path_result=$func_stripname_result
+ fi
+
+ test -n "$func_relative_path_result" || func_relative_path_result=.
+
+ :
+}
+
+
+# func_quote_for_eval ARG...
+# --------------------------
+# Aesthetically quote ARGs to be evaled later.
+# This function returns two values:
+# i) func_quote_for_eval_result
+# double-quoted, suitable for a subsequent eval
+# ii) func_quote_for_eval_unquoted_result
+# has all characters that are still active within double
+# quotes backslashified.
+func_quote_for_eval ()
+{
+ $debug_cmd
+
+ func_quote_for_eval_unquoted_result=
+ func_quote_for_eval_result=
+ while test 0 -lt $#; do
+ case $1 in
+ *[\\\`\"\$]*)
+ _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
+ *)
+ _G_unquoted_arg=$1 ;;
+ esac
+ if test -n "$func_quote_for_eval_unquoted_result"; then
+ func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
+ else
+ func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+ fi
+
+ case $_G_unquoted_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and variable expansion
+ # for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_quoted_arg=\"$_G_unquoted_arg\"
+ ;;
+ *)
+ _G_quoted_arg=$_G_unquoted_arg
+ ;;
+ esac
+
+ if test -n "$func_quote_for_eval_result"; then
+ func_append func_quote_for_eval_result " $_G_quoted_arg"
+ else
+ func_append func_quote_for_eval_result "$_G_quoted_arg"
+ fi
+ shift
+ done
+}
+
+
+# func_quote_for_expand ARG
+# -------------------------
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ $debug_cmd
+
+ case $1 in
+ *[\\\`\"]*)
+ _G_arg=`$ECHO "$1" | $SED \
+ -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ _G_arg=$1 ;;
+ esac
+
+ case $_G_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ _G_arg=\"$_G_arg\"
+ ;;
+ esac
+
+ func_quote_for_expand_result=$_G_arg
+}
+
+
+# func_stripname PREFIX SUFFIX NAME
+# ---------------------------------
+# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_stripname ()
+ {
+ $debug_cmd
+
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary variable first.
+ func_stripname_result=$3
+ func_stripname_result=${func_stripname_result#"$1"}
+ func_stripname_result=${func_stripname_result%"$2"}
+ }'
+else
+ func_stripname ()
+ {
+ $debug_cmd
+
+ case $2 in
+ .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
+ *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
+ esac
+ }
+fi
+
+
+# func_show_eval CMD [FAIL_EXP]
+# -----------------------------
+# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ $debug_cmd
+
+ _G_cmd=$1
+ _G_fail_exp=${2-':'}
+
+ func_quote_for_expand "$_G_cmd"
+ eval "func_notquiet $func_quote_for_expand_result"
+
+ $opt_dry_run || {
+ eval "$_G_cmd"
+ _G_status=$?
+ if test 0 -ne "$_G_status"; then
+ eval "(exit $_G_status); $_G_fail_exp"
+ fi
+ }
+}
+
+
+# func_show_eval_locale CMD [FAIL_EXP]
+# ------------------------------------
+# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ $debug_cmd
+
+ _G_cmd=$1
+ _G_fail_exp=${2-':'}
+
+ $opt_quiet || {
+ func_quote_for_expand "$_G_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ $opt_dry_run || {
+ eval "$_G_user_locale
+ $_G_cmd"
+ _G_status=$?
+ eval "$_G_safe_locale"
+ if test 0 -ne "$_G_status"; then
+ eval "(exit $_G_status); $_G_fail_exp"
+ fi
+ }
+}
+
+
+# func_tr_sh
+# ----------
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result. All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+ $debug_cmd
+
+ case $1 in
+ [0-9]* | *[!a-zA-Z0-9_]*)
+ func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
+ ;;
+ * )
+ func_tr_sh_result=$1
+ ;;
+ esac
+}
+
+
+# func_verbose ARG...
+# -------------------
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $debug_cmd
+
+ $opt_verbose && func_echo "$*"
+
+ :
+}
+
+
+# func_warn_and_continue ARG...
+# -----------------------------
+# Echo program name prefixed warning message to standard error.
+func_warn_and_continue ()
+{
+ $debug_cmd
+
+ $require_term_colors
+
+ func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
+}
+
+
+# func_warning CATEGORY ARG...
+# ----------------------------
+# Echo program name prefixed warning message to standard error. Warning
+# messages can be filtered according to CATEGORY, where this function
+# elides messages where CATEGORY is not listed in the global variable
+# 'opt_warning_types'.
+func_warning ()
+{
+ $debug_cmd
+
+ # CATEGORY must be in the warning_categories list!
+ case " $warning_categories " in
+ *" $1 "*) ;;
+ *) func_internal_error "invalid warning category '$1'" ;;
+ esac
+
+ _G_category=$1
+ shift
+
+ case " $opt_warning_types " in
+ *" $_G_category "*) $warning_func ${1+"$@"} ;;
+ esac
+}
+
+
+# func_sort_ver VER1 VER2
+# -----------------------
+# 'sort -V' is not generally available.
+# Note this deviates from the version comparison in automake
+# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
+# but this should suffice as we won't be specifying old
+# version formats or redundant trailing .0 in bootstrap.conf.
+# If we did want full compatibility then we should probably
+# use m4_version_compare from autoconf.
+func_sort_ver ()
+{
+ $debug_cmd
+
+ printf '%s\n%s\n' "$1" "$2" \
+ | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
+}
+
+# func_lt_ver PREV CURR
+# ---------------------
+# Return true if PREV and CURR are in the correct order according to
+# func_sort_ver, otherwise false. Use it like this:
+#
+# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
+func_lt_ver ()
+{
+ $debug_cmd
+
+ test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+#! /bin/sh
+
+# Set a version string for this script.
+scriptversion=2014-01-07.03; # UTC
+
+# A portable, pluggable option parser for Bourne shell.
+# Written by Gary V. Vaughan, 2010
+
+# Copyright (C) 2010-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
+
+
+## ------ ##
+## Usage. ##
+## ------ ##
+
+# This file is a library for parsing options in your shell scripts along
+# with assorted other useful supporting features that you can make use
+# of too.
+#
+# For the simplest scripts you might need only:
+#
+# #!/bin/sh
+# . relative/path/to/funclib.sh
+# . relative/path/to/options-parser
+# scriptversion=1.0
+# func_options ${1+"$@"}
+# eval set dummy "$func_options_result"; shift
+# ...rest of your script...
+#
+# In order for the '--version' option to work, you will need to have a
+# suitably formatted comment like the one at the top of this file
+# starting with '# Written by ' and ending with '# warranty; '.
+#
+# For '-h' and '--help' to work, you will also need a one line
+# description of your script's purpose in a comment directly above the
+# '# Written by ' line, like the one at the top of this file.
+#
+# The default options also support '--debug', which will turn on shell
+# execution tracing (see the comment above debug_cmd below for another
+# use), and '--verbose' and the func_verbose function to allow your script
+# to display verbose messages only when your user has specified
+# '--verbose'.
+#
+# After sourcing this file, you can plug processing for additional
+# options by amending the variables from the 'Configuration' section
+# below, and following the instructions in the 'Option parsing'
+# section further down.
+
+## -------------- ##
+## Configuration. ##
+## -------------- ##
+
+# You should override these variables in your script after sourcing this
+# file so that they reflect the customisations you have added to the
+# option parser.
+
+# The usage line for option parsing errors and the start of '-h' and
+# '--help' output messages. You can embed shell variables for delayed
+# expansion at the time the message is displayed, but you will need to
+# quote other shell meta-characters carefully to prevent them being
+# expanded when the contents are evaled.
+usage='$progpath [OPTION]...'
+
+# Short help message in response to '-h' and '--help'. Add to this or
+# override it after sourcing this library to reflect the full set of
+# options your script accepts.
+usage_message="\
+ --debug enable verbose shell tracing
+ -W, --warnings=CATEGORY
+ report the warnings falling in CATEGORY [all]
+ -v, --verbose verbosely report processing
+ --version print version information and exit
+ -h, --help print short or long help message and exit
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+long_help_message="
+Warning categories include:
+ 'all' show all warnings
+ 'none' turn off all the warnings
+ 'error' warnings are treated as fatal errors"
+
+# Help message printed before fatal option parsing errors.
+fatal_help="Try '\$progname --help' for more information."
+
+
+
+## ------------------------- ##
+## Hook function management. ##
+## ------------------------- ##
+
+# This section contains functions for adding, removing, and running hooks
+# to the main code. A hook is just a named list of of function, that can
+# be run in order later on.
+
+# func_hookable FUNC_NAME
+# -----------------------
+# Declare that FUNC_NAME will run hooks added with
+# 'func_add_hook FUNC_NAME ...'.
+func_hookable ()
+{
+ $debug_cmd
+
+ func_append hookable_fns " $1"
+}
+
+
+# func_add_hook FUNC_NAME HOOK_FUNC
+# ---------------------------------
+# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must
+# first have been declared "hookable" by a call to 'func_hookable'.
+func_add_hook ()
+{
+ $debug_cmd
+
+ case " $hookable_fns " in
+ *" $1 "*) ;;
+ *) func_fatal_error "'$1' does not accept hook functions." ;;
+ esac
+
+ eval func_append ${1}_hooks '" $2"'
+}
+
+
+# func_remove_hook FUNC_NAME HOOK_FUNC
+# ------------------------------------
+# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
+func_remove_hook ()
+{
+ $debug_cmd
+
+ eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
+}
+
+
+# func_run_hooks FUNC_NAME [ARG]...
+# ---------------------------------
+# Run all hook functions registered to FUNC_NAME.
+# It is assumed that the list of hook functions contains nothing more
+# than a whitespace-delimited list of legal shell function names, and
+# no effort is wasted trying to catch shell meta-characters or preserve
+# whitespace.
+func_run_hooks ()
+{
+ $debug_cmd
+
+ case " $hookable_fns " in
+ *" $1 "*) ;;
+ *) func_fatal_error "'$1' does not support hook funcions.n" ;;
+ esac
+
+ eval _G_hook_fns=\$$1_hooks; shift
+
+ for _G_hook in $_G_hook_fns; do
+ eval $_G_hook '"$@"'
+
+ # store returned options list back into positional
+ # parameters for next 'cmd' execution.
+ eval _G_hook_result=\$${_G_hook}_result
+ eval set dummy "$_G_hook_result"; shift
+ done
+
+ func_quote_for_eval ${1+"$@"}
+ func_run_hooks_result=$func_quote_for_eval_result
+}
+
+
+
+## --------------- ##
+## Option parsing. ##
+## --------------- ##
+
+# In order to add your own option parsing hooks, you must accept the
+# full positional parameter list in your hook function, remove any
+# options that you action, and then pass back the remaining unprocessed
+# options in '<hooked_function_name>_result', escaped suitably for
+# 'eval'. Like this:
+#
+# my_options_prep ()
+# {
+# $debug_cmd
+#
+# # Extend the existing usage message.
+# usage_message=$usage_message'
+# -s, --silent don'\''t print informational messages
+# '
+#
+# func_quote_for_eval ${1+"$@"}
+# my_options_prep_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_options_prep my_options_prep
+#
+#
+# my_silent_option ()
+# {
+# $debug_cmd
+#
+# # Note that for efficiency, we parse as many options as we can
+# # recognise in a loop before passing the remainder back to the
+# # caller on the first unrecognised argument we encounter.
+# while test $# -gt 0; do
+# opt=$1; shift
+# case $opt in
+# --silent|-s) opt_silent=: ;;
+# # Separate non-argument short options:
+# -s*) func_split_short_opt "$_G_opt"
+# set dummy "$func_split_short_opt_name" \
+# "-$func_split_short_opt_arg" ${1+"$@"}
+# shift
+# ;;
+# *) set dummy "$_G_opt" "$*"; shift; break ;;
+# esac
+# done
+#
+# func_quote_for_eval ${1+"$@"}
+# my_silent_option_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_parse_options my_silent_option
+#
+#
+# my_option_validation ()
+# {
+# $debug_cmd
+#
+# $opt_silent && $opt_verbose && func_fatal_help "\
+# '--silent' and '--verbose' options are mutually exclusive."
+#
+# func_quote_for_eval ${1+"$@"}
+# my_option_validation_result=$func_quote_for_eval_result
+# }
+# func_add_hook func_validate_options my_option_validation
+#
+# You'll alse need to manually amend $usage_message to reflect the extra
+# options you parse. It's preferable to append if you can, so that
+# multiple option parsing hooks can be added safely.
+
+
+# func_options [ARG]...
+# ---------------------
+# All the functions called inside func_options are hookable. See the
+# individual implementations for details.
+func_hookable func_options
+func_options ()
+{
+ $debug_cmd
+
+ func_options_prep ${1+"$@"}
+ eval func_parse_options \
+ ${func_options_prep_result+"$func_options_prep_result"}
+ eval func_validate_options \
+ ${func_parse_options_result+"$func_parse_options_result"}
+
+ eval func_run_hooks func_options \
+ ${func_validate_options_result+"$func_validate_options_result"}
+
+ # save modified positional parameters for caller
+ func_options_result=$func_run_hooks_result
+}
+
+
+# func_options_prep [ARG]...
+# --------------------------
+# All initialisations required before starting the option parse loop.
+# Note that when calling hook functions, we pass through the list of
+# positional parameters. If a hook function modifies that list, and
+# needs to propogate that back to rest of this script, then the complete
+# modified list must be put in 'func_run_hooks_result' before
+# returning.
+func_hookable func_options_prep
+func_options_prep ()
+{
+ $debug_cmd
+
+ # Option defaults:
+ opt_verbose=false
+ opt_warning_types=
+
+ func_run_hooks func_options_prep ${1+"$@"}
+
+ # save modified positional parameters for caller
+ func_options_prep_result=$func_run_hooks_result
+}
+
+
+# func_parse_options [ARG]...
+# ---------------------------
+# The main option parsing loop.
+func_hookable func_parse_options
+func_parse_options ()
+{
+ $debug_cmd
+
+ func_parse_options_result=
+
+ # this just eases exit handling
+ while test $# -gt 0; do
+ # Defer to hook functions for initial option parsing, so they
+ # get priority in the event of reusing an option name.
+ func_run_hooks func_parse_options ${1+"$@"}
+
+ # Adjust func_parse_options positional parameters to match
+ eval set dummy "$func_run_hooks_result"; shift
+
+ # Break out of the loop if we already parsed every option.
+ test $# -gt 0 || break
+
+ _G_opt=$1
+ shift
+ case $_G_opt in
+ --debug|-x) debug_cmd='set -x'
+ func_echo "enabling shell trace mode"
+ $debug_cmd
+ ;;
+
+ --no-warnings|--no-warning|--no-warn)
+ set dummy --warnings none ${1+"$@"}
+ shift
+ ;;
+
+ --warnings|--warning|-W)
+ test $# = 0 && func_missing_arg $_G_opt && break
+ case " $warning_categories $1" in
+ *" $1 "*)
+ # trailing space prevents matching last $1 above
+ func_append_uniq opt_warning_types " $1"
+ ;;
+ *all)
+ opt_warning_types=$warning_categories
+ ;;
+ *none)
+ opt_warning_types=none
+ warning_func=:
+ ;;
+ *error)
+ opt_warning_types=$warning_categories
+ warning_func=func_fatal_error
+ ;;
+ *)
+ func_fatal_error \
+ "unsupported warning category: '$1'"
+ ;;
+ esac
+ shift
+ ;;
+
+ --verbose|-v) opt_verbose=: ;;
+ --version) func_version ;;
+ -\?|-h) func_usage ;;
+ --help) func_help ;;
+
+ # Separate optargs to long options (plugins may need this):
+ --*=*) func_split_equals "$_G_opt"
+ set dummy "$func_split_equals_lhs" \
+ "$func_split_equals_rhs" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate optargs to short options:
+ -W*)
+ func_split_short_opt "$_G_opt"
+ set dummy "$func_split_short_opt_name" \
+ "$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ # Separate non-argument short options:
+ -\?*|-h*|-v*|-x*)
+ func_split_short_opt "$_G_opt"
+ set dummy "$func_split_short_opt_name" \
+ "-$func_split_short_opt_arg" ${1+"$@"}
+ shift
+ ;;
+
+ --) break ;;
+ -*) func_fatal_help "unrecognised option: '$_G_opt'" ;;
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ func_parse_options_result=$func_quote_for_eval_result
+}
+
+
+# func_validate_options [ARG]...
+# ------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+func_hookable func_validate_options
+func_validate_options ()
+{
+ $debug_cmd
+
+ # Display all warnings if -W was not given.
+ test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
+
+ func_run_hooks func_validate_options ${1+"$@"}
+
+ # Bail if the options were screwed!
+ $exit_cmd $EXIT_FAILURE
+
+ # save modified positional parameters for caller
+ func_validate_options_result=$func_run_hooks_result
+}
+
+
+
+## ----------------- ##
+## Helper functions. ##
+## ----------------- ##
+
+# This section contains the helper functions used by the rest of the
+# hookable option parser framework in ascii-betical order.
+
+
+# func_fatal_help ARG...
+# ----------------------
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ $debug_cmd
+
+ eval \$ECHO \""Usage: $usage"\"
+ eval \$ECHO \""$fatal_help"\"
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+
+# func_help
+# ---------
+# Echo long help message to standard output and exit.
+func_help ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "$long_help_message"
+ exit 0
+}
+
+
+# func_missing_arg ARGNAME
+# ------------------------
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ $debug_cmd
+
+ func_error "Missing argument for '$1'."
+ exit_cmd=exit
+}
+
+
+# func_split_equals STRING
+# ------------------------
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
+# splitting STRING at the '=' sign.
+test -z "$_G_HAVE_XSI_OPS" \
+ && (eval 'x=a/b/c;
+ test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
+ && _G_HAVE_XSI_OPS=yes
+
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_split_equals ()
+ {
+ $debug_cmd
+
+ func_split_equals_lhs=${1%%=*}
+ func_split_equals_rhs=${1#*=}
+ test "x$func_split_equals_lhs" = "x$1" \
+ && func_split_equals_rhs=
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_split_equals ()
+ {
+ $debug_cmd
+
+ func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
+ func_split_equals_rhs=
+ test "x$func_split_equals_lhs" = "x$1" \
+ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
+ }
+fi #func_split_equals
+
+
+# func_split_short_opt SHORTOPT
+# -----------------------------
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+if test yes = "$_G_HAVE_XSI_OPS"
+then
+ # This is an XSI compatible shell, allowing a faster implementation...
+ eval 'func_split_short_opt ()
+ {
+ $debug_cmd
+
+ func_split_short_opt_arg=${1#??}
+ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
+ }'
+else
+ # ...otherwise fall back to using expr, which is often a shell builtin.
+ func_split_short_opt ()
+ {
+ $debug_cmd
+
+ func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
+ func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
+ }
+fi #func_split_short_opt
+
+
+# func_usage
+# ----------
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
+ exit 0
+}
+
+
+# func_usage_message
+# ------------------
+# Echo short help message to standard output.
+func_usage_message ()
+{
+ $debug_cmd
+
+ eval \$ECHO \""Usage: $usage"\"
+ echo
+ $SED -n 's|^# ||
+ /^Written by/{
+ x;p;x
+ }
+ h
+ /^Written by/q' < "$progpath"
+ echo
+ eval \$ECHO \""$usage_message"\"
+}
+
+
+# func_version
+# ------------
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $debug_cmd
+
+ printf '%s\n' "$progname $scriptversion"
+ $SED -n '
+ /(C)/!b go
+ :more
+ /\./!{
+ N
+ s|\n# | |
+ b more
+ }
+ :go
+ /^# Written by /,/# warranty; / {
+ s|^# ||
+ s|^# *$||
+ s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+ p
+ }
+ /^# Written by / {
+ s|^# ||
+ p
+ }
+ /^warranty; /q' < "$progpath"
+
+ exit $?
+}
+
+
+# Local variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-time-zone: "UTC"
+# End:
+
+# Set a version string.
+scriptversion='(GNU libtool) 2.4.6'
+
+
+# func_echo ARG...
+# ----------------
+# Libtool also displays the current mode in messages, so override
+# funclib.sh func_echo with this custom definition.
+func_echo ()
+{
+ $debug_cmd
+
+ _G_message=$*
+
+ func_echo_IFS=$IFS
+ IFS=$nl
+ for _G_line in $_G_message; do
+ IFS=$func_echo_IFS
+ $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line"
+ done
+ IFS=$func_echo_IFS
+}
+
+
+# func_warning ARG...
+# -------------------
+# Libtool warnings are not categorized, so override funclib.sh
+# func_warning with this simpler definition.
+func_warning ()
+{
+ $debug_cmd
+
+ $warning_func ${1+"$@"}
+}
+
+
+## ---------------- ##
+## Options parsing. ##
+## ---------------- ##
+
+# Hook in the functions to make sure our own options are parsed during
+# the option parsing loop.
+
+usage='$progpath [OPTION]... [MODE-ARG]...'
+
+# Short help message in response to '-h'.
+usage_message="Options:
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+ -n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --mode=MODE use operation mode MODE
+ --no-warnings equivalent to '-Wnone'
+ --preserve-dup-deps don't remove duplicate dependency libraries
+ --quiet, --silent don't print informational messages
+ --tag=TAG use configuration variables from tag TAG
+ -v, --verbose print more informational messages than default
+ --version print version information
+ -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all]
+ -h, --help, --help-all print short, long, or detailed help message
+"
+
+# Additional text appended to 'usage_message' in response to '--help'.
+func_help ()
+{
+ $debug_cmd
+
+ func_usage_message
+ $ECHO "$long_help_message
+
+MODE must be one of the following:
+
+ clean remove files from the build directory
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. When passed as first option,
+'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that.
+Try '$progname --help --mode=MODE' for a more detailed description of MODE.
+
+When reporting a bug, please describe a test case to reproduce it and
+include the following information:
+
+ host-triplet: $host
+ shell: $SHELL
+ compiler: $LTCC
+ compiler flags: $LTCFLAGS
+ linker: $LD (gnu? $with_gnu_ld)
+ version: $progname (GNU libtool) 2.4.6
+ automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
+ autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
+
+Report bugs to <bug-libtool@gnu.org>.
+GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
+ exit 0
+}
+
+
+# func_lo2o OBJECT-NAME
+# ---------------------
+# Transform OBJECT-NAME from a '.lo' suffix to the platform specific
+# object suffix.
+
+lo2o=s/\\.lo\$/.$objext/
+o2lo=s/\\.$objext\$/.lo/
+
+if test yes = "$_G_HAVE_XSI_OPS"; then
+ eval 'func_lo2o ()
+ {
+ case $1 in
+ *.lo) func_lo2o_result=${1%.lo}.$objext ;;
+ * ) func_lo2o_result=$1 ;;
+ esac
+ }'
+
+ # func_xform LIBOBJ-OR-SOURCE
+ # ---------------------------
+ # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise)
+ # suffix to a '.lo' libtool-object suffix.
+ eval 'func_xform ()
+ {
+ func_xform_result=${1%.*}.lo
+ }'
+else
+ # ...otherwise fall back to using sed.
+ func_lo2o ()
+ {
+ func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"`
+ }
+
+ func_xform ()
+ {
+ func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'`
+ }
+fi
+
+
+# func_fatal_configuration ARG...
+# -------------------------------
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func__fatal_error ${1+"$@"} \
+ "See the $PACKAGE documentation for more information." \
+ "Fatal configuration error."
+}
+
+
+# func_config
+# -----------
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+
+# func_features
+# -------------
+# Display the features supported by this script.
+func_features ()
+{
+ echo "host: $host"
+ if test yes = "$build_libtool_libs"; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test yes = "$build_old_libs"; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+
+ exit $?
+}
+
+
+# func_enable_tag TAGNAME
+# -----------------------
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname=$1
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf=/$re_begincf/,/$re_endcf/p
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+
+# func_check_version_match
+# ------------------------
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+# libtool_options_prep [ARG]...
+# -----------------------------
+# Preparation for options parsed by libtool.
+libtool_options_prep ()
+{
+ $debug_mode
+
+ # Option defaults:
+ opt_config=false
+ opt_dlopen=
+ opt_dry_run=false
+ opt_help=false
+ opt_mode=
+ opt_preserve_dup_deps=false
+ opt_quiet=false
+
+ nonopt=
+ preserve_args=
+
+ # Shorthand for --mode=foo, only valid as the first argument
+ case $1 in
+ clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+ compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+ execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+ finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+ link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+ uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+ esac
+
+ # Pass back the list of options.
+ func_quote_for_eval ${1+"$@"}
+ libtool_options_prep_result=$func_quote_for_eval_result
+}
+func_add_hook func_options_prep libtool_options_prep
+
+
+# libtool_parse_options [ARG]...
+# ---------------------------------
+# Provide handling for libtool specific options.
+libtool_parse_options ()
+{
+ $debug_cmd
+
+ # Perform our own loop to consume as many options as possible in
+ # each iteration.
+ while test $# -gt 0; do
+ _G_opt=$1
+ shift
+ case $_G_opt in
+ --dry-run|--dryrun|-n)
+ opt_dry_run=:
+ ;;
+
+ --config) func_config ;;
+
+ --dlopen|-dlopen)
+ opt_dlopen="${opt_dlopen+$opt_dlopen
+}$1"
+ shift
+ ;;
+
+ --preserve-dup-deps)
+ opt_preserve_dup_deps=: ;;
+
+ --features) func_features ;;
+
+ --finish) set dummy --mode finish ${1+"$@"}; shift ;;
+
+ --help) opt_help=: ;;
+
+ --help-all) opt_help=': help-all' ;;
+
+ --mode) test $# = 0 && func_missing_arg $_G_opt && break
+ opt_mode=$1
+ case $1 in
+ # Valid mode arguments:
+ clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $_G_opt"
+ exit_cmd=exit
+ break
+ ;;
+ esac
+ shift
+ ;;
+
+ --no-silent|--no-quiet)
+ opt_quiet=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --no-warnings|--no-warning|--no-warn)
+ opt_warning=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --no-verbose)
+ opt_verbose=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --silent|--quiet)
+ opt_quiet=:
+ opt_verbose=false
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ --tag) test $# = 0 && func_missing_arg $_G_opt && break
+ opt_tag=$1
+ func_append preserve_args " $_G_opt $1"
+ func_enable_tag "$1"
+ shift
+ ;;
+
+ --verbose|-v) opt_quiet=false
+ opt_verbose=:
+ func_append preserve_args " $_G_opt"
+ ;;
+
+ # An option not handled by this hook function:
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+ esac
+ done
+
+
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ libtool_parse_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_parse_options libtool_parse_options
+
+
+
+# libtool_validate_options [ARG]...
+# ---------------------------------
+# Perform any sanity checks on option settings and/or unconsumed
+# arguments.
+libtool_validate_options ()
+{
+ # save first non-option argument
+ if test 0 -lt $#; then
+ nonopt=$1
+ shift
+ fi
+
+ # preserve --debug
+ test : = "$debug_cmd" || func_append preserve_args " --debug"
+
+ case $host in
+ # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
+ # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
+ *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+ ;;
+ esac
+
+ $opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ test yes != "$build_libtool_libs" \
+ && test yes != "$build_old_libs" \
+ && func_fatal_configuration "not configured to build any kind of library"
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$opt_dlopen" && test execute != "$opt_mode"; then
+ func_error "unrecognized option '-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help=$help
+ help="Try '$progname --help --mode=$opt_mode' for more information."
+ }
+
+ # Pass back the unparsed argument list
+ func_quote_for_eval ${1+"$@"}
+ libtool_validate_options_result=$func_quote_for_eval_result
+}
+func_add_hook func_validate_options libtool_validate_options
+
+
+# Process options as early as possible so that --help and --version
+# can return quickly.
+func_options ${1+"$@"}
+eval set dummy "$func_options_result"; shift
+
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+magic='%%%MAGIC variable%%%'
+magic_exe='%%%MAGIC EXE variable%%%'
+
+# Global variables.
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# func_generated_by_libtool
+# True iff stdin has been generated by Libtool. This function is only
+# a basic sanity check; it will hardly flush out determined imposters.
+func_generated_by_libtool_p ()
+{
+ $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool '.la' library or '.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if 'file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case $lalib_p_line in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test yes = "$lalib_p"
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ test -f "$1" &&
+ $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $debug_cmd
+
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$sp$nl
+ eval cmd=\"$cmd\"
+ IFS=$save_ifs
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# 'FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $debug_cmd
+
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot. Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+ func_resolve_sysroot_result=$1
+ case $func_resolve_sysroot_result in
+ =*)
+ func_stripname '=' '' "$func_resolve_sysroot_result"
+ func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+ ;;
+ esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+ case $lt_sysroot:$1 in
+ ?*:"$lt_sysroot"*)
+ func_stripname "$lt_sysroot" '' "$1"
+ func_replace_sysroot_result='='$func_stripname_result
+ ;;
+ *)
+ # Including no sysroot.
+ func_replace_sysroot_result=$1
+ ;;
+ esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $debug_cmd
+
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_append_quoted CC_quoted "$arg"
+ done
+ CC_expanded=`func_echo_all $CC`
+ CC_quoted_expanded=`func_echo_all $CC_quoted`
+ case "$@ " in
+ " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with '--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=$1
+ if test yes = "$build_libtool_libs"; then
+ write_lobj=\'$2\'
+ else
+ write_lobj=none
+ fi
+
+ if test yes = "$build_old_libs"; then
+ write_oldobj=\'$3\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "$write_libobj"
+ }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+ $debug_cmd
+
+ func_convert_core_file_wine_to_w32_result=$1
+ if test -n "$1"; then
+ # Unfortunately, winepath does not exit with a non-zero error code, so we
+ # are forced to check the contents of stdout. On the other hand, if the
+ # command is not found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both error code of
+ # zero AND non-empty stdout, which explains the odd construction:
+ func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then
+ func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+ $SED -e "$sed_naive_backslashify"`
+ else
+ func_convert_core_file_wine_to_w32_result=
+ fi
+ fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+ $debug_cmd
+
+ # unfortunately, winepath doesn't convert paths, only file names
+ func_convert_core_path_wine_to_w32_result=
+ if test -n "$1"; then
+ oldIFS=$IFS
+ IFS=:
+ for func_convert_core_path_wine_to_w32_f in $1; do
+ IFS=$oldIFS
+ func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+ if test -n "$func_convert_core_file_wine_to_w32_result"; then
+ if test -z "$func_convert_core_path_wine_to_w32_result"; then
+ func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result
+ else
+ func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+ fi
+ fi
+ done
+ IFS=$oldIFS
+ fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+ $debug_cmd
+
+ if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+ func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+ if test "$?" -ne 0; then
+ # on failure, ensure result is empty
+ func_cygpath_result=
+ fi
+ else
+ func_cygpath_result=
+ func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'"
+ fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format. Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+ $debug_cmd
+
+ # awkward: cmd appends spaces to result
+ func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+ $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+ $debug_cmd
+
+ if test -z "$2" && test -n "$1"; then
+ func_error "Could not determine host file name corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_file_result=$1
+ fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+ $debug_cmd
+
+ if test -z "$4" && test -n "$3"; then
+ func_error "Could not determine the host path corresponding to"
+ func_error " '$3'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This is a deliberately simplistic "conversion" and
+ # should not be "improved". See libtool.info.
+ if test "x$1" != "x$2"; then
+ lt_replace_pathsep_chars="s|$1|$2|g"
+ func_to_host_path_result=`echo "$3" |
+ $SED -e "$lt_replace_pathsep_chars"`
+ else
+ func_to_host_path_result=$3
+ fi
+ fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+ $debug_cmd
+
+ case $4 in
+ $1 ) func_to_host_path_result=$3$func_to_host_path_result
+ ;;
+ esac
+ case $4 in
+ $2 ) func_append func_to_host_path_result "$3"
+ ;;
+ esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via '$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+ $debug_cmd
+
+ $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result. If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+ $debug_cmd
+
+ case ,$2, in
+ *,"$to_tool_file_cmd",*)
+ func_to_tool_file_result=$1
+ ;;
+ *)
+ $to_tool_file_cmd "$1"
+ func_to_tool_file_result=$func_to_host_file_result
+ ;;
+ esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+ func_to_host_file_result=$1
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_to_host_file_result=$func_convert_core_msys_to_w32_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+ # LT_CYGPATH in this case.
+ func_to_host_file_result=`cygpath -m "$1"`
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format. Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_file_wine_to_w32 "$1"
+ func_to_host_file_result=$func_convert_core_file_wine_to_w32_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ func_convert_core_msys_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_msys_to_w32_result"
+ func_to_host_file_result=$func_cygpath_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set. Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_file_result=$1
+ if test -n "$1"; then
+ # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+ func_convert_core_file_wine_to_w32 "$1"
+ func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+ func_to_host_file_result=$func_cygpath_result
+ fi
+ func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via '$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format. If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+# file name conversion function : func_convert_file_X_to_Y ()
+# path conversion function : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same. If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+ $debug_cmd
+
+ if test -z "$to_host_path_cmd"; then
+ func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+ to_host_path_cmd=func_convert_path_$func_stripname_result
+ fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+ $debug_cmd
+
+ func_init_to_host_path_cmd
+ $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+ func_to_host_path_result=$1
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper. Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from ARG. MSYS
+ # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+ # and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result=$func_convert_core_msys_to_w32_result
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format. Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format. Requires a wine environment and
+# a working winepath. Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_to_host_path_result=$func_convert_core_path_wine_to_w32_result
+ func_convert_path_check : ";" \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+ fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # See func_convert_path_msys_to_w32:
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+ func_to_host_path_result=$func_cygpath_result
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set. Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+ $debug_cmd
+
+ func_to_host_path_result=$1
+ if test -n "$1"; then
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_stripname : : "$1"
+ func_to_host_path_tmp1=$func_stripname_result
+ func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+ func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+ func_to_host_path_result=$func_cygpath_result
+ func_convert_path_check : : \
+ "$func_to_host_path_tmp1" "$func_to_host_path_result"
+ func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+ fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_dll_def_p FILE
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with _LT_DLL_DEF_P in libtool.m4
+func_dll_def_p ()
+{
+ $debug_cmd
+
+ func_dll_def_p_tmp=`$SED -n \
+ -e 's/^[ ]*//' \
+ -e '/^\(;.*\)*$/d' \
+ -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \
+ -e q \
+ "$1"`
+ test DEF = "$func_dll_def_p_tmp"
+}
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $debug_cmd
+
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile=$nonopt # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg=$arg
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj=$arg
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify '-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ func_append pie_flag " $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ func_append later " $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs=$IFS; IFS=,
+ for arg in $args; do
+ IFS=$save_ifs
+ func_append_quoted lastarg "$arg"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ func_append base_compile " $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg=$srcfile
+ srcfile=$arg
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_append_quoted base_compile "$lastarg"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with '-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj=$func_basename_result
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from '$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test yes = "$build_libtool_libs" \
+ || func_fatal_configuration "cannot build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name '$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname=$func_basename_result
+ xdir=$func_dirname_result
+ lobj=$xdir$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test yes = "$build_old_libs"; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test no = "$compiler_c_o"; then
+ output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext
+ lockfile=$output_obj.lock
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test yes = "$need_locks"; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test warn = "$need_locks"; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ func_append removelist " $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ func_append removelist " $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+ srcfile=$func_to_tool_file_result
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test yes = "$build_libtool_libs"; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test no != "$pic_mode"; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ func_append command " -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test warn = "$need_locks" &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test yes = "$suppress_opt"; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test yes = "$build_old_libs"; then
+ if test yes != "$pic_mode"; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test yes = "$compiler_c_o"; then
+ func_append command " -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ func_append command "$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test warn = "$need_locks" &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support '-c' and '-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test no != "$need_locks"; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+ test compile = "$opt_mode" && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $opt_mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to build PIC objects only
+ -prefer-non-pic try to build non-PIC objects only
+ -shared do not build a '.o' file suitable for static linking
+ -static only build a '.o' file suitable for static linking
+ -Wc,FLAG pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a 'standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix '.c' with the
+library object suffix, '.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to '-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the '--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the 'install' or 'cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -bindir BINDIR specify path to binaries directory (for systems where
+ libraries must be found in the PATH setting at runtime)
+ -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE use a list of object files found in FILE to specify objects
+ -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes)
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+ -Wc,FLAG
+ -Xcompiler FLAG pass linker-specific FLAG directly to the compiler
+ -Wl,FLAG
+ -Xlinker FLAG pass linker-specific FLAG directly to the linker
+ -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with '-') are ignored.
+
+Every other argument is treated as a filename. Files ending in '.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in '.la', then a libtool library is created,
+only library objects ('.lo' files) may be specified, and '-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created
+using 'ar' and 'ranlib', or on Windows using 'lib'.
+
+If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode '$opt_mode'"
+ ;;
+ esac
+
+ echo
+ $ECHO "Try '$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+ if test : = "$opt_help"; then
+ func_mode_help
+ else
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ func_mode_help
+ done
+ } | $SED -n '1p; 2,$s/^Usage:/ or: /p'
+ {
+ func_help noexit
+ for opt_mode in compile link execute install finish uninstall clean; do
+ echo
+ func_mode_help
+ done
+ } |
+ $SED '1d
+ /^When reporting/,/^Report/{
+ H
+ d
+ }
+ $x
+ /information about other modes/d
+ /more detailed .*MODE/d
+ s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+ fi
+ exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $debug_cmd
+
+ # The first argument is the command name.
+ cmd=$nonopt
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $opt_dlopen; do
+ test -f "$file" \
+ || func_fatal_help "'$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "'$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "'$file' was not linked with '-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+
+ if test -f "$dir/$objdir/$dlname"; then
+ func_append dir "/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+ ;;
+
+ *)
+ func_warning "'-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir=$absdir
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic=$magic
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -* | *.la | *.lo ) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file=$progdir/$program
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file=$progdir/$program
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_append_quoted args "$file"
+ done
+
+ if $opt_dry_run; then
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ echo "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ else
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd=\$cmd$args
+ fi
+}
+
+test execute = "$opt_mode" && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $debug_cmd
+
+ libs=
+ libdirs=
+ admincmds=
+
+ for opt in "$nonopt" ${1+"$@"}
+ do
+ if test -d "$opt"; then
+ func_append libdirs " $opt"
+
+ elif test -f "$opt"; then
+ if func_lalib_unsafe_p "$opt"; then
+ func_append libs " $opt"
+ else
+ func_warning "'$opt' is not a valid libtool archive"
+ fi
+
+ else
+ func_fatal_error "invalid argument '$opt'"
+ fi
+ done
+
+ if test -n "$libs"; then
+ if test -n "$lt_sysroot"; then
+ sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+ sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+ else
+ sysroot_cmd=
+ fi
+
+ # Remove sysroot references
+ if $opt_dry_run; then
+ for lib in $libs; do
+ echo "removing references to $lt_sysroot and '=' prefixes from $lib"
+ done
+ else
+ tmpdir=`func_mktempdir`
+ for lib in $libs; do
+ $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+ > $tmpdir/tmp-la
+ mv -f $tmpdir/tmp-la $lib
+ done
+ ${RM}r "$tmpdir"
+ fi
+ fi
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || func_append admincmds "
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_quiet && exit $EXIT_SUCCESS
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the '-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the '$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the '$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the '$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
+ fi
+ echo
+
+ echo "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ echo "pages."
+ ;;
+ *)
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ echo "----------------------------------------------------------------------"
+ fi
+ exit $EXIT_SUCCESS
+}
+
+test finish = "$opt_mode" && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $debug_cmd
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" ||
+ # Allow the use of GNU shtool's install command.
+ case $nonopt in *shtool*) :;; *) false;; esac
+ then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ func_append install_prog "$func_quote_for_eval_result"
+ install_shared_prog=$install_prog
+ case " $install_prog " in
+ *[\\\ /]cp\ *) install_cp=: ;;
+ *) install_cp=false ;;
+ esac
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=false
+ stripme=
+ no_mode=:
+ for arg
+ do
+ arg2=
+ if test -n "$dest"; then
+ func_append files " $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=: ;;
+ -f)
+ if $install_cp; then :; else
+ prev=$arg
+ fi
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ if test X-m = "X$prev" && test -n "$install_override_mode"; then
+ arg2=$install_override_mode
+ no_mode=false
+ fi
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ func_append install_prog " $func_quote_for_eval_result"
+ if test -n "$arg2"; then
+ func_quote_for_eval "$arg2"
+ fi
+ func_append install_shared_prog " $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the '$prev' option requires an argument"
+
+ if test -n "$install_override_mode" && $no_mode; then
+ if $install_cp; then :; else
+ func_quote_for_eval "$install_override_mode"
+ func_append install_shared_prog " -m $func_quote_for_eval_result"
+ fi
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=:
+ if $isdir; then
+ destdir=$dest
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir=$func_dirname_result
+ destname=$func_basename_result
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "'$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "'$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic=$magic
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ func_append staticlibs " $file"
+ ;;
+
+ *.la)
+ func_resolve_sysroot "$file"
+ file=$func_resolve_sysroot_result
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "'$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append current_libdirs " $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) func_append future_libdirs " $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir=$func_dirname_result
+ func_append dir "$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking '$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname=$1
+ shift
+
+ srcname=$realname
+ test -n "$relink_command" && srcname=${realname}T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme=$stripme
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=
+ ;;
+ esac
+ ;;
+ os2*)
+ case $realname in
+ *_dll.a)
+ tstripme=
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try 'ln -sf' first, because the 'ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib=$destdir/$realname
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name=$func_basename_result
+ instname=$dir/${name}i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile=$destdir/$destname
+ else
+ func_basename "$file"
+ destfile=$func_basename_result
+ destfile=$destdir/$destfile
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest=$destfile
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to '$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test yes = "$build_old_libs"; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile=$destdir/$destname
+ else
+ func_basename "$file"
+ destfile=$func_basename_result
+ destfile=$destdir/$destfile
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=.exe
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script '$wrapper'"
+
+ finalize=:
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'`
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "'$lib' has not been installed in '$libdir'"
+ finalize=false
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test no = "$fast_install" && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if $finalize; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file=$func_basename_result
+ outputname=$tmpdir/$file
+ # Replace the output file specification.
+ relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_quiet || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink '$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file=$outputname
+ else
+ func_warning "cannot relink '$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name=$func_basename_result
+
+ # Set up the ranlib parameters.
+ oldlib=$destdir/$name
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run '$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test install = "$opt_mode" && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $debug_cmd
+
+ my_outputname=$1
+ my_originator=$2
+ my_pic_p=${3-false}
+ my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms=${my_outputname}S.c
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist=$output_objdir/$my_outputname.nm
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test yes = "$dlself"; then
+ func_verbose "generating symbol list for '$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+ func_verbose "extracting global C symbols from '$func_to_tool_file_result'"
+ $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols=$output_objdir/$outputname.exp
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from '$dlprefile'"
+ func_basename "$dlprefile"
+ name=$func_basename_result
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ # if an import library, we need to obtain dlname
+ if func_win32_import_lib_p "$dlprefile"; then
+ func_tr_sh "$dlprefile"
+ eval "curr_lafile=\$libfile_$func_tr_sh_result"
+ dlprefile_dlbasename=
+ if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+ # Use subshell, to avoid clobbering current variable values
+ dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+ if test -n "$dlprefile_dlname"; then
+ func_basename "$dlprefile_dlname"
+ dlprefile_dlbasename=$func_basename_result
+ else
+ # no lafile. user explicitly requested -dlpreopen <import library>.
+ $sharedlib_from_linklib_cmd "$dlprefile"
+ dlprefile_dlbasename=$sharedlib_from_linklib_result
+ fi
+ fi
+ $opt_dry_run || {
+ if test -n "$dlprefile_dlbasename"; then
+ eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+ else
+ func_warning "Could not compute DLL name from $name"
+ eval '$ECHO ": $name " >> "$nlist"'
+ fi
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+ $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+ }
+ else # not an import lib
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ fi
+ ;;
+ *)
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+ eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ ;;
+ esac
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ func_show_eval '$RM "${nlist}I"'
+ if test -n "$global_symbol_to_import"; then
+ eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I'
+ fi
+
+ echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];\
+"
+
+ if test -s "$nlist"I; then
+ echo >> "$output_objdir/$my_dlsyms" "\
+static void lt_syminit(void)
+{
+ LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols;
+ for (; symbol->name; ++symbol)
+ {"
+ $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms"
+ echo >> "$output_objdir/$my_dlsyms" "\
+ }
+}"
+ fi
+ echo >> "$output_objdir/$my_dlsyms" "\
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{ {\"$my_originator\", (void *) 0},"
+
+ if test -s "$nlist"I; then
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {\"@INIT@\", (void *) <_syminit},"
+ fi
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ echo >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ $my_pic_p && pic_flag_for_symtable=" $pic_flag"
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) func_append symtab_cflags " $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj=$output_objdir/${my_outputname}S.$objext
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for '$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+ $debug_cmd
+
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+ test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+ $debug_cmd
+
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+ test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+ $debug_cmd
+
+ win32_libid_type=unknown
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+ case $nm_interface in
+ "MS dumpbin")
+ if func_cygming_ms_implib_p "$1" ||
+ func_cygming_gnu_implib_p "$1"
+ then
+ win32_nmres=import
+ else
+ win32_nmres=
+ fi
+ ;;
+ *)
+ func_to_tool_file "$1" func_convert_file_msys_to_w32
+ win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s|.*|import|
+ p
+ q
+ }
+ }'`
+ ;;
+ esac
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+ $debug_cmd
+
+ sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+ $debug_cmd
+
+ match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+ $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+ $SED '/^Contents of section '"$match_literal"':/{
+ # Place marker at beginning of archive member dllname section
+ s/.*/====MARK====/
+ p
+ d
+ }
+ # These lines can sometimes be longer than 43 characters, but
+ # are always uninteresting
+ /:[ ]*file format pe[i]\{,1\}-/d
+ /^In archive [^:]*:/d
+ # Ensure marker is printed
+ /^====MARK====/p
+ # Remove all lines with less than 43 characters
+ /^.\{43\}/!d
+ # From remaining lines, remove first 43 characters
+ s/^.\{43\}//' |
+ $SED -n '
+ # Join marker and all lines until next marker into a single line
+ /^====MARK====/ b para
+ H
+ $ b para
+ b
+ :para
+ x
+ s/\n//g
+ # Remove the marker
+ s/^====MARK====//
+ # Remove trailing dots and whitespace
+ s/[\. \t]*$//
+ # Print
+ /./p' |
+ # we now have a list, one entry per line, of the stringified
+ # contents of the appropriate section of all members of the
+ # archive that possess that section. Heuristic: eliminate
+ # all those that have a first or second character that is
+ # a '.' (that is, objdump's representation of an unprintable
+ # character.) This should work for all archives with less than
+ # 0x302f exports -- but will fail for DLLs whose name actually
+ # begins with a literal '.' or a single character followed by
+ # a '.'.
+ #
+ # Of those that remain, print the first one.
+ $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+# $sharedlib_from_linklib_cmd
+# Result is available in the variable
+# $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+ $debug_cmd
+
+ if func_cygming_gnu_implib_p "$1"; then
+ # binutils import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+ elif func_cygming_ms_implib_p "$1"; then
+ # ms-generated import library
+ sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+ else
+ # unknown
+ sharedlib_from_linklib_result=
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $debug_cmd
+
+ f_ex_an_ar_dir=$1; shift
+ f_ex_an_ar_oldlib=$1
+ if test yes = "$lock_old_archive_extraction"; then
+ lockfile=$f_ex_an_ar_oldlib.lock
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ fi
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+ 'stat=$?; rm -f "$lockfile"; exit $stat'
+ if test yes = "$lock_old_archive_extraction"; then
+ $opt_dry_run || rm -f "$lockfile"
+ fi
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $debug_cmd
+
+ my_gentop=$1; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=
+ my_xlib=
+ my_xabs=
+ my_xdir=
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib=$func_basename_result
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir=$my_gentop/$my_xlib_u
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ func_basename "$darwin_archive"
+ darwin_base_archive=$func_basename_result
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches; do
+ func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch"
+ $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive"
+ cd "unfat-$$/$darwin_base_archive-$darwin_arch"
+ func_extract_an_archive "`pwd`" "$darwin_base_archive"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+ done
+
+ func_extract_archives_result=$my_oldobjs
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory where it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=${1-no}
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ file=\"\$0\""
+
+ qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+ $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+ ECHO=\"$qECHO\"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ that is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options that match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=\$0
+ shift
+ for lt_opt
+ do
+ case \"\$lt_opt\" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+ test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+ lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+ cat \"\$lt_dump_D/\$lt_dump_F\"
+ exit 0
+ ;;
+ --lt-*)
+ \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n \"\$lt_option_debug\"; then
+ echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\"
+ lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ if test -n \"\$lt_option_debug\"; then
+ \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2
+ func_lt_dump_args \${1+\"\$@\"} 1>&2
+ fi
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case \" \$* \" in
+ *\\ --lt-*)
+ for lt_wr_arg
+ do
+ case \$lt_wr_arg in
+ --lt-*) ;;
+ *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core \${1+\"\$@\"}
+}
+
+ # Parse options
+ func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test yes = "$fast_install"; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ \$ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # fixup the dll searchpath if we need to.
+ #
+ # Fix the DLL searchpath if we need to. Do this before prepending
+ # to shlibpath, because on Windows, both are PATH and uninstalled
+ # libraries must come first.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ # Export our shlibpath_var if we have one.
+ if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+ func_exec_program \${1+\"\$@\"}
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+*/
+EOF
+ cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0)
+
+/* declarations of non-ANSI functions */
+#if defined __MINGW32__
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined __CYGWIN__
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined other_platform || defined ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined _MSC_VER
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+# define S_IXUSR _S_IEXEC
+#elif defined __MINGW32__
+# define setmode _setmode
+# define stat _stat
+# define chmod _chmod
+# define getcwd _getcwd
+# define putenv _putenv
+#elif defined __CYGWIN__
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined other platforms ... */
+#endif
+
+#if defined PATH_MAX
+# define LT_PATHMAX PATH_MAX
+#elif defined MAXPATHLEN
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \
+ defined __OS2__
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free (stale); stale = 0; } \
+} while (0)
+
+#if defined LT_DEBUGWRAPPER
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+ cat <<EOF
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
+# define externally_visible volatile
+#else
+# define externally_visible __attribute__((externally_visible)) volatile
+#endif
+externally_visible const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_path "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_path "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_path_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test yes = "$fast_install"; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ int rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ newargz = XMALLOC (char *, (size_t) argc + 1);
+
+ /* very simple arg parsing; don't want to rely on getopt
+ * also, copy all non cwrapper options to newargz, except
+ * argz[0], which is handled differently
+ */
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (STREQ (argv[i], dumpscript_opt))
+ {
+EOF
+ case $host in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ lt_dump_script (stdout);
+ return 0;
+ }
+ if (STREQ (argv[i], debug_opt))
+ {
+ lt_debug = 1;
+ continue;
+ }
+ if (STREQ (argv[i], ltwrapper_option_prefix))
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal (__FILE__, __LINE__,
+ "unrecognized %s option: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+EOF
+ cat <<EOF
+ /* The GNU banner must be the first non-error debug message */
+ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n");
+EOF
+ cat <<"EOF"
+ lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (before symlink chase) at: %s\n",
+ tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) found exe (after symlink chase) at: %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) libtool target name: %s\n",
+ target_name);
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must
+ be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+ because on Windows, both *_VARNAMEs are PATH but uninstalled
+ libraries must come first. */
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+ lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+ nonnull (lt_argv_zero));
+ for (i = 0; i < newargc; i++)
+ {
+ lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+ i, nonnull (newargz[i]));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ newargz = prepare_spawn (newargz);
+ rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ lt_debugprintf (__FILE__, __LINE__,
+ "(main) failed to launch target \"%s\": %s\n",
+ lt_argv_zero, nonnull (strerror (errno)));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+ nonempty (path));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ size_t tmp_len;
+ char *concat_name;
+
+ lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+ nonempty (wrapper));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined HAVE_DOS_BASED_FILE_SYSTEM
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = (size_t) (q - p);
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+ nonnull (strerror (errno)));
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ lt_debugprintf (__FILE__, __LINE__,
+ "checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "error accessing file \"%s\": %s",
+ tmp_pathspec, nonnull (strerror (errno)));
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal (__FILE__, __LINE__,
+ "could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (STREQ (str, pat))
+ *str = '\0';
+ }
+ return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+ va_list args;
+ if (lt_debug)
+ {
+ (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+ }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+ int line, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+ va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+ return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+ return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_setenv) setting '%s' to '%s'\n",
+ nonnull (name), nonnull (value));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ size_t len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ size_t orig_value_len = strlen (orig_value);
+ size_t add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ size_t len = strlen (new_value);
+ while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[--len] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ lt_debugprintf (__FILE__, __LINE__,
+ "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ nonnull (name), nonnull (value));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+EOF
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+ Note that spawn() does not by itself call the command interpreter
+ (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+ ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&v);
+ v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+ }) ? "cmd.exe" : "command.com").
+ Instead it simply concatenates the arguments, separated by ' ', and calls
+ CreateProcess(). We must quote the arguments since Win32 CreateProcess()
+ interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+ special way:
+ - Space and tab are interpreted as delimiters. They are not treated as
+ delimiters if they are surrounded by double quotes: "...".
+ - Unescaped double quotes are removed from the input. Their only effect is
+ that within double quotes, space and tab are treated like normal
+ characters.
+ - Backslashes not followed by double quotes are not special.
+ - But 2*n+1 backslashes followed by a double quote become
+ n backslashes followed by a double quote (n >= 0):
+ \" -> "
+ \\\" -> \"
+ \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+ size_t argc;
+ char **new_argv;
+ size_t i;
+
+ /* Count number of arguments. */
+ for (argc = 0; argv[argc] != NULL; argc++)
+ ;
+
+ /* Allocate new argument vector. */
+ new_argv = XMALLOC (char *, argc + 1);
+
+ /* Put quoted arguments into the new argument vector. */
+ for (i = 0; i < argc; i++)
+ {
+ const char *string = argv[i];
+
+ if (string[0] == '\0')
+ new_argv[i] = xstrdup ("\"\"");
+ else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+ {
+ int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+ size_t length;
+ unsigned int backslashes;
+ const char *s;
+ char *quoted_string;
+ char *p;
+
+ length = 0;
+ backslashes = 0;
+ if (quote_around)
+ length++;
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ length += backslashes + 1;
+ length++;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ length += backslashes + 1;
+
+ quoted_string = XMALLOC (char, length + 1);
+
+ p = quoted_string;
+ backslashes = 0;
+ if (quote_around)
+ *p++ = '"';
+ for (s = string; *s != '\0'; s++)
+ {
+ char c = *s;
+ if (c == '"')
+ {
+ unsigned int j;
+ for (j = backslashes + 1; j > 0; j--)
+ *p++ = '\\';
+ }
+ *p++ = c;
+ if (c == '\\')
+ backslashes++;
+ else
+ backslashes = 0;
+ }
+ if (quote_around)
+ {
+ unsigned int j;
+ for (j = backslashes; j > 0; j--)
+ *p++ = '\\';
+ *p++ = '"';
+ }
+ *p = '\0';
+
+ new_argv[i] = quoted_string;
+ }
+ else
+ new_argv[i] = (char *) string;
+ }
+ new_argv[argc] = NULL;
+
+ return new_argv;
+}
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+ func_emit_wrapper yes |
+ $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/ fputs ("\1", f);/p
+g
+D'
+ cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+ $debug_cmd
+
+ case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+ *import*) : ;;
+ *) false ;;
+ esac
+}
+
+# func_suncc_cstd_abi
+# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!!
+# Several compiler flags select an ABI that is incompatible with the
+# Cstd library. Avoid specifying it if any are in CXXFLAGS.
+func_suncc_cstd_abi ()
+{
+ $debug_cmd
+
+ case " $compile_command " in
+ *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*)
+ suncc_use_cstd_abi=no
+ ;;
+ *)
+ suncc_use_cstd_abi=yes
+ ;;
+ esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $debug_cmd
+
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # what system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll that has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ bindir=
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ os2dllname=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=false
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module=$wl-single_module
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test yes != "$build_libtool_libs" \
+ && func_fatal_configuration "cannot build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg=$1
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ bindir)
+ bindir=$arg
+ prev=
+ continue
+ ;;
+ dlfiles|dlprefiles)
+ $preload || {
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=:
+ }
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test no = "$dlself"; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test dlprefiles = "$prev"; then
+ dlself=yes
+ elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test dlfiles = "$prev"; then
+ func_append dlfiles " $arg"
+ else
+ func_append dlprefiles " $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols=$arg
+ test -f "$arg" \
+ || func_fatal_error "symbol file '$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex=$arg
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) func_append deplibs " $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir=$arg
+ prev=
+ continue
+ ;;
+ mllvm)
+ # Clang does not use LLVM to link, so we can simply discard any
+ # '-mllvm $arg' options when doing the link step.
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# func_append moreargs " $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test none = "$pic_object" &&
+ test none = "$non_pic_object"; then
+ func_fatal_error "cannot find name of object for '$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ if test none != "$pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ pic_object=$xdir$pic_object
+
+ if test dlfiles = "$prev"; then
+ if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test dlprefiles = "$prev"; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg=$pic_object
+ fi
+
+ # Non-PIC object.
+ if test none != "$non_pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object=$xdir$non_pic_object
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test none = "$pic_object"; then
+ arg=$non_pic_object
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object=$pic_object
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "'$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file '$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ os2dllname)
+ os2dllname=$arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex=$arg
+ prev=
+ continue
+ ;;
+ release)
+ release=-$arg
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test rpath = "$prev"; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) func_append rpath " $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) func_append xrpath " $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds=$arg
+ prev=
+ continue
+ ;;
+ weak)
+ func_append weak_libs " $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ func_append compiler_flags " $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ func_append linker_flags " $qarg"
+ func_append compiler_flags " $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg=$arg
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "'-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -bindir)
+ prev=bindir
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test X-export-symbols = "X$arg"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname "-L" '' "$arg"
+ if test -z "$func_stripname_result"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between '-L' and '$1'"
+ else
+ func_fatal_error "need path for '-L' option"
+ fi
+ fi
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of '$dir'"
+ dir=$absdir
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "* | *" $arg "*)
+ # Will only happen for absolute or sysroot arguments
+ ;;
+ *)
+ # Preserve sysroot, but never include relative directories
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+ *) func_append deplibs " -L$dir" ;;
+ esac
+ func_append lib_search_path " $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) func_append dllsearchpath ":$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test X-lc = "X$arg" || test X-lm = "X$arg"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ # Do not include libc due to us having libc/libc_r.
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ func_append deplibs " System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test X-lc = "X$arg" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test X-lc = "X$arg" && continue
+ ;;
+ esac
+ elif test X-lc_r = "X$arg"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ func_append deplibs " $arg"
+ continue
+ ;;
+
+ -mllvm)
+ prev=mllvm
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot|--sysroot)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ func_append compiler_flags " $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) func_append new_inherited_linker_flags " $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module=$wl-multi_module
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "'-no-install' is ignored for $host"
+ func_warning "assuming '-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -os2dllname)
+ prev=os2dllname
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ =*)
+ func_stripname '=' '' "$dir"
+ dir=$lt_sysroot$func_stripname_result
+ ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs=$IFS; IFS=,
+ for flag in $args; do
+ IFS=$save_ifs
+ func_quote_for_eval "$flag"
+ func_append arg " $func_quote_for_eval_result"
+ func_append compiler_flags " $func_quote_for_eval_result"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs=$IFS; IFS=,
+ for flag in $args; do
+ IFS=$save_ifs
+ func_quote_for_eval "$flag"
+ func_append arg " $wl$func_quote_for_eval_result"
+ func_append compiler_flags " $wl$func_quote_for_eval_result"
+ func_append linker_flags " $func_quote_for_eval_result"
+ done
+ IFS=$save_ifs
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+
+ # Flags to be passed through unchanged, with rationale:
+ # -64, -mips[0-9] enable 64-bit mode for the SGI compiler
+ # -r[0-9][0-9]* specify processor for the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+ # +DA*, +DD* enable 64-bit mode for the HP compiler
+ # -q* compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+ # -F/path path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* profiling flags for GCC
+ # -fstack-protector* stack protector flags for GCC
+ # @file GCC response files
+ # -tp=* Portland pgcc target processor selection
+ # --sysroot=* for sysroot support
+ # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+ # -stdlib=* select c++ std lib with clang
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ func_append compiler_flags " $arg"
+ continue
+ ;;
+
+ -Z*)
+ if test os2 = "`expr $host : '.*\(os2\)'`"; then
+ # OS/2 uses -Zxxx to specify OS/2-specific options
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case $arg in
+ -Zlinker | -Zstack)
+ prev=xcompiler
+ ;;
+ esac
+ continue
+ else
+ # Otherwise treat like 'Some other compiler flag' below
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ fi
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+
+ *.$objext)
+ # A standard object.
+ func_append objs " $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test none = "$pic_object" &&
+ test none = "$non_pic_object"; then
+ func_fatal_error "cannot find name of object for '$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ test none = "$pic_object" || {
+ # Prepend the subdirectory the object is found in.
+ pic_object=$xdir$pic_object
+
+ if test dlfiles = "$prev"; then
+ if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then
+ func_append dlfiles " $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test dlprefiles = "$prev"; then
+ # Preload the old-style object.
+ func_append dlprefiles " $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg=$pic_object
+ }
+
+ # Non-PIC object.
+ if test none != "$non_pic_object"; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object=$xdir$non_pic_object
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test none = "$pic_object"; then
+ arg=$non_pic_object
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object=$pic_object
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir=$func_dirname_result
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "'$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ func_append deplibs " $arg"
+ func_append old_deplibs " $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ func_resolve_sysroot "$arg"
+ if test dlfiles = "$prev"; then
+ # This library was specified with -dlopen.
+ func_append dlfiles " $func_resolve_sysroot_result"
+ prev=
+ elif test dlprefiles = "$prev"; then
+ # The library was specified with -dlpreopen.
+ func_append dlprefiles " $func_resolve_sysroot_result"
+ prev=
+ else
+ func_append deplibs " $func_resolve_sysroot_result"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg=$func_quote_for_eval_result
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the '$prevarg' option requires an argument"
+
+ if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname=$func_basename_result
+ libobjs_save=$libobjs
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ # Definition is injected by LT_CONFIG during libtool generation.
+ func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH"
+
+ func_dirname "$output" "/" ""
+ output_objdir=$func_dirname_result$objdir
+ func_to_tool_file "$output_objdir/"
+ tool_output_objdir=$func_to_tool_file_result
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_preserve_dup_deps; then
+ case "$libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append libs " $deplib"
+ done
+
+ if test lib = "$linkmode"; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+ esac
+ func_append pre_post_deps " $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can '-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=false
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test lib,link = "$linkmode,$pass"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs=$tmp_deplibs
+ fi
+
+ if test lib,link = "$linkmode,$pass" ||
+ test prog,scan = "$linkmode,$pass"; then
+ libs=$deplibs
+ deplibs=
+ fi
+ if test prog = "$linkmode"; then
+ case $pass in
+ dlopen) libs=$dlfiles ;;
+ dlpreopen) libs=$dlprefiles ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ esac
+ fi
+ if test lib,dlpreopen = "$linkmode,$pass"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ func_resolve_sysroot "$lib"
+ case $lib in
+ *.la) func_source "$func_resolve_sysroot_result" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ func_basename "$deplib"
+ deplib_base=$func_basename_result
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) func_append deplibs " $deplib" ;;
+ esac
+ done
+ done
+ libs=$dlprefiles
+ fi
+ if test dlopen = "$pass"; then
+ # Collect dlpreopened libraries
+ save_deplibs=$deplibs
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=false
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append compiler_flags " $deplib"
+ if test lib = "$linkmode"; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test lib != "$linkmode" && test prog != "$linkmode"; then
+ func_warning "'-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test lib = "$linkmode"; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib=$searchdir/lib$name$search_ext
+ if test -f "$lib"; then
+ if test .la = "$search_ext"; then
+ found=:
+ else
+ found=false
+ fi
+ break 2
+ fi
+ done
+ done
+ if $found; then
+ # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll=$l
+ done
+ if test "X$ll" = "X$old_library"; then # only static version available
+ found=false
+ func_dirname "$lib" "" "."
+ ladir=$func_dirname_result
+ lib=$ladir/$old_library
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ else
+ # deplib doesn't seem to be a libtool library
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ ;; # -l
+ *.ltframework)
+ if test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test lib = "$linkmode"; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) func_append new_inherited_linker_flags " $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test conv = "$pass" && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ prog)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test scan = "$pass"; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ *)
+ func_warning "'-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test link = "$pass"; then
+ func_stripname '-R' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ dir=$func_resolve_sysroot_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) func_append xrpath " $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ lib=$func_resolve_sysroot_result
+ ;;
+ *.$libext)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=false
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=:
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=:
+ ;;
+ esac
+ if $valid_a_lib; then
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ else
+ echo
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because the file extensions .$libext of this argument makes me believe"
+ echo "*** that it is just a static archive that I should not use here."
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test link != "$pass"; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test conv = "$pass"; then
+ deplibs="$deplib $deplibs"
+ elif test prog = "$linkmode"; then
+ if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ func_append newdlprefiles " $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ func_append newdlfiles " $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=:
+ continue
+ ;;
+ esac # case $deplib
+
+ $found || test -f "$lib" \
+ || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'"
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "'$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir=$func_dirname_result
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test lib,link = "$linkmode,$pass" ||
+ test prog,scan = "$linkmode,$pass" ||
+ { test prog != "$linkmode" && test lib != "$linkmode"; }; then
+ test -n "$dlopen" && func_append dlfiles " $dlopen"
+ test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+ fi
+
+ if test conv = "$pass"; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for '$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ func_append convenience " $ladir/$objdir/$old_library"
+ func_append old_convenience " $ladir/$objdir/$old_library"
+ elif test prog != "$linkmode" && test lib != "$linkmode"; then
+ func_fatal_error "'$lib' is not a convenience library"
+ fi
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ if test -n "$old_library" &&
+ { test yes = "$prefer_static_libs" ||
+ test built,no = "$prefer_static_libs,$installed"; }; then
+ linklib=$old_library
+ else
+ for l in $old_library $library_names; do
+ linklib=$l
+ done
+ fi
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for '$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test dlopen = "$pass"; then
+ test -z "$libdir" \
+ && func_fatal_error "cannot -dlopen a convenience library: '$lib'"
+ if test -z "$dlname" ||
+ test yes != "$dlopen_support" ||
+ test no = "$build_libtool_libs"
+ then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ func_append dlprefiles " $lib $dependency_libs"
+ else
+ func_append newdlfiles " $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of '$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir=$ladir
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname=$func_basename_result
+
+ # Find the relevant object directory and library name.
+ if test yes = "$installed"; then
+ if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library '$lib' was moved."
+ dir=$ladir
+ absdir=$abs_ladir
+ libdir=$abs_ladir
+ else
+ dir=$lt_sysroot$libdir
+ absdir=$lt_sysroot$libdir
+ fi
+ test yes = "$hardcode_automatic" && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir=$ladir
+ absdir=$abs_ladir
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ else
+ dir=$ladir/$objdir
+ absdir=$abs_ladir/$objdir
+ # Remove this search path later
+ func_append notinst_path " $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test dlpreopen = "$pass"; then
+ if test -z "$libdir" && test prog = "$linkmode"; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'"
+ fi
+ case $host in
+ # special handling for platforms with PE-DLLs.
+ *cygwin* | *mingw* | *cegcc* )
+ # Linker will automatically link against shared library if both
+ # static and shared are present. Therefore, ensure we extract
+ # symbols from the import library if a shared library is present
+ # (otherwise, the dlopen module name will be incorrect). We do
+ # this by putting the import library name into $newdlprefiles.
+ # We recover the dlopen module name by 'saving' the la file
+ # name in a special purpose variable, and (later) extracting the
+ # dlname from the la file.
+ if test -n "$dlname"; then
+ func_tr_sh "$dir/$linklib"
+ eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+ func_append newdlprefiles " $dir/$linklib"
+ else
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ fi
+ ;;
+ * )
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ func_append newdlprefiles " $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ func_append dlpreconveniencelibs " $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ func_append newdlprefiles " $dir/$dlname"
+ else
+ func_append newdlprefiles " $dir/$linklib"
+ fi
+ ;;
+ esac
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test lib = "$linkmode"; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test prog,link = "$linkmode,$pass"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test prog = "$linkmode" && test link != "$pass"; then
+ func_append newlib_search_path " $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=false
+ if test no != "$link_all_deplibs" || test -z "$library_names" ||
+ test no = "$build_libtool_libs"; then
+ linkalldeplibs=:
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result"
+ func_append newlib_search_path " $func_resolve_sysroot_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if $linkalldeplibs; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test prog,link = "$linkmode,$pass"; then
+ if test -n "$library_names" &&
+ { { test no = "$prefer_static_libs" ||
+ test built,yes = "$prefer_static_libs,$installed"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then
+ # Make sure the rpath contains only unique directories.
+ case $temp_rpath: in
+ *"$absdir:"*) ;;
+ *) func_append temp_rpath "$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if $alldeplibs &&
+ { test pass_all = "$deplibs_check_method" ||
+ { test yes = "$build_libtool_libs" &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test built = "$use_static_libs" && test yes = "$installed"; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test no = "$use_static_libs" || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc* | *os2*)
+ # No point in relinking DLLs because paths are not encoded
+ func_append notinst_deplibs " $lib"
+ need_relink=no
+ ;;
+ *)
+ if test no = "$installed"; then
+ func_append notinst_deplibs " $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule=$dlpremoduletest
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
+ echo
+ if test prog = "$linkmode"; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test lib = "$linkmode" &&
+ test yes = "$hardcode_into_libs"; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) func_append compile_rpath " $absdir" ;;
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname=$1
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname=$dlname
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc* | *os2*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix=-$major
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname=$realname
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot=$soname
+ func_basename "$soroot"
+ soname=$func_basename_result
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from '$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for '$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test prog = "$linkmode" || test relink != "$opt_mode"; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test no = "$hardcode_direct"; then
+ add=$dir/$linklib
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;;
+ *-*-sysv4*uw2*) add_dir=-L$dir ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir=-L$dir ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we cannot
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library"; then
+ echo
+ echo "*** And there doesn't seem to be a static archive available"
+ echo "*** The link will probably fail, sorry"
+ else
+ add=$dir/$old_library
+ fi
+ elif test -n "$old_library"; then
+ add=$dir/$old_library
+ fi
+ fi
+ esac
+ elif test no = "$hardcode_minus_L"; then
+ case $host in
+ *-*-sunos*) add_shlibpath=$dir ;;
+ esac
+ add_dir=-L$dir
+ add=-l$name
+ elif test no = "$hardcode_shlibpath_var"; then
+ add_shlibpath=$dir
+ add=-l$name
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test yes = "$hardcode_direct" &&
+ test no = "$hardcode_direct_absolute"; then
+ add=$dir/$linklib
+ elif test yes = "$hardcode_minus_L"; then
+ add_dir=-L$absdir
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add=-l$name
+ elif test yes = "$hardcode_shlibpath_var"; then
+ add_shlibpath=$dir
+ add=-l$name
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test yes != "$lib_linked"; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) func_append compile_shlibpath "$add_shlibpath:" ;;
+ esac
+ fi
+ if test prog = "$linkmode"; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test yes != "$hardcode_direct" &&
+ test yes != "$hardcode_minus_L" &&
+ test yes = "$hardcode_shlibpath_var"; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test prog = "$linkmode" || test relink = "$opt_mode"; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test yes = "$hardcode_direct" &&
+ test no = "$hardcode_direct_absolute"; then
+ add=$libdir/$linklib
+ elif test yes = "$hardcode_minus_L"; then
+ add_dir=-L$libdir
+ add=-l$name
+ elif test yes = "$hardcode_shlibpath_var"; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) func_append finalize_shlibpath "$libdir:" ;;
+ esac
+ add=-l$name
+ elif test yes = "$hardcode_automatic"; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib"; then
+ add=$inst_prefix_dir$libdir/$linklib
+ else
+ add=$libdir/$linklib
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir=-L$libdir
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ func_append add_dir " -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add=-l$name
+ fi
+
+ if test prog = "$linkmode"; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test prog = "$linkmode"; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test unsupported != "$hardcode_direct"; then
+ test -n "$old_library" && linklib=$old_library
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test yes = "$build_libtool_libs"; then
+ # Not a shared library
+ if test pass_all != "$deplibs_check_method"; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ $ECHO "*** Warning: This system cannot link to static lib archive $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test yes = "$module"; then
+ echo "*** But as you try to build a module library, libtool will still create "
+ echo "*** a static module, that should work as long as the dlopening application"
+ echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test no = "$build_old_libs"; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test lib = "$linkmode"; then
+ if test -n "$dependency_libs" &&
+ { test yes != "$hardcode_into_libs" ||
+ test yes = "$build_old_libs" ||
+ test yes = "$link_static"; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) func_append xrpath " $temp_xrpath";;
+ esac;;
+ *) func_append temp_deplibs " $libdir";;
+ esac
+ done
+ dependency_libs=$temp_deplibs
+ fi
+
+ func_append newlib_search_path " $absdir"
+ # Link against this library
+ test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ func_resolve_sysroot "$func_stripname_result";;
+ *) func_resolve_sysroot "$deplib" ;;
+ esac
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $func_resolve_sysroot_result "*)
+ func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+ esac
+ fi
+ func_append tmp_libs " $func_resolve_sysroot_result"
+ done
+
+ if test no != "$link_all_deplibs"; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path=$deplib ;;
+ *.la)
+ func_resolve_sysroot "$deplib"
+ deplib=$func_resolve_sysroot_result
+ func_dirname "$deplib" "" "."
+ dir=$func_dirname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of '$dir'"
+ absdir=$dir
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names"; then
+ for tmp in $deplibrary_names; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl"; then
+ depdepl=$absdir/$objdir/$depdepl
+ darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
+ func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path=-L$absdir/$objdir
+ ;;
+ esac
+ else
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "'$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "'$deplib' seems to be moved"
+
+ path=-L$absdir
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test link = "$pass"; then
+ if test prog = "$linkmode"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs=$newdependency_libs
+ if test dlpreopen = "$pass"; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test dlopen != "$pass"; then
+ test conv = "$pass" || {
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) func_append lib_search_path " $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ }
+
+ if test prog,link = "$linkmode,$pass"; then
+ vars="compile_deplibs finalize_deplibs"
+ else
+ vars=deplibs
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append tmp_libs " $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+
+ # Add Sun CC postdeps if required:
+ test CXX = "$tagname" && {
+ case $host_os in
+ linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C++ 5.9
+ func_suncc_cstd_abi
+
+ if test no != "$suncc_use_cstd_abi"; then
+ func_append postdeps ' -library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ func_cc_basename "$CC"
+ case $func_cc_basename_result in
+ CC* | sunCC*)
+ func_suncc_cstd_abi
+
+ if test no != "$suncc_use_cstd_abi"; then
+ func_append postdeps ' -library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ }
+
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=
+ ;;
+ esac
+ if test -n "$i"; then
+ func_append tmp_libs " $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test prog = "$linkmode"; then
+ dlfiles=$newdlfiles
+ fi
+ if test prog = "$linkmode" || test lib = "$linkmode"; then
+ dlprefiles=$newdlprefiles
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ func_warning "'-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "'-l' and '-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "'-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "'-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "'-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs=$output
+ func_append objs "$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form 'libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test no = "$module" \
+ && func_fatal_help "libtool library '$output' must begin with 'lib'"
+
+ if test no != "$need_lib_prefix"; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test pass_all != "$deplibs_check_method"; then
+ func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
+ else
+ echo
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ func_append libobjs " $objs"
+ fi
+ fi
+
+ test no = "$dlself" \
+ || func_warning "'-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test 1 -lt "$#" \
+ && func_warning "ignoring multiple '-rpath's for a libtool library"
+
+ install_libdir=$1
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test yes = "$build_libtool_libs"; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a '.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs=$IFS; IFS=:
+ set dummy $vinfo 0 0 0
+ shift
+ IFS=$save_ifs
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to '-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major=$1
+ number_minor=$2
+ number_revision=$3
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # that has an extra 1 added just for fun
+ #
+ case $version_type in
+ # correct linux to gnu/linux during the next big refactor
+ darwin|freebsd-elf|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age=$number_minor
+ revision=$number_revision
+ ;;
+ freebsd-aout|qnx|sunos)
+ current=$number_major
+ revision=$number_minor
+ age=0
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age=$number_minor
+ revision=$number_minor
+ lt_irix_increment=no
+ ;;
+ esac
+ ;;
+ no)
+ current=$1
+ revision=$2
+ age=$3
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT '$current' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION '$revision' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE '$age' must be a nonnegative integer"
+ func_fatal_error "'$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE '$age' is greater than the current interface number '$current'"
+ func_fatal_error "'$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ # On Darwin other compilers
+ case $CC in
+ nagfor*)
+ verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
+ ;;
+ *)
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+ esac
+ ;;
+
+ freebsd-aout)
+ major=.$current
+ versuffix=.$current.$revision
+ ;;
+
+ freebsd-elf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ ;;
+
+ irix | nonstopux)
+ if test no = "$lt_irix_increment"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring=$verstring_prefix$major.$revision
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test 0 -ne "$loop"; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring=$verstring_prefix$major.$iface:$verstring
+ done
+
+ # Before this point, $major must not contain '.'.
+ major=.$major
+ versuffix=$major.$revision
+ ;;
+
+ linux) # correct to gnu/linux during the next big refactor
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=$major.$age.$revision
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=.$current.$age.$revision
+ verstring=$current.$age.$revision
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test 0 -ne "$loop"; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring=$verstring:$iface.0
+ done
+
+ # Make executables depend on our current version.
+ func_append verstring ":$current.0"
+ ;;
+
+ qnx)
+ major=.$current
+ versuffix=.$current
+ ;;
+
+ sco)
+ major=.$current
+ versuffix=.$current
+ ;;
+
+ sunos)
+ major=.$current
+ versuffix=.$current.$revision
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 file systems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix=-$major
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type '$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring=0.0
+ ;;
+ esac
+ if test no = "$need_version"; then
+ versuffix=
+ else
+ versuffix=.0.0
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test yes,no = "$avoid_version,$need_version"; then
+ major=
+ versuffix=
+ verstring=
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test yes = "$allow_undefined"; then
+ if test unsupported = "$allow_undefined_flag"; then
+ if test yes = "$build_old_libs"; then
+ func_warning "undefined symbols not allowed in $host shared libraries; building static only"
+ build_libtool_libs=no
+ else
+ func_fatal_error "can't build $host shared library unless -no-undefined is specified"
+ fi
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag=$no_undefined_flag
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" :
+ func_append libobjs " $symfileobj"
+ test " " = "$libobjs" && libobjs=
+
+ if test relink != "$opt_mode"; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*)
+ if test -n "$precious_files_regex"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ func_append removelist " $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then
+ func_append oldlibs " $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+ # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ func_replace_sysroot "$libdir"
+ func_append temp_xrpath " -R$func_replace_sysroot_result"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles=$dlfiles
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) func_append dlfiles " $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles=$dlprefiles
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) func_append dlprefiles " $lib" ;;
+ esac
+ done
+
+ if test yes = "$build_libtool_libs"; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ func_append deplibs " System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test yes = "$build_libtool_need_lc"; then
+ func_append deplibs " -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=
+ versuffix=
+ major=
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=
+ ;;
+ esac
+ fi
+ if test -n "$i"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which I believe you do not have"
+ echo "*** because a test_compile did reveal that the linker did not use it for"
+ echo "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ func_append newdeplibs " $i"
+ i=
+ ;;
+ esac
+ fi
+ if test -n "$i"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
+ func_append newdeplibs " $i"
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because a test_compile did reveal that the linker did not use this one"
+ echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ func_append newdeplibs " $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ if test -n "$file_magic_glob"; then
+ libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+ else
+ libnameglob=$libname
+ fi
+ test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test yes = "$want_nocaseglob"; then
+ shopt -s nocaseglob
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ $nocaseglob
+ else
+ potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+ fi
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib=$potent_lib
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | $SED 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;;
+ *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib"; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib"; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib"; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib=$potent_lib # see symlink-check above in file_magic test
+ if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ func_append newdeplibs " $a_deplib"
+ a_deplib=
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib"; then
+ droppeddeps=yes
+ echo
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have"
+ echo "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib"; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ func_append newdeplibs " $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=
+ tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+ if test yes = "$allow_libtool_libs_with_static_runtimes"; then
+ for i in $predeps $postdeps; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"`
+ done
+ fi
+ case $tmp_deplibs in
+ *[!\ \ ]*)
+ echo
+ if test none = "$deplibs_check_method"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ ;;
+ esac
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test yes = "$droppeddeps"; then
+ if test yes = "$module"; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** 'nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test no = "$build_old_libs"; then
+ oldlibs=$output_objdir/$libname.$libext
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test no = "$allow_undefined"; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test no = "$build_old_libs"; then
+ oldlibs=$output_objdir/$libname.$libext
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ deplibs=$new_libs
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test yes = "$build_libtool_libs"; then
+ # Remove $wl instances when linking with ld.
+ # FIXME: should test the right _cmds variable.
+ case $archive_cmds in
+ *\$LD\ *) wl= ;;
+ esac
+ if test yes = "$hardcode_into_libs"; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath=$finalize_rpath
+ test relink = "$opt_mode" || rpath=$compile_rpath$rpath
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ func_replace_sysroot "$libdir"
+ libdir=$func_replace_sysroot_result
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append dep_rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath=$finalize_shlibpath
+ test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname=$1
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname=$realname
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib=$output_objdir/$realname
+ linknames=
+ for link
+ do
+ func_append linknames " $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols=$output_objdir/$libname.uexp
+ func_append delfiles " $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ func_dll_def_p "$export_symbols" || {
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols=$export_symbols
+ export_symbols=
+ always_export_symbols=yes
+ }
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for '$libname.la'"
+ export_symbols=$output_objdir/$libname.exp
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs=$IFS; IFS='~'
+ for cmd1 in $cmds; do
+ IFS=$save_ifs
+ # Take the normal branch if the nm_file_list_spec branch
+ # doesn't work or if tool conversion is not needed.
+ case $nm_file_list_spec~$to_tool_file_cmd in
+ *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+ try_normal_branch=yes
+ eval cmd=\"$cmd1\"
+ func_len " $cmd"
+ len=$func_len_result
+ ;;
+ *)
+ try_normal_branch=no
+ ;;
+ esac
+ if test yes = "$try_normal_branch" \
+ && { test "$len" -lt "$max_cmd_len" \
+ || test "$max_cmd_len" -le -1; }
+ then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ elif test -n "$nm_file_list_spec"; then
+ func_basename "$output"
+ output_la=$func_basename_result
+ save_libobjs=$libobjs
+ save_output=$output
+ output=$output_objdir/$output_la.nm
+ func_to_tool_file "$output"
+ libobjs=$nm_file_list_spec$func_to_tool_file_result
+ func_append delfiles " $output"
+ func_verbose "creating $NM input file list: $output"
+ for obj in $save_libobjs; do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > "$output"
+ eval cmd=\"$cmd1\"
+ func_show_eval "$cmd" 'exit $?'
+ output=$save_output
+ libobjs=$save_libobjs
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS=$save_ifs
+ if test -n "$export_symbols_regex" && test : != "$skipped_export"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols=$export_symbols
+ test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test : != "$skipped_export" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands, which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ func_append tmp_deplibs " $test_deplib"
+ ;;
+ esac
+ done
+ deplibs=$tmp_deplibs
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test yes = "$compiler_needs_object" &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ func_append linker_flags " $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test relink = "$opt_mode"; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test yes = "$module" && test -n "$module_cmds"; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test : != "$skipped_export" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ func_basename "$output"
+ output_la=$func_basename_result
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then
+ output=$output_objdir/$output_la.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ echo 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ echo ')' >> $output
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$func_to_tool_file_result
+ elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then
+ output=$output_objdir/$output_la.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test yes = "$compiler_needs_object"; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result" >> $output
+ done
+ func_append delfiles " $output"
+ func_to_tool_file "$output"
+ output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-$k.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test -z "$objlist" ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test 1 -eq "$k"; then
+ # The first file doesn't have a previous command to add.
+ reload_objs=$objlist
+ eval concat_cmds=\"$reload_cmds\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-$k.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-$k.$objext
+ objlist=" $obj"
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ reload_objs="$objlist $last_robj"
+ eval concat_cmds=\"\$concat_cmds$reload_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ func_append delfiles " $output"
+
+ else
+ output=
+ fi
+
+ ${skipped_export-false} && {
+ func_verbose "generating symbol list for '$libname.la'"
+ export_symbols=$output_objdir/$libname.exp
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ }
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs=$IFS; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS=$save_ifs
+ $opt_quiet || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS=$save_ifs
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ ${skipped_export-false} && {
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols=$export_symbols
+ test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols
+ $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for '$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands, which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ }
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test yes = "$module" && test -n "$module_cmds"; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append libobjs " $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs=$IFS; IFS='~'
+ for cmd in $cmds; do
+ IFS=$sp$nl
+ eval cmd=\"$cmd\"
+ IFS=$save_ifs
+ $opt_quiet || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS=$save_ifs
+
+ # Restore the uninstalled library and exit
+ if test relink = "$opt_mode"; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test yes = "$module" || test yes = "$export_dynamic"; then
+ # On all known operating systems, these are identical.
+ dlname=$soname
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then
+ func_warning "'-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "'-l' and '-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "'-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "'-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "'-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object '$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj=$output
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # if reload_cmds runs $LD directly, get rid of -Wl from
+ # whole_archive_flag_spec and hope we can get by with turning comma
+ # into space.
+ case $reload_cmds in
+ *\$LD[\ \$]*) wl= ;;
+ esac
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+ reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags
+ else
+ gentop=$output_objdir/${obj}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # If we're not building shared, we need to use non_pic_objs
+ test yes = "$build_libtool_libs" || libobjs=$non_pic_objects
+
+ # Create the old-style object.
+ reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs
+
+ output=$obj
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ test yes = "$build_libtool_libs" || {
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ }
+
+ if test -n "$pic_flag" || test default != "$pic_mode"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output=$libobj
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "'-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "'-release' is ignored for programs"
+
+ $preload \
+ && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \
+ && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test CXX = "$tagname"; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ func_append compile_command " $wl-bind_at_load"
+ func_append finalize_command " $wl-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ func_append new_libs " -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ ;;
+ *) func_append new_libs " $deplib" ;;
+ esac
+ done
+ compile_deplibs=$new_libs
+
+
+ func_append compile_command " $compile_deplibs"
+ func_append finalize_command " $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_rpath " $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append perm_rpath " $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) func_append dllsearchpath ":$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) func_append dllsearchpath ":$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath=$rpath
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs=$libdir
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ func_append rpath " $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) func_append finalize_perm_rpath " $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir=$hardcode_libdirs
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath=$rpath
+
+ if test -n "$libobjs" && test yes = "$build_old_libs"; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" false
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=:
+ case $host in
+ *cegcc* | *mingw32ce*)
+ # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+ wrappers_required=false
+ ;;
+ *cygwin* | *mingw* )
+ test yes = "$build_libtool_libs" || wrappers_required=false
+ ;;
+ *)
+ if test no = "$need_relink" || test yes != "$build_libtool_libs"; then
+ wrappers_required=false
+ fi
+ ;;
+ esac
+ $wrappers_required || {
+ # Replace the output file specification.
+ compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ link_command=$compile_command$compile_rpath
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.$objext"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.$objext"'
+ fi
+
+ exit $exit_status
+ }
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ func_append rpath "$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test yes = "$no_install"; then
+ # We don't need to create a wrapper script.
+ link_command=$compile_var$compile_command$compile_rpath
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ case $hardcode_action,$fast_install in
+ relink,*)
+ # Fast installation is not supported
+ link_command=$compile_var$compile_command$compile_rpath
+ relink_command=$finalize_var$finalize_command$finalize_rpath
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "'$output' will be relinked during installation"
+ ;;
+ *,yes)
+ link_command=$finalize_var$compile_command$finalize_rpath
+ relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+ ;;
+ *,no)
+ link_command=$compile_var$compile_command$compile_rpath
+ relink_command=$finalize_var$finalize_command$finalize_rpath
+ ;;
+ *,needless)
+ link_command=$finalize_var$compile_command$finalize_rpath
+ relink_command=
+ ;;
+ esac
+
+ # Replace the output file specification.
+ link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ if test -n "$postlink_cmds"; then
+ func_to_tool_file "$output_objdir/$outputname"
+ postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+ func_execute_cmds "$postlink_cmds" 'exit $?'
+ fi
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource=$output_path/$objdir/lt-$output_name.c
+ cwrapper=$output_path/$output_name.exe
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host"; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ case $build_libtool_libs in
+ convenience)
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs=$convenience
+ build_libtool_libs=no
+ ;;
+ module)
+ oldobjs=$libobjs_save
+ addlibs=$old_convenience
+ build_libtool_libs=no
+ ;;
+ *)
+ oldobjs="$old_deplibs $non_pic_objects"
+ $preload && test -f "$symfileobj" \
+ && func_append oldobjs " $symfileobj"
+ addlibs=$old_convenience
+ ;;
+ esac
+
+ if test -n "$addlibs"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $addlibs
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ func_append oldobjs " $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ echo "copying selected object files to avoid basename conflicts..."
+ gentop=$output_objdir/${outputname}x
+ func_append generated " $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase=$func_basename_result
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ func_append oldobjs " $gentop/$newobj"
+ ;;
+ *) func_append oldobjs " $obj" ;;
+ esac
+ done
+ fi
+ func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+ tool_oldlib=$func_to_tool_file_result
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ elif test -n "$archiver_list_spec"; then
+ func_verbose "using command file archive linking..."
+ for obj in $oldobjs
+ do
+ func_to_tool_file "$obj"
+ $ECHO "$func_to_tool_file_result"
+ done > $output_objdir/$libname.libcmd
+ func_to_tool_file "$output_objdir/$libname.libcmd"
+ oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj"; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test -z "$oldobjs"; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test yes = "$build_old_libs" && old_library=$libname.$libext
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+ if test yes = "$hardcode_automatic"; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test yes = "$installed"; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output=$output_objdir/${outputname}i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name=$func_basename_result
+ func_resolve_sysroot "$deplib"
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+ test -z "$libdir" && \
+ func_fatal_error "'$deplib' is not a valid libtool archive"
+ func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ -L*)
+ func_stripname -L '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -L$func_replace_sysroot_result"
+ ;;
+ -R*)
+ func_stripname -R '' "$deplib"
+ func_replace_sysroot "$func_stripname_result"
+ func_append newdependency_libs " -R$func_replace_sysroot_result"
+ ;;
+ *) func_append newdependency_libs " $deplib" ;;
+ esac
+ done
+ dependency_libs=$newdependency_libs
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name=$func_basename_result
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "'$lib' is not a valid libtool archive"
+ func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ *) func_append newdlfiles " $lib" ;;
+ esac
+ done
+ dlfiles=$newdlfiles
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name=$func_basename_result
+ eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "'$lib' is not a valid libtool archive"
+ func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles=$newdlprefiles
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlfiles " $abs"
+ done
+ dlfiles=$newdlfiles
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ func_append newdlprefiles " $abs"
+ done
+ dlprefiles=$newdlprefiles
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ # In fact, it would be nice if we could use this code for all target
+ # systems that can't hard-code library paths into their executables
+ # and that have no shared library path variable independent of PATH,
+ # but it turns out we can't easily determine that from inspecting
+ # libtool variables, so we have to hard-code the OSs to which it
+ # applies here; at the moment, that means platforms that use the PE
+ # object format with DLL files. See the long comment at the top of
+ # tests/bindir.at for full details.
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+ # If a -bindir argument was supplied, place the dll there.
+ if test -n "$bindir"; then
+ func_relative_path "$install_libdir" "$bindir"
+ tdlname=$func_relative_path_result/$dlname
+ else
+ # Otherwise fall back on heuristic.
+ tdlname=../bin/$dlname
+ fi
+ ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that cannot go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test no,yes = "$installed,$need_relink"; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+if test link = "$opt_mode" || test relink = "$opt_mode"; then
+ func_mode_link ${1+"$@"}
+fi
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $debug_cmd
+
+ RM=$nonopt
+ files=
+ rmforce=false
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic=$magic
+
+ for arg
+ do
+ case $arg in
+ -f) func_append RM " $arg"; rmforce=: ;;
+ -*) func_append RM " $arg" ;;
+ *) func_append files " $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir=$func_dirname_result
+ if test . = "$dir"; then
+ odir=$objdir
+ else
+ odir=$dir/$objdir
+ fi
+ func_basename "$file"
+ name=$func_basename_result
+ test uninstall = "$opt_mode" && odir=$dir
+
+ # Remember odir for removal later, being careful to avoid duplicates
+ if test clean = "$opt_mode"; then
+ case " $rmdirs " in
+ *" $odir "*) ;;
+ *) func_append rmdirs " $odir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif $rmforce; then
+ continue
+ fi
+
+ rmfiles=$file
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ func_append rmfiles " $odir/$n"
+ done
+ test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+ case $opt_mode in
+ clean)
+ case " $library_names " in
+ *" $dlname "*) ;;
+ *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+ esac
+ test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" && test none != "$pic_object"; then
+ func_append rmfiles " $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" && test none != "$non_pic_object"; then
+ func_append rmfiles " $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test clean = "$opt_mode"; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ func_append rmfiles " $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ func_append rmfiles " $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ func_append rmfiles " $odir/$name $odir/${name}S.$objext"
+ if test yes = "$fast_install" && test -n "$relink_command"; then
+ func_append rmfiles " $odir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name"; then
+ func_append rmfiles " $odir/lt-$noexename.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+
+ # Try to remove the $objdir's in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then
+ func_mode_uninstall ${1+"$@"}
+fi
+
+test -z "$opt_mode" && {
+ help=$generic_help
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode '$opt_mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# where we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
--- /dev/null
+#! /bin/sh
+# Common wrapper for a few potentially missing GNU programs.
+
+scriptversion=2013-10-28.13; # UTC
+
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try '$0 --help' for more information"
+ exit 1
+fi
+
+case $1 in
+
+ --is-lightweight)
+ # Used by our autoconf macros to check whether the available missing
+ # script is modern enough.
+ exit 0
+ ;;
+
+ --run)
+ # Back-compat with the calling convention used by older automake.
+ shift
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal autoconf autoheader autom4te automake makeinfo
+ bison yacc flex lex help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: unknown '$1' option"
+ echo 1>&2 "Try '$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch. This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+ msg="probably too old"
+elif test $st -eq 127; then
+ # Program was missing.
+ msg="missing on your system"
+else
+ # Program was found and executed, but failed. Give up.
+ exit $st
+fi
+
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+ case $1 in
+ aclocal|automake)
+ echo "The '$1' program is part of the GNU Automake package:"
+ echo "<$gnu_software_URL/automake>"
+ echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/autoconf>"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ autoconf|autom4te|autoheader)
+ echo "The '$1' program is part of the GNU Autoconf package:"
+ echo "<$gnu_software_URL/autoconf/>"
+ echo "It also requires GNU m4 and Perl in order to run:"
+ echo "<$gnu_software_URL/m4/>"
+ echo "<$perl_URL>"
+ ;;
+ esac
+}
+
+give_advice ()
+{
+ # Normalize program name to check for.
+ normalized_program=`echo "$1" | sed '
+ s/^gnu-//; t
+ s/^gnu//; t
+ s/^g//; t'`
+
+ printf '%s\n' "'$1' is $msg."
+
+ configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+ case $normalized_program in
+ autoconf*)
+ echo "You should only need it if you modified 'configure.ac',"
+ echo "or m4 files included by it."
+ program_details 'autoconf'
+ ;;
+ autoheader*)
+ echo "You should only need it if you modified 'acconfig.h' or"
+ echo "$configure_deps."
+ program_details 'autoheader'
+ ;;
+ automake*)
+ echo "You should only need it if you modified 'Makefile.am' or"
+ echo "$configure_deps."
+ program_details 'automake'
+ ;;
+ aclocal*)
+ echo "You should only need it if you modified 'acinclude.m4' or"
+ echo "$configure_deps."
+ program_details 'aclocal'
+ ;;
+ autom4te*)
+ echo "You might have modified some maintainer files that require"
+ echo "the 'autom4te' program to be rebuilt."
+ program_details 'autom4te'
+ ;;
+ bison*|yacc*)
+ echo "You should only need it if you modified a '.y' file."
+ echo "You may want to install the GNU Bison package:"
+ echo "<$gnu_software_URL/bison/>"
+ ;;
+ lex*|flex*)
+ echo "You should only need it if you modified a '.l' file."
+ echo "You may want to install the Fast Lexical Analyzer package:"
+ echo "<$flex_URL>"
+ ;;
+ help2man*)
+ echo "You should only need it if you modified a dependency" \
+ "of a man page."
+ echo "You may want to install the GNU Help2man package:"
+ echo "<$gnu_software_URL/help2man/>"
+ ;;
+ makeinfo*)
+ echo "You should only need it if you modified a '.texi' file, or"
+ echo "any other file indirectly affecting the aspect of the manual."
+ echo "You might want to install the Texinfo package:"
+ echo "<$gnu_software_URL/texinfo/>"
+ echo "The spurious makeinfo call might also be the consequence of"
+ echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+ echo "want to install GNU make:"
+ echo "<$gnu_software_URL/make/>"
+ ;;
+ *)
+ echo "You might have modified some files without having the proper"
+ echo "tools for further handling them. Check the 'README' file, it"
+ echo "often tells you about the needed prerequisites for installing"
+ echo "this package. You may also peek at any GNU archive site, in"
+ echo "case some other package contains this missing '$1' program."
+ ;;
+ esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+ -e '2,$s/^/ /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2013-07-13.22; # UTC
+
+# Copyright (C) 2011-2014 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+# Make unconditional expansion of undefined variables an error. This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+ echo "$0: $*" >&2
+ print_usage >&2
+ exit 2
+}
+
+print_usage ()
+{
+ cat <<END
+Usage:
+ test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+ [--expect-failure={yes|no}] [--color-tests={yes|no}]
+ [--enable-hard-errors={yes|no}] [--]
+ TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+test_name= # Used for reporting.
+log_file= # Where to save the output of the test script.
+trs_file= # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+ case $1 in
+ --help) print_usage; exit $?;;
+ --version) echo "test-driver $scriptversion"; exit $?;;
+ --test-name) test_name=$2; shift;;
+ --log-file) log_file=$2; shift;;
+ --trs-file) trs_file=$2; shift;;
+ --color-tests) color_tests=$2; shift;;
+ --expect-failure) expect_failure=$2; shift;;
+ --enable-hard-errors) enable_hard_errors=$2; shift;;
+ --) shift; break;;
+ -*) usage_error "invalid option: '$1'";;
+ *) break;;
+ esac
+ shift
+done
+
+missing_opts=
+test x"$test_name" = x && missing_opts="$missing_opts --test-name"
+test x"$log_file" = x && missing_opts="$missing_opts --log-file"
+test x"$trs_file" = x && missing_opts="$missing_opts --trs-file"
+if test x"$missing_opts" != x; then
+ usage_error "the following mandatory options are missing:$missing_opts"
+fi
+
+if test $# -eq 0; then
+ usage_error "missing argument"
+fi
+
+if test $color_tests = yes; then
+ # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+ red='\e[0;31m' # Red.
+ grn='\e[0;32m' # Green.
+ lgn='\e[1;32m' # Light green.
+ blu='\e[1;34m' # Blue.
+ mgn='\e[0;35m' # Magenta.
+ std='\e[m' # No color.
+else
+ red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+ tweaked_estatus=1
+else
+ tweaked_estatus=$estatus
+fi
+
+case $tweaked_estatus:$expect_failure in
+ 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+ 0:*) col=$grn res=PASS recheck=no gcopy=no;;
+ 77:*) col=$blu res=SKIP recheck=no gcopy=yes;;
+ 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;;
+ *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;;
+ *:*) col=$red res=FAIL recheck=yes gcopy=yes;;
+esac
+
+# Report the test outcome and exit status in the logs, so that one can
+# know whether the test passed or failed simply by looking at the '.log'
+# file, without the need of also peaking into the corresponding '.trs'
+# file (automake bug#11814).
+echo "$res $test_name (exit status: $estatus)" >>$log_file
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
--- /dev/null
+NULL =
+
+# Avoid need for python(pyparsing) by end users
+CLIENT_MARSHALLERS = \
+ generated_client_demarshallers.c \
+ generated_client_demarshallers1.c \
+ generated_client_marshallers.c \
+ generated_client_marshallers.h \
+ generated_client_marshallers1.c \
+ $(NULL)
+
+SERVER_MARSHALLERS = \
+ generated_server_demarshallers.c \
+ generated_server_marshallers.c \
+ generated_server_marshallers.h \
+ $(NULL)
+
+BUILT_SOURCES = $(CLIENT_MARSHALLERS) $(SERVER_MARSHALLERS)
+
+noinst_LTLIBRARIES = libspice-common.la libspice-common-server.la libspice-common-client.la
+libspice_common_la_SOURCES = \
+ backtrace.c \
+ backtrace.h \
+ bitops.h \
+ canvas_utils.c \
+ canvas_utils.h \
+ client_demarshallers.h \
+ client_marshallers.h \
+ draw.h \
+ lines.c \
+ lines.h \
+ log.c \
+ log.h \
+ lz.c \
+ lz.h \
+ lz_common.h \
+ lz_config.h \
+ macros.h \
+ marshaller.c \
+ marshaller.h \
+ mem.c \
+ mem.h \
+ messages.h \
+ pixman_utils.c \
+ pixman_utils.h \
+ quic.c \
+ quic.h \
+ quic_config.h \
+ rect.h \
+ region.c \
+ region.h \
+ ring.h \
+ rop3.c \
+ rop3.h \
+ snd_codec.c \
+ snd_codec.h \
+ spice_common.h \
+ ssl_verify.c \
+ ssl_verify.h \
+ verify.h \
+ $(NULL)
+
+# These 2 files are not build as part of spice-common
+# build system, but modules using spice-common will build
+# them with the appropriate options. We need to let automake
+# know that these are source files so that it can properly
+# track these files dependencies
+EXTRA_libspice_common_la_SOURCES = \
+ sw_canvas.c \
+ sw_canvas.h \
+ $(NULL)
+
+libspice_common_client_la_SOURCES = \
+ $(CLIENT_MARSHALLERS) \
+ $(NULL)
+
+libspice_common_server_la_SOURCES = \
+ $(SERVER_MARSHALLERS) \
+ $(NULL)
+
+libspice_common_server_la_CFLAGS = -DFIXME_SERVER_SMARTCARD
+
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(SPICE_COMMON_CFLAGS) \
+ $(PROTOCOL_CFLAGS) \
+ $(NULL)
+
+libspice_common_la_LIBADD = \
+ $(SPICE_COMMON_LIBS) \
+ $(NULL)
+
+MARSHALLERS_DEPS = \
+ $(top_srcdir)/python_modules/__init__.py \
+ $(top_srcdir)/python_modules/codegen.py \
+ $(top_srcdir)/python_modules/demarshal.py \
+ $(top_srcdir)/python_modules/marshal.py \
+ $(top_srcdir)/python_modules/ptypes.py \
+ $(top_srcdir)/python_modules/spice_parser.py \
+ $(top_srcdir)/spice_codegen.py \
+ $(NULL)
+
+# Note despite being autogenerated these are not part of CLEANFILES, they are
+# actually a part of EXTRA_DIST, to avoid the need for pyparser by end users
+generated_client_demarshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --client --include common/messages.h $< $@ >/dev/null
+
+generated_client_demarshallers1.c: $(top_srcdir)/spice1.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --client --include common/messages.h --prefix 1 --ptrsize 8 $< $@ >/dev/null
+
+generated_client_marshallers.h: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --client --include common/messages.h -H $< $@ >/dev/null
+
+generated_client_marshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include client_marshallers.h --client $< $@ >/dev/null
+
+generated_client_marshallers1.c: $(top_srcdir)/spice1.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include common/messages.h --include client_marshallers.h --client --prefix 1 --ptrsize 8 $< $@ >/dev/null
+
+generated_server_demarshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --server --include common/messages.h $< $@ >/dev/null
+
+STRUCTS = -M String -M Rect -M Point -M DisplayBase -M Fill -M Opaque -M Copy -M Blend -M Blackness -M Whiteness -M Invers -M Rop3 -M Stroke -M Text -M Transparent -M AlphaBlend -M Composite
+generated_server_marshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers $(STRUCTS) --server --include common/messages.h $< $@ >/dev/null
+
+generated_server_marshallers.h: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers $(STRUCTS) --server --include common/messages.h -H $< $@ >/dev/null
+
+EXTRA_DIST = \
+ $(CLIENT_MARSHALLERS) \
+ $(SERVER_MARSHALLERS) \
+ canvas_base.c \
+ canvas_base.h \
+ gdi_canvas.c \
+ gdi_canvas.h \
+ lz_compress_tmpl.c \
+ lz_decompress_tmpl.c \
+ quic_family_tmpl.c \
+ quic_rgb_tmpl.c \
+ quic_tmpl.c \
+ snd_codec.h \
+ $(NULL)
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = common
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_module.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libspice_common_client_la_LIBADD =
+am__objects_1 =
+am__objects_2 = generated_client_demarshallers.lo \
+ generated_client_demarshallers1.lo \
+ generated_client_marshallers.lo \
+ generated_client_marshallers1.lo $(am__objects_1)
+am_libspice_common_client_la_OBJECTS = $(am__objects_2) \
+ $(am__objects_1)
+libspice_common_client_la_OBJECTS = \
+ $(am_libspice_common_client_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libspice_common_server_la_LIBADD =
+am__objects_3 = \
+ libspice_common_server_la-generated_server_demarshallers.lo \
+ libspice_common_server_la-generated_server_marshallers.lo \
+ $(am__objects_1)
+am_libspice_common_server_la_OBJECTS = $(am__objects_3) \
+ $(am__objects_1)
+libspice_common_server_la_OBJECTS = \
+ $(am_libspice_common_server_la_OBJECTS)
+libspice_common_server_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(libspice_common_server_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am__DEPENDENCIES_1 =
+libspice_common_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_libspice_common_la_OBJECTS = backtrace.lo canvas_utils.lo lines.lo \
+ log.lo lz.lo marshaller.lo mem.lo pixman_utils.lo quic.lo \
+ region.lo rop3.lo snd_codec.lo ssl_verify.lo $(am__objects_1)
+libspice_common_la_OBJECTS = $(am_libspice_common_la_OBJECTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libspice_common_client_la_SOURCES) \
+ $(libspice_common_server_la_SOURCES) \
+ $(libspice_common_la_SOURCES) \
+ $(EXTRA_libspice_common_la_SOURCES)
+DIST_SOURCES = $(libspice_common_client_la_SOURCES) \
+ $(libspice_common_server_la_SOURCES) \
+ $(libspice_common_la_SOURCES) \
+ $(EXTRA_libspice_common_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CELT051_CFLAGS = @CELT051_CFLAGS@
+CELT051_LIBS = @CELT051_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPUS_CFLAGS = @OPUS_CFLAGS@
+OPUS_LIBS = @OPUS_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PROTOCOL_CFLAGS = @PROTOCOL_CFLAGS@
+PROTOCOL_LIBS = @PROTOCOL_LIBS@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_COMMON_CFLAGS = @SPICE_COMMON_CFLAGS@
+SPICE_COMMON_LIBS = @SPICE_COMMON_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+
+# Avoid need for python(pyparsing) by end users
+CLIENT_MARSHALLERS = \
+ generated_client_demarshallers.c \
+ generated_client_demarshallers1.c \
+ generated_client_marshallers.c \
+ generated_client_marshallers.h \
+ generated_client_marshallers1.c \
+ $(NULL)
+
+SERVER_MARSHALLERS = \
+ generated_server_demarshallers.c \
+ generated_server_marshallers.c \
+ generated_server_marshallers.h \
+ $(NULL)
+
+BUILT_SOURCES = $(CLIENT_MARSHALLERS) $(SERVER_MARSHALLERS)
+noinst_LTLIBRARIES = libspice-common.la libspice-common-server.la libspice-common-client.la
+libspice_common_la_SOURCES = \
+ backtrace.c \
+ backtrace.h \
+ bitops.h \
+ canvas_utils.c \
+ canvas_utils.h \
+ client_demarshallers.h \
+ client_marshallers.h \
+ draw.h \
+ lines.c \
+ lines.h \
+ log.c \
+ log.h \
+ lz.c \
+ lz.h \
+ lz_common.h \
+ lz_config.h \
+ macros.h \
+ marshaller.c \
+ marshaller.h \
+ mem.c \
+ mem.h \
+ messages.h \
+ pixman_utils.c \
+ pixman_utils.h \
+ quic.c \
+ quic.h \
+ quic_config.h \
+ rect.h \
+ region.c \
+ region.h \
+ ring.h \
+ rop3.c \
+ rop3.h \
+ snd_codec.c \
+ snd_codec.h \
+ spice_common.h \
+ ssl_verify.c \
+ ssl_verify.h \
+ verify.h \
+ $(NULL)
+
+
+# These 2 files are not build as part of spice-common
+# build system, but modules using spice-common will build
+# them with the appropriate options. We need to let automake
+# know that these are source files so that it can properly
+# track these files dependencies
+EXTRA_libspice_common_la_SOURCES = \
+ sw_canvas.c \
+ sw_canvas.h \
+ $(NULL)
+
+libspice_common_client_la_SOURCES = \
+ $(CLIENT_MARSHALLERS) \
+ $(NULL)
+
+libspice_common_server_la_SOURCES = \
+ $(SERVER_MARSHALLERS) \
+ $(NULL)
+
+libspice_common_server_la_CFLAGS = -DFIXME_SERVER_SMARTCARD
+AM_CPPFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(SPICE_COMMON_CFLAGS) \
+ $(PROTOCOL_CFLAGS) \
+ $(NULL)
+
+libspice_common_la_LIBADD = \
+ $(SPICE_COMMON_LIBS) \
+ $(NULL)
+
+MARSHALLERS_DEPS = \
+ $(top_srcdir)/python_modules/__init__.py \
+ $(top_srcdir)/python_modules/codegen.py \
+ $(top_srcdir)/python_modules/demarshal.py \
+ $(top_srcdir)/python_modules/marshal.py \
+ $(top_srcdir)/python_modules/ptypes.py \
+ $(top_srcdir)/python_modules/spice_parser.py \
+ $(top_srcdir)/spice_codegen.py \
+ $(NULL)
+
+STRUCTS = -M String -M Rect -M Point -M DisplayBase -M Fill -M Opaque -M Copy -M Blend -M Blackness -M Whiteness -M Invers -M Rop3 -M Stroke -M Text -M Transparent -M AlphaBlend -M Composite
+EXTRA_DIST = \
+ $(CLIENT_MARSHALLERS) \
+ $(SERVER_MARSHALLERS) \
+ canvas_base.c \
+ canvas_base.h \
+ gdi_canvas.c \
+ gdi_canvas.h \
+ lz_compress_tmpl.c \
+ lz_decompress_tmpl.c \
+ quic_family_tmpl.c \
+ quic_rgb_tmpl.c \
+ quic_tmpl.c \
+ snd_codec.h \
+ $(NULL)
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign common/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign common/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libspice-common-client.la: $(libspice_common_client_la_OBJECTS) $(libspice_common_client_la_DEPENDENCIES) $(EXTRA_libspice_common_client_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libspice_common_client_la_OBJECTS) $(libspice_common_client_la_LIBADD) $(LIBS)
+
+libspice-common-server.la: $(libspice_common_server_la_OBJECTS) $(libspice_common_server_la_DEPENDENCIES) $(EXTRA_libspice_common_server_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libspice_common_server_la_LINK) $(libspice_common_server_la_OBJECTS) $(libspice_common_server_la_LIBADD) $(LIBS)
+
+libspice-common.la: $(libspice_common_la_OBJECTS) $(libspice_common_la_DEPENDENCIES) $(EXTRA_libspice_common_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libspice_common_la_OBJECTS) $(libspice_common_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backtrace.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/canvas_utils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generated_client_demarshallers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generated_client_demarshallers1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generated_client_marshallers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generated_client_marshallers1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libspice_common_server_la-generated_server_demarshallers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libspice_common_server_la-generated_server_marshallers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lines.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lz.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/marshaller.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pixman_utils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quic.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/region.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rop3.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snd_codec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_verify.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sw_canvas.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+libspice_common_server_la-generated_server_demarshallers.lo: generated_server_demarshallers.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libspice_common_server_la_CFLAGS) $(CFLAGS) -MT libspice_common_server_la-generated_server_demarshallers.lo -MD -MP -MF $(DEPDIR)/libspice_common_server_la-generated_server_demarshallers.Tpo -c -o libspice_common_server_la-generated_server_demarshallers.lo `test -f 'generated_server_demarshallers.c' || echo '$(srcdir)/'`generated_server_demarshallers.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libspice_common_server_la-generated_server_demarshallers.Tpo $(DEPDIR)/libspice_common_server_la-generated_server_demarshallers.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='generated_server_demarshallers.c' object='libspice_common_server_la-generated_server_demarshallers.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libspice_common_server_la_CFLAGS) $(CFLAGS) -c -o libspice_common_server_la-generated_server_demarshallers.lo `test -f 'generated_server_demarshallers.c' || echo '$(srcdir)/'`generated_server_demarshallers.c
+
+libspice_common_server_la-generated_server_marshallers.lo: generated_server_marshallers.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libspice_common_server_la_CFLAGS) $(CFLAGS) -MT libspice_common_server_la-generated_server_marshallers.lo -MD -MP -MF $(DEPDIR)/libspice_common_server_la-generated_server_marshallers.Tpo -c -o libspice_common_server_la-generated_server_marshallers.lo `test -f 'generated_server_marshallers.c' || echo '$(srcdir)/'`generated_server_marshallers.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libspice_common_server_la-generated_server_marshallers.Tpo $(DEPDIR)/libspice_common_server_la-generated_server_marshallers.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='generated_server_marshallers.c' object='libspice_common_server_la-generated_server_marshallers.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libspice_common_server_la_CFLAGS) $(CFLAGS) -c -o libspice_common_server_la-generated_server_marshallers.lo `test -f 'generated_server_marshallers.c' || echo '$(srcdir)/'`generated_server_marshallers.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: all check install install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Note despite being autogenerated these are not part of CLEANFILES, they are
+# actually a part of EXTRA_DIST, to avoid the need for pyparser by end users
+generated_client_demarshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --client --include common/messages.h $< $@ >/dev/null
+
+generated_client_demarshallers1.c: $(top_srcdir)/spice1.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --client --include common/messages.h --prefix 1 --ptrsize 8 $< $@ >/dev/null
+
+generated_client_marshallers.h: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --client --include common/messages.h -H $< $@ >/dev/null
+
+generated_client_marshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include client_marshallers.h --client $< $@ >/dev/null
+
+generated_client_marshallers1.c: $(top_srcdir)/spice1.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include common/messages.h --include client_marshallers.h --client --prefix 1 --ptrsize 8 $< $@ >/dev/null
+
+generated_server_demarshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --server --include common/messages.h $< $@ >/dev/null
+generated_server_marshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers $(STRUCTS) --server --include common/messages.h $< $@ >/dev/null
+
+generated_server_marshallers.h: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers $(STRUCTS) --server --include common/messages.h -H $< $@ >/dev/null
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Taken from xserver os/backtrace.c:
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spice_common.h"
+
+#include <unistd.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#ifndef __MINGW32__
+#include <sys/wait.h>
+#endif
+
+#define GSTACK_PATH "/usr/bin/gstack"
+
+#if HAVE_EXECINFO_H
+#include <execinfo.h>
+
+static void spice_backtrace_backtrace(void)
+{
+ void *array[100];
+ int size;
+
+ size = backtrace(array, sizeof(array)/sizeof(array[0]));
+ backtrace_symbols_fd(array, size, STDERR_FILENO);
+}
+#else
+static void spice_backtrace_backtrace(void)
+{
+}
+#endif
+
+/* XXX perhaps gstack can be available in windows but pipe/waitpid isn't,
+ * so until it is ported properly just compile it out, we lose the
+ * backtrace only. */
+#ifndef __MINGW32__
+static int spice_backtrace_gstack(void)
+{
+ pid_t kidpid;
+ int pipefd[2];
+
+ if (pipe(pipefd) != 0) {
+ return -1;
+ }
+
+ kidpid = fork();
+
+ if (kidpid == -1) {
+ /* ERROR */
+ return -1;
+ } else if (kidpid == 0) {
+ /* CHILD */
+ char parent[16];
+
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ dup2(pipefd[1],STDOUT_FILENO);
+ close(STDERR_FILENO);
+
+ snprintf(parent, sizeof(parent), "%d", getppid());
+ execle(GSTACK_PATH, "gstack", parent, NULL, NULL);
+ exit(1);
+ } else {
+ /* PARENT */
+ char btline[256];
+ int kidstat;
+ int bytesread;
+ int done = 0;
+
+ close(pipefd[1]);
+
+ while (!done) {
+ bytesread = read(pipefd[0], btline, sizeof(btline) - 1);
+
+ if (bytesread > 0) {
+ btline[bytesread] = 0;
+ fprintf(stderr, "%s", btline);
+ }
+ else if ((bytesread == 0) ||
+ ((errno != EINTR) && (errno != EAGAIN))) {
+ done = 1;
+ }
+ }
+ close(pipefd[0]);
+ waitpid(kidpid, &kidstat, 0);
+ if (kidstat != 0)
+ return -1;
+ }
+ return 0;
+}
+#else
+static int spice_backtrace_gstack(void)
+{
+ /* empty failing implementation */
+ return -1;
+}
+#endif
+
+void spice_backtrace(void)
+{
+ int ret = -1;
+
+ if (!access(GSTACK_PATH, X_OK)) {
+ ret = spice_backtrace_gstack();
+ }
+ if (ret != 0) {
+ spice_backtrace_backtrace();
+ }
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef BACKTRACE_H
+#define BACKTRACE_H
+
+#include <spice/macros.h>
+
+SPICE_BEGIN_DECLS
+
+#if defined(WIN32) && !defined(__MINGW32__)
+#define spice_backtrace()
+#else
+void spice_backtrace(void);
+#endif
+
+SPICE_END_DECLS
+
+#endif // BACKTRACE_H
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef BITOPS_H
+#define BITOPS_H
+
+#include <spice/macros.h>
+
+SPICE_BEGIN_DECLS
+
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+static inline int spice_bit_find_msb(unsigned int val)
+{
+ int ret;
+
+ asm ("bsrl %1,%0\n\t"
+ "jnz 1f\n\t"
+ "movl $-1,%0\n"
+ "1:"
+ : "=r"(ret) : "r"(val));
+ return ret + 1;
+}
+
+#elif defined(WIN32) && !defined(_WIN64)
+static inline int spice_bit_find_msb(uint32_t val)
+{
+ uint32_t r;
+ __asm {
+ bsr eax, val
+ jnz found
+ mov eax, -1
+
+found:
+ mov r, eax
+ }
+ return r + 1;
+}
+
+#else
+static inline int spice_bit_find_msb(unsigned int val)
+{
+ signed char index = 31;
+
+ if(val == 0) {
+ return 0;
+ }
+
+ do {
+ if(val & 0x80000000) {
+ break;
+ }
+ val <<= 1;
+ } while(--index >= 0);
+
+ return index+1;
+}
+
+#endif
+
+static inline int spice_bit_next_pow2(unsigned int val)
+{
+ if ((val & (val - 1)) == 0) {
+ return val;
+ }
+ return 1 << spice_bit_find_msb(val);
+}
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <math.h>
+
+#ifdef USE_LZ4
+#ifndef WIN32
+#include <arpa/inet.h>
+#endif
+#include <lz4.h>
+#endif
+#include <spice/macros.h>
+#include "log.h"
+#include "quic.h"
+#include "lz.h"
+#include "canvas_base.h"
+#include "pixman_utils.h"
+#include "canvas_utils.h"
+#include "rect.h"
+#include "lines.h"
+#include "rop3.h"
+#include "mem.h"
+#include "macros.h"
+
+#define ROUND(_x) ((int)floor((_x) + 0.5))
+
+ static inline int fix_to_int(SPICE_FIXED28_4 fixed)
+{
+ int val, rem;
+
+ rem = fixed & 0x0f;
+ val = fixed >> 4;
+ if (rem > 8) {
+ val++;
+ }
+ return val;
+}
+
+ static inline SPICE_FIXED28_4 int_to_fix(int v)
+{
+ return v << 4;
+}
+
+static inline double fix_to_double(SPICE_FIXED28_4 fixed)
+{
+ return (double)(fixed & 0x0f) / 0x0f + (fixed >> 4);
+}
+
+static inline uint16_t rgb_32_to_16_555(uint32_t color)
+{
+ return
+ (((color) >> 3) & 0x001f) |
+ (((color) >> 6) & 0x03e0) |
+ (((color) >> 9) & 0x7c00);
+}
+static inline uint16_t rgb_32_to_16_565(uint32_t color)
+{
+ return
+ (((color) >> 3) & 0x001f) |
+ (((color) >> 5) & 0x07e0) |
+ (((color) >> 8) & 0xf800);
+}
+
+static inline uint32_t canvas_16bpp_to_32bpp(uint32_t color)
+{
+ uint32_t ret;
+
+ ret = ((color & 0x001f) << 3) | ((color & 0x001c) >> 2);
+ ret |= ((color & 0x03e0) << 6) | ((color & 0x0380) << 1);
+ ret |= ((color & 0x7c00) << 9) | ((color & 0x7000) << 4);
+
+ return ret;
+}
+#if defined(WIN32) && defined(GDI_CANVAS)
+static HDC create_compatible_dc()
+{
+ HDC dc = CreateCompatibleDC(NULL);
+
+ spice_return_val_if_fail(dc != NULL, NULL);
+
+ return dc;
+}
+
+#endif
+
+typedef struct LzData {
+ LzUsrContext usr;
+ LzContext *lz;
+ LzDecodeUsrData decode_data;
+ jmp_buf jmp_env;
+ char message_buf[512];
+} LzData;
+
+typedef struct GlzData {
+ SpiceGlzDecoder *decoder;
+ LzDecodeUsrData decode_data;
+} GlzData;
+
+typedef struct QuicData {
+ QuicUsrContext usr;
+ QuicContext *quic;
+ jmp_buf jmp_env;
+ char message_buf[512];
+ SpiceChunks *chunks;
+ uint32_t current_chunk;
+} QuicData;
+
+typedef struct CanvasBase {
+ SpiceCanvas parent;
+ uint32_t color_shift;
+ uint32_t color_mask;
+ QuicData quic_data;
+
+ uint32_t format;
+ int width;
+ int height;
+ pixman_region32_t canvas_region;
+
+ SpiceImageCache *bits_cache;
+#ifdef SW_CANVAS_CACHE
+ SpicePaletteCache *palette_cache;
+#endif
+#ifdef WIN32
+ HDC dc;
+#endif
+
+ SpiceImageSurfaces *surfaces;
+
+ LzData lz_data;
+ GlzData glz_data;
+ SpiceJpegDecoder* jpeg;
+ SpiceZlibDecoder* zlib;
+
+ void *usr_data;
+ spice_destroy_fn_t usr_data_destroy;
+} CanvasBase;
+
+typedef enum {
+ ROP_INPUT_SRC,
+ ROP_INPUT_BRUSH,
+ ROP_INPUT_DEST
+} ROPInput;
+
+static SpiceROP ropd_descriptor_to_rop(int desc,
+ ROPInput src_input,
+ ROPInput dest_input)
+{
+ int old;
+ int invert_masks[] = {
+ SPICE_ROPD_INVERS_SRC,
+ SPICE_ROPD_INVERS_BRUSH,
+ SPICE_ROPD_INVERS_DEST
+ };
+
+ old = desc;
+
+ desc &= ~(SPICE_ROPD_INVERS_SRC | SPICE_ROPD_INVERS_DEST);
+ if (old & invert_masks[src_input]) {
+ desc |= SPICE_ROPD_INVERS_SRC;
+ }
+
+ if (old & invert_masks[dest_input]) {
+ desc |= SPICE_ROPD_INVERS_DEST;
+ }
+
+ if (desc & SPICE_ROPD_OP_PUT) {
+ if (desc & SPICE_ROPD_INVERS_SRC) {
+ if (desc & SPICE_ROPD_INVERS_RES) {
+ return SPICE_ROP_COPY;
+ }
+ return SPICE_ROP_COPY_INVERTED;
+ } else {
+ if (desc & SPICE_ROPD_INVERS_RES) {
+ return SPICE_ROP_COPY_INVERTED;
+ }
+ return SPICE_ROP_COPY;
+ }
+ } else if (desc & SPICE_ROPD_OP_OR) {
+
+ if (desc & SPICE_ROPD_INVERS_RES) {
+ if (desc & SPICE_ROPD_INVERS_SRC) {
+ if (desc & SPICE_ROPD_INVERS_DEST) {
+ /* !(!src or !dest) == src and dest*/
+ return SPICE_ROP_AND;
+ } else {
+ /* ! (!src or dest) = src and !dest*/
+ return SPICE_ROP_AND_REVERSE;
+ }
+ } else {
+ if (desc & SPICE_ROPD_INVERS_DEST) {
+ /* !(src or !dest) == !src and dest */
+ return SPICE_ROP_AND_INVERTED;
+ } else {
+ /* !(src or dest) */
+ return SPICE_ROP_NOR;
+ }
+ }
+ } else {
+ if (desc & SPICE_ROPD_INVERS_SRC) {
+ if (desc & SPICE_ROPD_INVERS_DEST) {
+ /* !src or !dest == !(src and dest)*/
+ return SPICE_ROP_NAND;
+ } else {
+ /* !src or dest */
+ return SPICE_ROP_OR_INVERTED;
+ }
+ } else {
+ if (desc & SPICE_ROPD_INVERS_DEST) {
+ /* src or !dest */
+ return SPICE_ROP_OR_REVERSE;
+ } else {
+ /* src or dest */
+ return SPICE_ROP_OR;
+ }
+ }
+ }
+
+ } else if (desc & SPICE_ROPD_OP_AND) {
+
+ if (desc & SPICE_ROPD_INVERS_RES) {
+ if (desc & SPICE_ROPD_INVERS_SRC) {
+ if (desc & SPICE_ROPD_INVERS_DEST) {
+ /* !(!src and !dest) == src or dest*/
+ return SPICE_ROP_OR;
+ } else {
+ /* ! (!src and dest) = src or !dest*/
+ return SPICE_ROP_OR_REVERSE;
+ }
+ } else {
+ if (desc & SPICE_ROPD_INVERS_DEST) {
+ /* !(src and !dest) == !src or dest */
+ return SPICE_ROP_OR_INVERTED;
+ } else {
+ /* !(src and dest) */
+ return SPICE_ROP_NAND;
+ }
+ }
+ } else {
+ if (desc & SPICE_ROPD_INVERS_SRC) {
+ if (desc & SPICE_ROPD_INVERS_DEST) {
+ /* !src and !dest == !(src or dest)*/
+ return SPICE_ROP_NOR;
+ } else {
+ /* !src and dest */
+ return SPICE_ROP_AND_INVERTED;
+ }
+ } else {
+ if (desc & SPICE_ROPD_INVERS_DEST) {
+ /* src and !dest */
+ return SPICE_ROP_AND_REVERSE;
+ } else {
+ /* src and dest */
+ return SPICE_ROP_AND;
+ }
+ }
+ }
+
+ } else if (desc & SPICE_ROPD_OP_XOR) {
+
+ if (desc & SPICE_ROPD_INVERS_RES) {
+ if (desc & SPICE_ROPD_INVERS_SRC) {
+ if (desc & SPICE_ROPD_INVERS_DEST) {
+ /* !(!src xor !dest) == !src xor dest */
+ return SPICE_ROP_EQUIV;
+ } else {
+ /* ! (!src xor dest) = src xor dest*/
+ return SPICE_ROP_XOR;
+ }
+ } else {
+ if (desc & SPICE_ROPD_INVERS_DEST) {
+ /* !(src xor !dest) == src xor dest */
+ return SPICE_ROP_XOR;
+ } else {
+ /* !(src xor dest) */
+ return SPICE_ROP_EQUIV;
+ }
+ }
+ } else {
+ if (desc & SPICE_ROPD_INVERS_SRC) {
+ if (desc & SPICE_ROPD_INVERS_DEST) {
+ /* !src xor !dest == src xor dest */
+ return SPICE_ROP_XOR;
+ } else {
+ /* !src xor dest */
+ return SPICE_ROP_EQUIV;
+ }
+ } else {
+ if (desc & SPICE_ROPD_INVERS_DEST) {
+ /* src xor !dest */
+ return SPICE_ROP_EQUIV;
+ } else {
+ /* src xor dest */
+ return SPICE_ROP_XOR;
+ }
+ }
+ }
+
+ } else if (desc & SPICE_ROPD_OP_BLACKNESS) {
+ return SPICE_ROP_CLEAR;
+ } else if (desc & SPICE_ROPD_OP_WHITENESS) {
+ return SPICE_ROP_SET;
+ } else if (desc & SPICE_ROPD_OP_INVERS) {
+ return SPICE_ROP_INVERT;
+ }
+ return SPICE_ROP_COPY;
+}
+
+//#define DEBUG_DUMP_COMPRESS
+#ifdef DEBUG_DUMP_COMPRESS
+static void dump_surface(pixman_image_t *surface, int cache);
+#endif
+
+
+static pixman_format_code_t canvas_get_target_format(CanvasBase *canvas,
+ int source_has_alpha)
+{
+ pixman_format_code_t format;
+
+ /* Convert to target surface format */
+ format = spice_surface_format_to_pixman (canvas->format);
+
+ if (source_has_alpha) {
+ /* Even though the destination has no alpha, we make the source
+ * remember there are alpha bits instead of throwing away this
+ * information. The results are the same if alpha is not
+ * interpreted, and if need to interpret alpha, don't use
+ * conversion to target format.
+ * This is needed for instance when doing the final
+ * canvas_get_target_format() in canvas_get_image_internal
+ * as otherwise we wouldn't know if the bitmap source
+ * really had alpha.
+ */
+ if (format == PIXMAN_x8r8g8b8) {
+ format = PIXMAN_a8r8g8b8;
+ }
+ } else { /* !source_has_alpha */
+ /* If the source doesn't have alpha, but the destination has,
+ don't convert to alpha, since that would just do an unnecessary
+ copy to fill the alpha bytes with 0xff which is not expected if
+ we just use the raw bits, (and handled implicitly by pixman if
+ we're interpreting data) */
+ if (format == PIXMAN_a8r8g8b8) {
+ format = PIXMAN_x8r8g8b8;
+ }
+ }
+
+ return format;
+}
+
+static pixman_image_t *canvas_get_quic(CanvasBase *canvas, SpiceImage *image,
+ int want_original)
+{
+ pixman_image_t *surface = NULL;
+ QuicData *quic_data = &canvas->quic_data;
+ QuicImageType type, as_type;
+ pixman_format_code_t pixman_format;
+ uint8_t *dest;
+ int stride;
+ int width;
+ int height;
+
+ if (setjmp(quic_data->jmp_env)) {
+ pixman_image_unref(surface);
+ spice_warning("%s", quic_data->message_buf);
+ return NULL;
+ }
+
+ quic_data->chunks = image->u.quic.data;
+ quic_data->current_chunk = 0;
+
+ if (quic_decode_begin(quic_data->quic,
+ (uint32_t *)image->u.quic.data->chunk[0].data,
+ image->u.quic.data->chunk[0].len >> 2,
+ &type, &width, &height) == QUIC_ERROR) {
+ spice_warning("quic decode begin failed");
+ return NULL;
+ }
+
+ switch (type) {
+ case QUIC_IMAGE_TYPE_RGBA:
+ as_type = QUIC_IMAGE_TYPE_RGBA;
+ pixman_format = PIXMAN_LE_a8r8g8b8;
+ break;
+ case QUIC_IMAGE_TYPE_RGB32:
+ case QUIC_IMAGE_TYPE_RGB24:
+ as_type = QUIC_IMAGE_TYPE_RGB32;
+ pixman_format = PIXMAN_LE_x8r8g8b8;
+ break;
+ case QUIC_IMAGE_TYPE_RGB16:
+ if (!want_original &&
+ (canvas->format == SPICE_SURFACE_FMT_32_xRGB ||
+ canvas->format == SPICE_SURFACE_FMT_32_ARGB)) {
+ as_type = QUIC_IMAGE_TYPE_RGB32;
+ pixman_format = PIXMAN_LE_x8r8g8b8;
+ } else {
+ as_type = QUIC_IMAGE_TYPE_RGB16;
+ pixman_format = PIXMAN_x1r5g5b5;
+ }
+ break;
+ case QUIC_IMAGE_TYPE_INVALID:
+ case QUIC_IMAGE_TYPE_GRAY:
+ default:
+ spice_warn_if_reached();
+ return NULL;
+ }
+
+ spice_return_val_if_fail((uint32_t)width == image->descriptor.width, NULL);
+ spice_return_val_if_fail((uint32_t)height == image->descriptor.height, NULL);
+
+ surface = surface_create(
+#ifdef WIN32
+ canvas->dc,
+#endif
+ pixman_format,
+ width, height, FALSE);
+
+ spice_return_val_if_fail(surface != NULL, NULL);
+
+ dest = (uint8_t *)pixman_image_get_data(surface);
+ stride = pixman_image_get_stride(surface);
+ if (quic_decode(quic_data->quic, as_type,
+ dest, stride) == QUIC_ERROR) {
+ pixman_image_unref(surface);
+ spice_warning("quic decode failed");
+ return NULL;
+ }
+
+#ifdef DEBUG_DUMP_COMPRESS
+ dump_surface(surface, 0);
+#endif
+ return surface;
+}
+
+
+//#define DUMP_JPEG
+#ifdef DUMP_JPEG
+static int jpeg_id = 0;
+static void dump_jpeg(uint8_t* data, int data_size)
+{
+ char file_str[200];
+ uint32_t id = ++jpeg_id;
+
+#ifdef WIN32
+ sprintf(file_str, "c:\\tmp\\spice_dump\\%u.jpg", id);
+#else
+ sprintf(file_str, "/tmp/spice_dump/%u.jpg", id);
+#endif
+
+ FILE *f = fopen(file_str, "wb");
+ if (!f) {
+ return;
+ }
+
+ fwrite(data, 1, data_size, f);
+ fclose(f);
+}
+#endif
+
+static pixman_image_t *canvas_get_jpeg(CanvasBase *canvas, SpiceImage *image)
+{
+ pixman_image_t *surface = NULL;
+ int stride;
+ int width;
+ int height;
+ uint8_t *dest;
+
+ spice_return_val_if_fail(image->u.jpeg.data->num_chunks == 1, NULL);
+ canvas->jpeg->ops->begin_decode(canvas->jpeg, image->u.jpeg.data->chunk[0].data, image->u.jpeg.data->chunk[0].len,
+ &width, &height);
+ spice_return_val_if_fail((uint32_t)width == image->descriptor.width, NULL);
+ spice_return_val_if_fail((uint32_t)height == image->descriptor.height, NULL);
+
+ surface = surface_create(
+#ifdef WIN32
+ canvas->dc,
+#endif
+ PIXMAN_LE_x8r8g8b8,
+ width, height, FALSE);
+ if (surface == NULL) {
+ spice_warning("create surface failed");
+ return NULL;
+ }
+
+ dest = (uint8_t *)pixman_image_get_data(surface);
+ stride = pixman_image_get_stride(surface);
+
+ canvas->jpeg->ops->decode(canvas->jpeg, dest, stride, SPICE_BITMAP_FMT_32BIT);
+
+#ifdef DUMP_JPEG
+ dump_jpeg(image->u.jpeg.data, image->u.jpeg.data_size);
+#endif
+ return surface;
+}
+
+#if defined(USE_LZ4) || defined(SW_CANVAS_CACHE)
+static void canvas_fix_alignment(uint8_t *bits,
+ int stride_encoded, int stride_pixman,
+ int height)
+{
+ if (stride_pixman > stride_encoded) {
+ // Fix the row alignment
+ int row;
+ uint8_t *dest = bits;
+ for (row = height - 1; row > 0; --row) {
+ uint32_t *dest_aligned, *dest_misaligned;
+ dest_aligned = (uint32_t *)(dest + stride_pixman*row);
+ dest_misaligned = (uint32_t*)(dest + stride_encoded*row);
+ memmove(dest_aligned, dest_misaligned, stride_encoded);
+ }
+ }
+}
+#endif
+
+#ifdef USE_LZ4
+static pixman_image_t *canvas_get_lz4(CanvasBase *canvas, SpiceImage *image)
+{
+ pixman_image_t *surface = NULL;
+ int dec_size, enc_size, available;
+ int stride, stride_abs, stride_encoded;
+ uint8_t *dest, *data, *data_end, *bits;
+ int width, height, top_down;
+ LZ4_streamDecode_t *stream;
+ uint8_t spice_format;
+ pixman_format_code_t format;
+
+ spice_chunks_linearize(image->u.lz4.data);
+ data = image->u.lz4.data->chunk[0].data;
+ data_end = data + image->u.lz4.data->chunk[0].len;
+ width = image->descriptor.width;
+ stride_encoded = width;
+ height = image->descriptor.height;
+ top_down = *(data++);
+ spice_format = *(data++);
+ switch (spice_format) {
+ case SPICE_BITMAP_FMT_16BIT:
+ format = PIXMAN_x1r5g5b5;
+ stride_encoded *= 2;
+ break;
+ case SPICE_BITMAP_FMT_24BIT:
+ format = PIXMAN_LE_r8g8b8;
+ stride_encoded *= 3;
+ break;
+ case SPICE_BITMAP_FMT_32BIT:
+ format = PIXMAN_LE_x8r8g8b8;
+ stride_encoded *= 4;
+ break;
+ case SPICE_BITMAP_FMT_RGBA:
+ format = PIXMAN_LE_a8r8g8b8;
+ stride_encoded *= 4;
+ break;
+ default:
+ spice_warning("Unsupported bitmap format %d with LZ4\n", spice_format);
+ return NULL;
+ }
+
+ surface = surface_create(
+#ifdef WIN32
+ canvas->dc,
+#endif
+ format,
+ width, height, top_down);
+ if (surface == NULL) {
+ spice_warning("create surface failed");
+ return NULL;
+ }
+
+ stream = LZ4_createStreamDecode();
+ dest = (uint8_t *)pixman_image_get_data(surface);
+ stride = pixman_image_get_stride(surface);
+ stride_abs = abs(stride);
+ available = height * stride_abs;
+ if (!top_down) {
+ dest -= (stride_abs * (height - 1));
+ }
+ bits = dest;
+
+ do {
+ // Read next compressed block
+ enc_size = ntohl(*((uint32_t *)data));
+ data += 4;
+ dec_size = LZ4_decompress_safe_continue(stream, (const char *) data,
+ (char *) dest, enc_size, available);
+ if (dec_size <= 0) {
+ spice_warning("Error decoding LZ4 block\n");
+ pixman_image_unref(surface);
+ surface = NULL;
+ break;
+ }
+ dest += dec_size;
+ available -= dec_size;
+ data += enc_size;
+ } while (data < data_end);
+
+ canvas_fix_alignment(bits, stride_encoded, stride_abs, height);
+
+ LZ4_freeStreamDecode(stream);
+ return surface;
+}
+#endif
+
+static pixman_image_t *canvas_get_jpeg_alpha(CanvasBase *canvas, SpiceImage *image)
+{
+ pixman_image_t *surface = NULL;
+ int stride;
+ int width;
+ int height;
+ uint8_t *dest;
+ int alpha_top_down = FALSE;
+ LzData *lz_data = &canvas->lz_data;
+ LzImageType lz_alpha_type;
+ uint8_t *comp_alpha_buf = NULL;
+ uint8_t *decomp_alpha_buf = NULL;
+ int alpha_size;
+ int lz_alpha_width, lz_alpha_height, n_comp_pixels, lz_alpha_top_down;
+
+ spice_return_val_if_fail(image->u.jpeg_alpha.data->num_chunks == 1, NULL);
+ canvas->jpeg->ops->begin_decode(canvas->jpeg,
+ image->u.jpeg_alpha.data->chunk[0].data,
+ image->u.jpeg_alpha.jpeg_size,
+ &width, &height);
+ spice_return_val_if_fail((uint32_t)width == image->descriptor.width, NULL);
+ spice_return_val_if_fail((uint32_t)height == image->descriptor.height, NULL);
+
+ if (image->u.jpeg_alpha.flags & SPICE_JPEG_ALPHA_FLAGS_TOP_DOWN) {
+ alpha_top_down = TRUE;
+ }
+
+#ifdef WIN32
+ lz_data->decode_data.dc = canvas->dc;
+#endif
+ surface = alloc_lz_image_surface(&lz_data->decode_data, PIXMAN_LE_a8r8g8b8,
+ width, height, width*height, alpha_top_down);
+
+ if (surface == NULL) {
+ spice_warning("create surface failed");
+ return NULL;
+ }
+
+ dest = (uint8_t *)pixman_image_get_data(surface);
+ stride = pixman_image_get_stride(surface);
+
+ canvas->jpeg->ops->decode(canvas->jpeg, dest, stride, SPICE_BITMAP_FMT_32BIT);
+
+ comp_alpha_buf = image->u.jpeg_alpha.data->chunk[0].data + image->u.jpeg_alpha.jpeg_size;
+ alpha_size = image->u.jpeg_alpha.data_size - image->u.jpeg_alpha.jpeg_size;
+
+ lz_decode_begin(lz_data->lz, comp_alpha_buf, alpha_size, &lz_alpha_type,
+ &lz_alpha_width, &lz_alpha_height, &n_comp_pixels,
+ &lz_alpha_top_down, NULL);
+ spice_return_val_if_fail(lz_alpha_type == LZ_IMAGE_TYPE_XXXA, NULL);
+ spice_return_val_if_fail(!!lz_alpha_top_down == !!alpha_top_down, NULL);
+ spice_return_val_if_fail(lz_alpha_width == width, NULL);
+ spice_return_val_if_fail(lz_alpha_height == height, NULL);
+ spice_return_val_if_fail(n_comp_pixels == width * height, NULL);
+
+ if (!alpha_top_down) {
+ decomp_alpha_buf = dest + stride * (height - 1);
+ } else {
+ decomp_alpha_buf = dest;
+ }
+ lz_decode(lz_data->lz, LZ_IMAGE_TYPE_XXXA, decomp_alpha_buf);
+
+#ifdef DUMP_JPEG
+ dump_jpeg(image->u.jpeg_alpha.data, image->u.jpeg_alpha.jpeg_size);
+#endif
+ return surface;
+}
+
+static pixman_image_t *canvas_bitmap_to_surface(CanvasBase *canvas, SpiceBitmap* bitmap,
+ SpicePalette *palette, int want_original)
+{
+ uint8_t* src;
+ pixman_image_t *image;
+ pixman_format_code_t format;
+
+ spice_chunks_linearize(bitmap->data);
+
+ src = bitmap->data->chunk[0].data;
+
+ if (want_original) {
+ format = spice_bitmap_format_to_pixman(bitmap->format, canvas->format);
+ } else {
+ format = canvas_get_target_format(canvas,
+ bitmap->format == SPICE_BITMAP_FMT_RGBA);
+ }
+
+ image = surface_create(
+#ifdef WIN32
+ canvas->dc,
+#endif
+ format,
+ bitmap->x, bitmap->y, FALSE);
+ if (image == NULL) {
+ spice_warning("create surface failed");
+ return NULL;
+ }
+
+ spice_bitmap_convert_to_pixman(format, image,
+ bitmap->format,
+ bitmap->flags,
+ bitmap->x, bitmap->y,
+ src, bitmap->stride,
+ canvas->format, palette);
+ return image;
+}
+
+
+#ifdef SW_CANVAS_CACHE
+
+static inline SpicePalette *canvas_get_palette(CanvasBase *canvas, SpicePalette *base_palette, uint64_t palette_id, uint8_t flags)
+{
+ SpicePalette *palette;
+
+ if (flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE) {
+ palette = canvas->palette_cache->ops->get(canvas->palette_cache, palette_id);
+ } else {
+ palette = base_palette;
+ if (palette != NULL && flags & SPICE_BITMAP_FLAGS_PAL_CACHE_ME) {
+ canvas->palette_cache->ops->put(canvas->palette_cache, palette);
+ }
+ }
+ return palette;
+}
+
+static inline SpicePalette *canvas_get_localized_palette(CanvasBase *canvas, SpicePalette *base_palette, uint64_t palette_id, uint8_t flags, int *free_palette)
+{
+ SpicePalette *palette = canvas_get_palette(canvas, base_palette, palette_id, flags);
+ SpicePalette *copy;
+ uint32_t *now, *end;
+ size_t size;
+
+ if (canvas->format == SPICE_SURFACE_FMT_32_xRGB ||
+ canvas->format == SPICE_SURFACE_FMT_32_ARGB) {
+ return palette;
+ }
+
+ size = sizeof(SpicePalette) + palette->num_ents * 4;
+ copy = (SpicePalette *)spice_malloc(size);
+ memcpy(copy, palette, size);
+
+ switch (canvas->format) {
+ case SPICE_SURFACE_FMT_32_xRGB:
+ case SPICE_SURFACE_FMT_32_ARGB:
+ /* Won't happen */
+ break;
+ case SPICE_SURFACE_FMT_16_555:
+ now = copy->ents;
+ end = now + copy->num_ents;
+ for (; now < end; now++) {
+ *now = canvas_16bpp_to_32bpp(*now);
+ }
+ break;
+ case SPICE_SURFACE_FMT_16_565:
+ default:
+ spice_warn_if_reached();
+ free(copy);
+ return NULL;
+ }
+ *free_palette = TRUE;
+ return copy;
+}
+
+static pixman_image_t *canvas_get_lz(CanvasBase *canvas, SpiceImage *image,
+ int want_original)
+{
+ LzData *lz_data = &canvas->lz_data;
+ uint8_t *comp_buf = NULL;
+ int comp_size;
+ uint8_t *decomp_buf = NULL;
+ pixman_format_code_t pixman_format;
+ LzImageType type, as_type;
+ SpicePalette *palette;
+ int n_comp_pixels;
+ int width;
+ int height;
+ int top_down;
+ int stride_encoded;
+ int stride;
+ int free_palette;
+
+ if (setjmp(lz_data->jmp_env)) {
+ free(decomp_buf);
+ spice_warning("%s", lz_data->message_buf);
+ return NULL;
+ }
+
+ free_palette = FALSE;
+ if (image->descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB) {
+ spice_return_val_if_fail(image->u.lz_rgb.data->num_chunks == 1, NULL); /* TODO: Handle chunks */
+ comp_buf = image->u.lz_rgb.data->chunk[0].data;
+ comp_size = image->u.lz_rgb.data->chunk[0].len;
+ palette = NULL;
+ } else if (image->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) {
+ spice_return_val_if_fail(image->u.lz_plt.data->num_chunks == 1, NULL); /* TODO: Handle chunks */
+ comp_buf = image->u.lz_plt.data->chunk[0].data;
+ comp_size = image->u.lz_plt.data->chunk[0].len;
+ palette = canvas_get_localized_palette(canvas, image->u.lz_plt.palette, image->u.lz_plt.palette_id, image->u.lz_plt.flags, &free_palette);
+ } else {
+ spice_warn_if_reached();
+ return NULL;
+ }
+
+ lz_decode_begin(lz_data->lz, comp_buf, comp_size, &type,
+ &width, &height, &n_comp_pixels, &top_down, palette);
+
+ stride_encoded = width;
+ switch (type) {
+ case LZ_IMAGE_TYPE_RGBA:
+ as_type = LZ_IMAGE_TYPE_RGBA;
+ pixman_format = PIXMAN_LE_a8r8g8b8;
+ stride_encoded *= 4;
+ break;
+ case LZ_IMAGE_TYPE_RGB32:
+ case LZ_IMAGE_TYPE_RGB24:
+ case LZ_IMAGE_TYPE_PLT1_LE:
+ case LZ_IMAGE_TYPE_PLT1_BE:
+ case LZ_IMAGE_TYPE_PLT4_LE:
+ case LZ_IMAGE_TYPE_PLT4_BE:
+ case LZ_IMAGE_TYPE_PLT8:
+ as_type = LZ_IMAGE_TYPE_RGB32;
+ pixman_format = PIXMAN_LE_x8r8g8b8;
+ stride_encoded *= 4;
+ break;
+ case LZ_IMAGE_TYPE_A8:
+ as_type = LZ_IMAGE_TYPE_A8;
+ pixman_format = PIXMAN_a8;
+ break;
+ case LZ_IMAGE_TYPE_RGB16:
+ if (!want_original &&
+ (canvas->format == SPICE_SURFACE_FMT_32_xRGB ||
+ canvas->format == SPICE_SURFACE_FMT_32_ARGB)) {
+ as_type = LZ_IMAGE_TYPE_RGB32;
+ pixman_format = PIXMAN_LE_x8r8g8b8;
+ stride_encoded *= 4;
+ } else {
+ as_type = LZ_IMAGE_TYPE_RGB16;
+ pixman_format = PIXMAN_x1r5g5b5;
+ stride_encoded *= 2;
+ }
+ break;
+ default:
+ spice_warn_if_reached();
+ return NULL;
+ }
+
+ spice_return_val_if_fail((unsigned)width == image->descriptor.width, NULL);
+ spice_return_val_if_fail((unsigned)height == image->descriptor.height, NULL);
+
+ spice_return_val_if_fail((image->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) || (n_comp_pixels == width * height), NULL);
+#ifdef WIN32
+ lz_data->decode_data.dc = canvas->dc;
+#endif
+
+
+ alloc_lz_image_surface(&lz_data->decode_data, pixman_format,
+ width, height, n_comp_pixels, top_down);
+
+ stride = pixman_image_get_stride(lz_data->decode_data.out_surface);
+ stride = abs(stride);
+
+ decomp_buf = (uint8_t *)pixman_image_get_data(lz_data->decode_data.out_surface);
+ if (!top_down) {
+ decomp_buf -= stride * (height - 1);
+ }
+
+ lz_decode(lz_data->lz, as_type, decomp_buf);
+
+ canvas_fix_alignment(decomp_buf, stride_encoded, stride, height);
+
+ if (free_palette) {
+ free(palette);
+ }
+
+ return lz_data->decode_data.out_surface;
+}
+
+static pixman_image_t *canvas_get_glz_rgb_common(CanvasBase *canvas, uint8_t *data,
+ int want_original)
+{
+ spice_return_val_if_fail(canvas->glz_data.decoder != NULL, NULL);
+
+ canvas->glz_data.decoder->ops->decode(canvas->glz_data.decoder,
+ data, NULL,
+ &canvas->glz_data.decode_data);
+
+ /* global_decode calls alloc_lz_image, which sets canvas->glz_data.surface */
+ return (canvas->glz_data.decode_data.out_surface);
+}
+
+// don't handle plts since bitmaps with plt can be decoded globally to RGB32 (because
+// same byte sequence can be transformed to different RGB pixels by different plts)
+static pixman_image_t *canvas_get_glz(CanvasBase *canvas, SpiceImage *image,
+ int want_original)
+{
+ spice_return_val_if_fail(image->descriptor.type == SPICE_IMAGE_TYPE_GLZ_RGB, NULL);
+#ifdef WIN32
+ canvas->glz_data.decode_data.dc = canvas->dc;
+#endif
+
+ spice_return_val_if_fail(image->u.lz_rgb.data->num_chunks == 1, NULL); /* TODO: Handle chunks */
+ return canvas_get_glz_rgb_common(canvas, image->u.lz_rgb.data->chunk[0].data, want_original);
+}
+
+static pixman_image_t *canvas_get_zlib_glz_rgb(CanvasBase *canvas, SpiceImage *image,
+ int want_original)
+{
+ uint8_t *glz_data;
+ pixman_image_t *surface;
+
+ spice_return_val_if_fail(canvas->zlib != NULL, NULL);
+
+ spice_return_val_if_fail(image->u.zlib_glz.data->num_chunks == 1, NULL); /* TODO: Handle chunks */
+ glz_data = (uint8_t*)spice_malloc(image->u.zlib_glz.glz_data_size);
+ canvas->zlib->ops->decode(canvas->zlib, image->u.zlib_glz.data->chunk[0].data,
+ image->u.zlib_glz.data->chunk[0].len,
+ glz_data, image->u.zlib_glz.glz_data_size);
+ surface = canvas_get_glz_rgb_common(canvas, glz_data, want_original);
+ free(glz_data);
+ return surface;
+}
+
+//#define DEBUG_DUMP_BITMAP
+
+#ifdef DEBUG_DUMP_BITMAP
+static void dump_bitmap(SpiceBitmap *bitmap, SpicePalette *palette)
+{
+ uint8_t* data = (uint8_t *)SPICE_GET_ADDRESS(bitmap->data);
+ static uint32_t file_id = 0;
+ uint32_t i, j;
+ char file_str[200];
+ uint32_t id = ++file_id;
+
+#ifdef WIN32
+ sprintf(file_str, "c:\\tmp\\spice_dump\\%u.%ubpp", id, bitmap->format);
+#else
+ sprintf(file_str, "/tmp/spice_dump/%u.%ubpp", id, bitmap->format);
+#endif
+ FILE *f = fopen(file_str, "wb");
+ if (!f) {
+ return;
+ }
+
+ fprintf(f, "%d\n", bitmap->format); // 1_LE,1_BE,....
+ fprintf(f, "%d %d\n", bitmap->x, bitmap->y); // width and height
+ fprintf(f, "%d\n", palette->num_ents); // #plt entries
+ for (i = 0; i < palette->num_ents; i++) {
+ fwrite(&(palette->ents[i]), 4, 1, f);
+ }
+ fprintf(f, "\n");
+
+ for (i = 0; i < bitmap->y; i++, data += bitmap->stride) {
+ uint8_t *now = data;
+ for (j = 0; j < bitmap->x; j++) {
+ fwrite(now, 1, 1, f);
+ now++;
+ }
+ }
+}
+
+#endif
+
+static pixman_image_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap,
+ int want_original)
+{
+ pixman_image_t* surface;
+ SpicePalette *palette;
+
+ palette = canvas_get_palette(canvas, bitmap->palette, bitmap->palette_id, bitmap->flags);
+#ifdef DEBUG_DUMP_BITMAP
+ if (palette) {
+ dump_bitmap(bitmap, palette);
+ }
+#endif
+
+ surface = canvas_bitmap_to_surface(canvas, bitmap, palette, want_original);
+
+ if (palette && (bitmap->flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
+ canvas->palette_cache->ops->release(canvas->palette_cache, palette);
+ }
+
+ return surface;
+}
+
+#else
+
+
+static pixman_image_t *canvas_get_bits(CanvasBase *canvas, SpiceBitmap *bitmap,
+ int want_original)
+{
+ SpicePalette *palette;
+
+ if (!bitmap->palette) {
+ return canvas_bitmap_to_surface(canvas, bitmap, NULL, want_original);
+ }
+ palette = (SpicePalette *)SPICE_GET_ADDRESS(bitmap->palette);
+ return canvas_bitmap_to_surface(canvas, bitmap, palette, want_original);
+}
+
+#endif
+
+
+
+// caution: defining DEBUG_DUMP_SURFACE will dump both cached & non-cached
+// images to disk. it will reduce performance dramatically & eat
+// disk space rapidly. use it only for debugging.
+//#define DEBUG_DUMP_SURFACE
+
+#if defined(DEBUG_DUMP_SURFACE) || defined(DEBUG_DUMP_COMPRESS)
+
+static void dump_surface(pixman_image_t *surface, int cache)
+{
+ static uint32_t file_id = 0;
+ int i, j;
+ char file_str[200];
+ int depth = pixman_image_get_depth(surface);
+
+ if (depth != 24 && depth != 32) {
+ return;
+ }
+
+ uint8_t *data = (uint8_t *)pixman_image_get_data(surface);
+ int width = pixman_image_get_width(surface);
+ int height = pixman_image_get_height(surface);
+ int stride = pixman_image_get_stride(surface);
+
+ uint32_t id = ++file_id;
+#ifdef WIN32
+ sprintf(file_str, "c:\\tmp\\spice_dump\\%d\\%u.ppm", cache, id);
+#else
+ sprintf(file_str, "/tmp/spice_dump/%u.ppm", id);
+#endif
+ FILE *f = fopen(file_str, "wb");
+ if (!f) {
+ return;
+ }
+ fprintf(f, "P6\n");
+ fprintf(f, "%d %d\n", width, height);
+ fprintf(f, "#spicec dump\n");
+ fprintf(f, "255\n");
+ for (i = 0; i < height; i++, data += stride) {
+ uint8_t *now = data;
+ for (j = 0; j < width; j++) {
+ fwrite(&now[2], 1, 1, f);
+ fwrite(&now[1], 1, 1, f);
+ fwrite(&now[0], 1, 1, f);
+ now += 4;
+ }
+ }
+ fclose(f);
+}
+
+#endif
+
+static SpiceCanvas *canvas_get_surface_internal(CanvasBase *canvas, SpiceImage *image)
+{
+ if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) {
+ SpiceSurface *surface = &image->u.surface;
+ return canvas->surfaces->ops->get(canvas->surfaces, surface->surface_id);
+ }
+ return NULL;
+}
+
+static SpiceCanvas *canvas_get_surface_mask_internal(CanvasBase *canvas, SpiceImage *image)
+{
+ if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) {
+ SpiceSurface *surface = &image->u.surface;
+ return canvas->surfaces->ops->get(canvas->surfaces, surface->surface_id);
+ }
+ return NULL;
+}
+
+
+#if defined(SW_CANVAS_CACHE)
+static int image_has_palette_to_cache(SpiceImage *image)
+{
+ SpiceImageDescriptor *descriptor = &image->descriptor;
+
+ if (descriptor->type == SPICE_IMAGE_TYPE_BITMAP) {
+ return image->u.bitmap.palette &&
+ (image->u.bitmap.flags & SPICE_BITMAP_FLAGS_PAL_CACHE_ME);
+ } else if (descriptor->type == SPICE_IMAGE_TYPE_LZ_PLT) {
+ return image->u.lz_plt.palette &&
+ (image->u.lz_plt.flags & SPICE_BITMAP_FLAGS_PAL_CACHE_ME);
+ }
+ return FALSE;
+}
+#endif
+
+//#define DEBUG_LZ
+
+/* If real get is FALSE, then only do whatever is needed but don't return an image. For instance,
+ * if we need to read it to cache it we do.
+ *
+ * This generally converts the image to the right type for the canvas.
+ * However, if want_original is set the real source format is returned, and
+ * you have to be able to handle any image format. This is useful to avoid
+ * e.g. losing alpha when blending a argb32 image on a rgb16 surface.
+ */
+static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SpiceImage *image,
+ int want_original, int real_get)
+{
+ SpiceImageDescriptor *descriptor = &image->descriptor;
+ pixman_image_t *surface, *converted;
+ pixman_format_code_t wanted_format, surface_format;
+ int saved_want_original;
+
+ /* When touching, only really allocate if we need to cache, or
+ * if we're loading a GLZ stream (since those need inter-thread communication
+ * to happen which breaks if we don't. */
+ if (!real_get &&
+ !(descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_ME) &&
+#ifdef SW_CANVAS_CACHE
+ !(descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME) &&
+ !image_has_palette_to_cache(image) &&
+#endif
+ (descriptor->type != SPICE_IMAGE_TYPE_GLZ_RGB) &&
+ (descriptor->type != SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB)) {
+ return NULL;
+ }
+
+ saved_want_original = want_original;
+ if (descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_ME
+#ifdef SW_CANVAS_CACHE
+ || descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME
+#endif
+ ) {
+ want_original = TRUE;
+ }
+
+ switch (descriptor->type) {
+ case SPICE_IMAGE_TYPE_QUIC: {
+ surface = canvas_get_quic(canvas, image, want_original);
+ break;
+ }
+#if defined(SW_CANVAS_CACHE)
+ case SPICE_IMAGE_TYPE_LZ_PLT:
+ case SPICE_IMAGE_TYPE_LZ_RGB: {
+ surface = canvas_get_lz(canvas, image, want_original);
+ break;
+ }
+#endif
+ case SPICE_IMAGE_TYPE_JPEG: {
+ surface = canvas_get_jpeg(canvas, image);
+ break;
+ }
+ case SPICE_IMAGE_TYPE_JPEG_ALPHA: {
+ surface = canvas_get_jpeg_alpha(canvas, image);
+ break;
+ }
+ case SPICE_IMAGE_TYPE_LZ4: {
+#ifdef USE_LZ4
+ surface = canvas_get_lz4(canvas, image);
+#else
+ spice_warning("Lz4 compression algorithm not supported.\n");
+ surface = NULL;
+#endif
+ break;
+ }
+#if defined(SW_CANVAS_CACHE)
+ case SPICE_IMAGE_TYPE_GLZ_RGB: {
+ surface = canvas_get_glz(canvas, image, want_original);
+ break;
+ }
+ case SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB: {
+ surface = canvas_get_zlib_glz_rgb(canvas, image, want_original);
+ break;
+ }
+#endif
+ case SPICE_IMAGE_TYPE_FROM_CACHE:
+ surface = canvas->bits_cache->ops->get(canvas->bits_cache, descriptor->id);
+ break;
+#ifdef SW_CANVAS_CACHE
+ case SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS:
+ surface = canvas->bits_cache->ops->get_lossless(canvas->bits_cache, descriptor->id);
+ break;
+#endif
+ case SPICE_IMAGE_TYPE_BITMAP: {
+ surface = canvas_get_bits(canvas, &image->u.bitmap, want_original);
+ break;
+ }
+ default:
+ spice_warn_if_reached();
+ return NULL;
+ }
+
+ spice_return_val_if_fail(surface != NULL, NULL);
+ spice_return_val_if_fail(spice_pixman_image_get_format(surface, &surface_format), NULL);
+
+ if (descriptor->flags & SPICE_IMAGE_FLAGS_HIGH_BITS_SET &&
+ descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE &&
+#ifdef SW_CANVAS_CACHE
+ descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS &&
+#endif
+ surface_format == PIXMAN_x8r8g8b8) {
+ spice_pixman_fill_rect_rop(surface,
+ 0, 0,
+ pixman_image_get_width(surface),
+ pixman_image_get_height(surface),
+ 0xff000000U, SPICE_ROP_OR);
+ }
+
+ if (descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_ME &&
+#ifdef SW_CANVAS_CACHE
+ descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS &&
+#endif
+ descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE ) {
+#ifdef SW_CANVAS_CACHE
+ if (!spice_image_descriptor_is_lossy(descriptor)) {
+ canvas->bits_cache->ops->put(canvas->bits_cache, descriptor->id, surface);
+ } else {
+ canvas->bits_cache->ops->put_lossy(canvas->bits_cache, descriptor->id, surface);
+ }
+#else
+ canvas->bits_cache->ops->put(canvas->bits_cache, descriptor->id, surface);
+#endif
+#ifdef DEBUG_DUMP_SURFACE
+ dump_surface(surface, 1);
+#endif
+#ifdef SW_CANVAS_CACHE
+ } else if (descriptor->flags & SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME) {
+ if (spice_image_descriptor_is_lossy(descriptor)) {
+ spice_warning("invalid cache replace request: the image is lossy");
+ return NULL;
+ }
+ canvas->bits_cache->ops->replace_lossy(canvas->bits_cache, descriptor->id, surface);
+#ifdef DEBUG_DUMP_SURFACE
+ dump_surface(surface, 1);
+#endif
+#endif
+#ifdef DEBUG_DUMP_SURFACE
+ } else if (descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE
+#ifdef SW_CANVAS_CACHE
+ && descriptor->type != SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS
+#endif
+ ) {
+
+ dump_surface(surface, 0);
+#endif
+ }
+
+ if (!real_get) {
+ pixman_image_unref(surface);
+ return NULL;
+ }
+
+ if (!saved_want_original) {
+ /* Conversion to canvas format was requested, but maybe it didn't
+ happen above (due to save/load to cache for instance, or
+ maybe the reader didn't support conversion).
+ If so we convert here. */
+
+ wanted_format = canvas_get_target_format(canvas,
+#ifdef WORDS_BIGENDIAN
+ surface_format == PIXMAN_b8g8r8a8 ||
+#endif
+ surface_format == PIXMAN_a8r8g8b8);
+
+ if (surface_format != wanted_format) {
+ converted = surface_create(
+#ifdef WIN32
+ canvas->dc,
+#endif
+ wanted_format,
+ pixman_image_get_width(surface),
+ pixman_image_get_height(surface),
+ TRUE);
+ pixman_image_composite32 (PIXMAN_OP_SRC,
+ surface, NULL, converted,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ pixman_image_get_width(surface),
+ pixman_image_get_height(surface));
+ pixman_image_unref (surface);
+ surface = converted;
+ }
+ }
+
+ return surface;
+}
+
+static SpiceCanvas *canvas_get_surface_mask(CanvasBase *canvas, SpiceImage *image)
+{
+ return canvas_get_surface_mask_internal(canvas, image);
+}
+
+static SpiceCanvas *canvas_get_surface(CanvasBase *canvas, SpiceImage *image)
+{
+ return canvas_get_surface_internal(canvas, image);
+}
+
+static pixman_image_t *canvas_get_image(CanvasBase *canvas, SpiceImage *image,
+ int want_original)
+{
+ return canvas_get_image_internal(canvas, image, want_original, TRUE);
+}
+
+static void canvas_touch_image(CanvasBase *canvas, SpiceImage *image)
+{
+ canvas_get_image_internal(canvas, image, TRUE, FALSE);
+}
+
+static pixman_image_t* canvas_get_image_from_self(SpiceCanvas *canvas,
+ int x, int y,
+ int32_t width, int32_t height,
+ int force_opaque)
+{
+ CanvasBase *canvas_base = (CanvasBase *)canvas;
+ pixman_image_t *surface;
+ uint8_t *dest;
+ int dest_stride;
+ SpiceRect area;
+ pixman_format_code_t format;
+
+ format = spice_surface_format_to_pixman (canvas_base->format);
+ if (force_opaque)
+ {
+ /* Set alpha bits of the format to 0 */
+ format = (pixman_format_code_t)(((uint32_t)format) & ~(0xf << 12));
+
+ spice_return_val_if_fail (
+ pixman_format_supported_destination (format), NULL);
+ }
+
+ surface = pixman_image_create_bits(spice_surface_format_to_pixman (canvas_base->format),
+ width, height, NULL, 0);
+ spice_return_val_if_fail(surface != NULL, NULL);
+
+ dest = (uint8_t *)pixman_image_get_data(surface);
+ dest_stride = pixman_image_get_stride(surface);
+
+ area.left = x;
+ area.top = y;
+ area.right = x + width;
+ area.bottom = y + height;
+
+ canvas->ops->read_bits(canvas, dest, dest_stride, &area);
+
+ return surface;
+}
+
+
+#ifdef REVERS_BITS_SLOW
+static inline uint8_t revers_bits(uint8_t byte)
+{
+ uint8_t ret = 0;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ int shift = 7 - i * 2;
+ ret |= (byte & (1 << i)) << shift;
+ ret |= (byte & (0x80 >> i)) >> shift;
+ }
+ return ret;
+}
+#else
+static inline uint8_t revers_bits(uint8_t byte)
+{
+ static const uint8_t revers[] = {
+ 0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x8, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x4, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0xc, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x2, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0xa, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x6, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0xe, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x1, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x9, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x5, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0xd, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x3, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0xb, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x7, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0xf, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+ };
+
+ return revers[byte];
+}
+#endif
+
+static pixman_image_t *canvas_get_bitmap_mask(CanvasBase *canvas, SpiceBitmap* bitmap, int invers)
+{
+ pixman_image_t *surface;
+ uint8_t *src_line;
+ uint8_t *end_line;
+ uint8_t *dest_line;
+ int src_stride;
+ int line_size;
+ int dest_stride;
+
+ surface = surface_create(
+#ifdef WIN32
+ canvas->dc,
+#endif
+ PIXMAN_a1, bitmap->x, bitmap->y, TRUE);
+ spice_return_val_if_fail(surface != NULL, NULL);
+
+ spice_chunks_linearize(bitmap->data);
+ src_line = bitmap->data->chunk[0].data;
+ src_stride = bitmap->stride;
+ end_line = src_line + (bitmap->y * src_stride);
+ line_size = SPICE_ALIGN(bitmap->x, 8) >> 3;
+
+ dest_stride = pixman_image_get_stride(surface);
+ dest_line = (uint8_t *)pixman_image_get_data(surface);
+ if (!(bitmap->flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
+ spice_return_val_if_fail(bitmap->y > 0, NULL);
+ dest_line += dest_stride * ((int)bitmap->y - 1);
+ dest_stride = -dest_stride;
+ }
+
+ if (invers) {
+ switch (bitmap->format) {
+#if defined(GDI_CANVAS)
+ case SPICE_BITMAP_FMT_1BIT_BE:
+#else
+ case SPICE_BITMAP_FMT_1BIT_LE:
+#endif
+ for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
+ uint8_t *dest = dest_line;
+ uint8_t *now = src_line;
+ uint8_t *end = now + line_size;
+ while (now < end) {
+ *(dest++) = ~*(now++);
+ }
+ }
+ break;
+#if defined(GDI_CANVAS)
+ case SPICE_BITMAP_FMT_1BIT_LE:
+#else
+ case SPICE_BITMAP_FMT_1BIT_BE:
+#endif
+ for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
+ uint8_t *dest = dest_line;
+ uint8_t *now = src_line;
+ uint8_t *end = now + line_size;
+
+ while (now < end) {
+ *(dest++) = ~revers_bits(*(now++));
+ }
+ }
+ break;
+ default:
+ pixman_image_unref(surface);
+ surface = NULL;
+ spice_warn_if_reached();
+ return NULL;
+ }
+ } else {
+ switch (bitmap->format) {
+#if defined(GDI_CANVAS)
+ case SPICE_BITMAP_FMT_1BIT_BE:
+#else
+ case SPICE_BITMAP_FMT_1BIT_LE:
+#endif
+ for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
+ memcpy(dest_line, src_line, line_size);
+ }
+ break;
+#if defined(GDI_CANVAS)
+ case SPICE_BITMAP_FMT_1BIT_LE:
+#else
+ case SPICE_BITMAP_FMT_1BIT_BE:
+#endif
+ for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
+ uint8_t *dest = dest_line;
+ uint8_t *now = src_line;
+ uint8_t *end = now + line_size;
+
+ while (now < end) {
+ *(dest++) = revers_bits(*(now++));
+ }
+ }
+ break;
+ default:
+ pixman_image_unref(surface);
+ surface = NULL;
+ spice_warn_if_reached();
+ return NULL;
+ }
+ }
+ return surface;
+}
+
+static inline pixman_image_t *canvas_A1_invers(pixman_image_t *src_surf)
+{
+ int width = pixman_image_get_width(src_surf);
+ int height = pixman_image_get_height(src_surf);
+ pixman_image_t * invers;
+ uint8_t *src_line, *end_line, *dest_line;
+ int src_stride, line_size, dest_stride;
+
+ spice_return_val_if_fail(pixman_image_get_depth(src_surf) == 1, NULL);
+
+ invers = pixman_image_create_bits(PIXMAN_a1, width, height, NULL, 0);
+ spice_return_val_if_fail(invers != NULL, NULL);
+
+ src_line = (uint8_t *)pixman_image_get_data(src_surf);
+ src_stride = pixman_image_get_stride(src_surf);
+ end_line = src_line + (height * src_stride);
+ line_size = SPICE_ALIGN(width, 8) >> 3;
+ dest_line = (uint8_t *)pixman_image_get_data(invers);
+ dest_stride = pixman_image_get_stride(invers);
+
+ for (; src_line != end_line; src_line += src_stride, dest_line += dest_stride) {
+ uint8_t *dest = dest_line;
+ uint8_t *now = src_line;
+ uint8_t *end = now + line_size;
+ while (now < end) {
+ *(dest++) = ~*(now++);
+ }
+ }
+ return invers;
+}
+
+static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask, int *needs_invert_out)
+{
+ SpiceImage *image;
+ pixman_image_t *surface;
+ int need_invers;
+ int is_invers;
+ int cache_me;
+
+ if (needs_invert_out) {
+ *needs_invert_out = 0;
+ }
+
+ image = mask->bitmap;
+ need_invers = mask->flags & SPICE_MASK_FLAGS_INVERS;
+
+#ifdef SW_CANVAS_CACHE
+ cache_me = image->descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME;
+#else
+ cache_me = 0;
+#endif
+
+ switch (image->descriptor.type) {
+ case SPICE_IMAGE_TYPE_BITMAP: {
+ is_invers = need_invers && !cache_me;
+ surface = canvas_get_bitmap_mask(canvas, &image->u.bitmap, is_invers);
+ break;
+ }
+ case SPICE_IMAGE_TYPE_FROM_CACHE:
+ surface = canvas->bits_cache->ops->get(canvas->bits_cache, image->descriptor.id);
+ is_invers = 0;
+ break;
+#ifdef SW_CANVAS_CACHE
+ case SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS:
+ surface = canvas->bits_cache->ops->get_lossless(canvas->bits_cache, image->descriptor.id);
+ is_invers = 0;
+ break;
+#endif
+ default:
+ spice_warn_if_reached();
+ return NULL;
+ }
+
+ if (cache_me) {
+ canvas->bits_cache->ops->put(canvas->bits_cache, image->descriptor.id, surface);
+ }
+
+ if (need_invers && !is_invers) { // surface is in cache
+ if (needs_invert_out != NULL) {
+ *needs_invert_out = TRUE;
+ } else {
+ pixman_image_t *inv_surf;
+ inv_surf = canvas_A1_invers(surface);
+ pixman_image_unref(surface);
+ surface = inv_surf;
+ }
+ }
+
+ return surface;
+}
+
+static inline void canvas_raster_glyph_box(const SpiceRasterGlyph *glyph, SpiceRect *r)
+{
+ spice_return_if_fail(r != NULL);
+
+ r->top = glyph->render_pos.y + glyph->glyph_origin.y;
+ r->bottom = r->top + glyph->height;
+ r->left = glyph->render_pos.x + glyph->glyph_origin.x;
+ r->right = r->left + glyph->width;
+}
+
+static inline void __canvas_put_bits(uint8_t *dest, int offset, uint8_t val, int n)
+{
+ uint8_t mask;
+ int now;
+
+ dest = dest + (offset >> 3);
+ offset &= 0x07;
+
+ now = MIN(8 - offset, n);
+
+ mask = (1 << now) - 1;
+ mask <<= offset;
+ val = revers_bits(val);
+ *dest = ((val << offset) & mask) | *dest;
+
+ if ((n = n - now)) {
+ mask = (1 << n) - 1;
+ dest++;
+ *dest = ((val >> now) & mask) | *dest;
+ }
+}
+
+static inline void canvas_put_bits(uint8_t *dest, int dest_offset, uint8_t *src, int n)
+{
+ while (n) {
+ int now = MIN(n, 8);
+
+ n -= now;
+ __canvas_put_bits(dest, dest_offset, *src, now);
+ dest_offset += now;
+ src++;
+ }
+}
+
+static void canvas_put_glyph_bits(SpiceRasterGlyph *glyph, int bpp, uint8_t *dest, int dest_stride,
+ SpiceRect *bounds)
+{
+ SpiceRect glyph_box;
+ uint8_t *src;
+ int lines;
+ int width;
+
+ //todo: support SPICE_STRING_FLAGS_RASTER_TOP_DOWN
+ canvas_raster_glyph_box(glyph, &glyph_box);
+ spice_return_if_fail(glyph_box.top >= bounds->top && glyph_box.bottom <= bounds->bottom);
+ spice_return_if_fail(glyph_box.left >= bounds->left && glyph_box.right <= bounds->right);
+ rect_offset(&glyph_box, -bounds->left, -bounds->top);
+
+ dest += glyph_box.top * dest_stride;
+ src = glyph->data;
+ lines = glyph_box.bottom - glyph_box.top;
+ width = glyph_box.right - glyph_box.left;
+ switch (bpp) {
+ case 1: {
+ int src_stride = SPICE_ALIGN(width, 8) >> 3;
+ int i;
+
+ src += src_stride * (lines);
+ for (i = 0; i < lines; i++) {
+ src -= src_stride;
+ canvas_put_bits(dest, glyph_box.left, src, width);
+ dest += dest_stride;
+ }
+ break;
+ }
+ case 4: {
+ uint8_t *end;
+ int src_stride = SPICE_ALIGN(width * 4, 8) >> 3;
+
+ src += src_stride * lines;
+ dest += glyph_box.left;
+ end = dest + dest_stride * lines;
+ for (; dest != end; dest += dest_stride) {
+ int i = 0;
+ uint8_t *now;
+
+ src -= src_stride;
+ now = src;
+ while (i < (width & ~1)) {
+ dest[i] = MAX(dest[i], *now & 0xf0);
+ dest[i + 1] = MAX(dest[i + 1], *now << 4);
+ i += 2;
+ now++;
+ }
+ if (i < width) {
+ dest[i] = MAX(dest[i], *now & 0xf0);
+ now++;
+ }
+ }
+ break;
+ }
+ case 8: {
+ uint8_t *end;
+ src += width * lines;
+ dest += glyph_box.left;
+ end = dest + dest_stride * lines;
+ for (; dest != end; dest += dest_stride, src -= width) {
+ int i;
+
+ for (i = 0; i < width; i++) {
+ dest[i] = MAX(dest[i], src[i]);
+ }
+ }
+ break;
+ }
+ default:
+ spice_warn_if_reached();
+ return;
+ }
+}
+
+static pixman_image_t *canvas_get_str_mask(CanvasBase *canvas, SpiceString *str, int bpp, SpicePoint *pos)
+{
+ SpiceRasterGlyph *glyph;
+ SpiceRect bounds;
+ pixman_image_t *str_mask;
+ uint8_t *dest;
+ int dest_stride;
+ int i;
+
+ spice_return_val_if_fail(str->length > 0, NULL);
+
+ glyph = str->glyphs[0];
+ canvas_raster_glyph_box(glyph, &bounds);
+
+ for (i = 1; i < str->length; i++) {
+ SpiceRect glyph_box;
+
+ canvas_raster_glyph_box(str->glyphs[i], &glyph_box);
+ rect_union(&bounds, &glyph_box);
+ }
+
+ str_mask = pixman_image_create_bits((bpp == 1) ? PIXMAN_a1 : PIXMAN_a8,
+ bounds.right - bounds.left,
+ bounds.bottom - bounds.top, NULL, 0);
+ spice_return_val_if_fail(str_mask != NULL, NULL);
+
+ dest = (uint8_t *)pixman_image_get_data(str_mask);
+ dest_stride = pixman_image_get_stride(str_mask);
+ for (i = 0; i < str->length; i++) {
+ glyph = str->glyphs[i];
+ canvas_put_glyph_bits(glyph, bpp, dest, dest_stride, &bounds);
+ }
+
+ pos->x = bounds.left;
+ pos->y = bounds.top;
+ return str_mask;
+}
+
+static pixman_image_t *canvas_scale_surface(pixman_image_t *src, const SpiceRect *src_area, int width,
+ int height, int scale_mode)
+{
+ pixman_image_t *surface;
+ pixman_transform_t transform;
+ pixman_format_code_t format;
+ double sx, sy;
+
+ spice_return_val_if_fail(spice_pixman_image_get_format (src, &format), NULL);
+
+ surface = pixman_image_create_bits(format, width, height, NULL, 0);
+ spice_return_val_if_fail(surface != NULL, NULL);
+
+ sx = (double)(src_area->right - src_area->left) / width;
+ sy = (double)(src_area->bottom - src_area->top) / height;
+
+ pixman_transform_init_scale(&transform, pixman_double_to_fixed(sx), pixman_double_to_fixed(sy));
+
+ pixman_image_set_transform (src, &transform);
+ pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
+ spice_return_val_if_fail(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE || scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST, NULL);
+ pixman_image_set_filter(src,
+ (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
+ NULL, 0);
+
+ pixman_image_composite32(PIXMAN_OP_SRC,
+ src, NULL, surface,
+ ROUND(src_area->left / sx), ROUND (src_area->top / sy),
+ 0, 0, /* mask */
+ 0, 0, /* dst */
+ width, height);
+
+ pixman_transform_init_identity(&transform);
+ pixman_image_set_transform(src, &transform);
+
+ return surface;
+}
+
+SPICE_ATTR_NORETURN
+SPICE_ATTR_PRINTF(2, 3) static void quic_usr_error(QuicUsrContext *usr, const char *fmt, ...)
+{
+ QuicData *usr_data = (QuicData *)usr;
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
+ va_end(ap);
+
+ longjmp(usr_data->jmp_env, 1);
+}
+
+SPICE_ATTR_PRINTF(2, 3) static void quic_usr_warn(QuicUsrContext *usr, const char *fmt, ...)
+{
+ QuicData *usr_data = (QuicData *)usr;
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
+ va_end(ap);
+}
+
+static void *quic_usr_malloc(QuicUsrContext *usr, int size)
+{
+ return spice_malloc(size);
+}
+
+static void quic_usr_free(QuicUsrContext *usr, void *ptr)
+{
+ free(ptr);
+}
+
+SPICE_ATTR_PRINTF(2, 3) static void lz_usr_warn(LzUsrContext *usr, const char *fmt, ...)
+{
+ LzData *usr_data = (LzData *)usr;
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
+ va_end(ap);
+}
+
+SPICE_ATTR_NORETURN
+SPICE_ATTR_PRINTF(2, 3) static void lz_usr_error(LzUsrContext *usr, const char *fmt, ...)
+{
+ LzData *usr_data = (LzData *)usr;
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(usr_data->message_buf, sizeof(usr_data->message_buf), fmt, ap);
+ va_end(ap);
+
+ longjmp(usr_data->jmp_env, 1);
+}
+
+static void *lz_usr_malloc(LzUsrContext *usr, int size)
+{
+ return spice_malloc(size);
+}
+
+static void lz_usr_free(LzUsrContext *usr, void *ptr)
+{
+ free(ptr);
+}
+
+static int lz_usr_more_space(LzUsrContext *usr, uint8_t **io_ptr)
+{
+ return 0;
+}
+
+static int lz_usr_more_lines(LzUsrContext *usr, uint8_t **lines)
+{
+ return 0;
+}
+
+static int quic_usr_more_space(QuicUsrContext *usr, uint32_t **io_ptr, int rows_completed)
+{
+ QuicData *quic_data = (QuicData *)usr;
+
+ if (quic_data->current_chunk == quic_data->chunks->num_chunks -1) {
+ return 0;
+ }
+ quic_data->current_chunk++;
+
+ *io_ptr = (uint32_t *)quic_data->chunks->chunk[quic_data->current_chunk].data;
+ return quic_data->chunks->chunk[quic_data->current_chunk].len >> 2;
+}
+
+
+static int quic_usr_more_lines(QuicUsrContext *usr, uint8_t **lines)
+{
+ return 0;
+}
+
+static void canvas_base_destroy(CanvasBase *canvas)
+{
+ quic_destroy(canvas->quic_data.quic);
+ lz_destroy(canvas->lz_data.lz);
+#ifdef GDI_CANVAS
+ DeleteDC(canvas->dc);
+#endif
+
+ if (canvas->usr_data && canvas->usr_data_destroy) {
+ canvas->usr_data_destroy (canvas->usr_data);
+ canvas->usr_data = NULL;
+ }
+}
+
+/* This is kind of lame, but it protects against multiple
+ instances of these functions. We really should stop including
+ canvas_base.c and build it separately instead */
+#ifdef CANVAS_SINGLE_INSTANCE
+
+void spice_canvas_set_usr_data(SpiceCanvas *spice_canvas,
+ void *data,
+ spice_destroy_fn_t destroy_fn)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ if (canvas->usr_data && canvas->usr_data_destroy) {
+ canvas->usr_data_destroy (canvas->usr_data);
+ }
+ canvas->usr_data = data;
+ canvas->usr_data_destroy = destroy_fn;
+}
+
+void *spice_canvas_get_usr_data(SpiceCanvas *spice_canvas)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ return canvas->usr_data;
+}
+#endif
+
+
+static void canvas_clip_pixman(CanvasBase *canvas,
+ pixman_region32_t *dest_region,
+ SpiceClip *clip)
+{
+ pixman_region32_intersect(dest_region, dest_region, &canvas->canvas_region);
+
+ switch (clip->type) {
+ case SPICE_CLIP_TYPE_NONE:
+ break;
+ case SPICE_CLIP_TYPE_RECTS: {
+ uint32_t n = clip->rects->num_rects;
+ SpiceRect *now = clip->rects->rects;
+
+ pixman_region32_t clip;
+
+ if (spice_pixman_region32_init_rects(&clip, now, n)) {
+ pixman_region32_intersect(dest_region, dest_region, &clip);
+ pixman_region32_fini(&clip);
+ }
+
+ break;
+ }
+ default:
+ spice_warn_if_reached();
+ return;
+ }
+}
+
+static void canvas_mask_pixman(CanvasBase *canvas,
+ pixman_region32_t *dest_region,
+ SpiceQMask *mask, int x, int y)
+{
+ SpiceCanvas *surface_canvas;
+ pixman_image_t *image, *subimage;
+ int needs_invert;
+ pixman_region32_t mask_region;
+ uint32_t *mask_data;
+ int mask_x, mask_y;
+ int mask_width, mask_height, mask_stride;
+ pixman_box32_t extents;
+
+ if (!mask->bitmap) {
+ return;
+ }
+
+ surface_canvas = canvas_get_surface_mask(canvas, mask->bitmap);
+ if (surface_canvas) {
+ needs_invert = mask->flags & SPICE_MASK_FLAGS_INVERS;
+ image = surface_canvas->ops->get_image(surface_canvas, FALSE);
+ } else {
+ needs_invert = FALSE;
+ image = canvas_get_mask(canvas,
+ mask,
+ &needs_invert);
+ }
+
+ mask_data = pixman_image_get_data(image);
+ mask_width = pixman_image_get_width(image);
+ mask_height = pixman_image_get_height(image);
+ mask_stride = pixman_image_get_stride(image);
+
+ mask_x = mask->pos.x;
+ mask_y = mask->pos.y;
+
+ /* We need to subset the area of the mask that we turn into a region,
+ because a cached mask may be much larger than what is used for
+ the clip operation. */
+ extents = *pixman_region32_extents(dest_region);
+
+ /* convert from destination pixels to mask pixels */
+ extents.x1 -= x - mask_x;
+ extents.y1 -= y - mask_y;
+ extents.x2 -= x - mask_x;
+ extents.y2 -= y - mask_y;
+
+ /* clip to mask size */
+ if (extents.x1 < 0) {
+ extents.x1 = 0;
+ }
+ if (extents.x2 >= mask_width) {
+ extents.x2 = mask_width;
+ }
+ if (extents.x2 < extents.x1) {
+ extents.x2 = extents.x1;
+ }
+ if (extents.y1 < 0) {
+ extents.y1 = 0;
+ }
+ if (extents.y2 >= mask_height) {
+ extents.y2 = mask_height;
+ }
+ if (extents.y2 < extents.y1) {
+ extents.y2 = extents.y1;
+ }
+
+ /* round down X to even 32 pixels (i.e. uint32_t) */
+ extents.x1 = extents.x1 & ~(0x1f);
+
+ mask_data = (uint32_t *)((uint8_t *)mask_data + mask_stride * extents.y1 + extents.x1 / 32);
+ mask_x -= extents.x1;
+ mask_y -= extents.y1;
+ mask_width = extents.x2 - extents.x1;
+ mask_height = extents.y2 - extents.y1;
+
+ subimage = pixman_image_create_bits(PIXMAN_a1, mask_width, mask_height,
+ mask_data, mask_stride);
+ pixman_region32_init_from_image(&mask_region,
+ subimage);
+ pixman_image_unref(subimage);
+
+ if (needs_invert) {
+ pixman_box32_t rect;
+
+ rect.x1 = rect.y1 = 0;
+ rect.x2 = mask_width;
+ rect.y2 = mask_height;
+
+ pixman_region32_inverse(&mask_region, &mask_region, &rect);
+ }
+
+ pixman_region32_translate(&mask_region,
+ -mask_x + x, -mask_y + y);
+
+ pixman_region32_intersect(dest_region, dest_region, &mask_region);
+ pixman_region32_fini(&mask_region);
+
+ pixman_image_unref(image);
+}
+
+static void draw_brush(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ SpiceBrush *brush,
+ SpiceROP rop)
+{
+ CanvasBase *canvas_base = (CanvasBase *)canvas;
+ uint32_t color;
+ SpicePattern *pattern;
+ pixman_image_t *tile;
+ int offset_x, offset_y;
+ pixman_box32_t *rects;
+ int n_rects;
+
+ rects = pixman_region32_rectangles(region, &n_rects);
+
+ switch (brush->type) {
+ case SPICE_BRUSH_TYPE_SOLID:
+ color = brush->u.color;
+ if (rop == SPICE_ROP_COPY) {
+ canvas->ops->fill_solid_rects(canvas, rects, n_rects, color);
+ } else {
+ canvas->ops->fill_solid_rects_rop(canvas, rects, n_rects, color, rop);
+ }
+ break;
+ case SPICE_BRUSH_TYPE_PATTERN: {
+ SpiceCanvas *surface_canvas;
+
+ pattern = &brush->u.pattern;
+ offset_x = pattern->pos.x;
+ offset_y = pattern->pos.y;
+
+ surface_canvas = canvas_get_surface(canvas_base, pattern->pat);
+ if (surface_canvas) {
+ if (rop == SPICE_ROP_COPY) {
+ canvas->ops->fill_tiled_rects_from_surface(canvas, rects, n_rects, surface_canvas,
+ offset_x, offset_y);
+ } else {
+ canvas->ops->fill_tiled_rects_rop_from_surface(canvas, rects, n_rects,
+ surface_canvas, offset_x, offset_y,
+ rop);
+ }
+ } else {
+ tile = canvas_get_image(canvas_base, pattern->pat, FALSE);
+ spice_return_if_fail(tile != NULL);
+
+ if (rop == SPICE_ROP_COPY) {
+ canvas->ops->fill_tiled_rects(canvas, rects, n_rects, tile, offset_x, offset_y);
+ } else {
+ canvas->ops->fill_tiled_rects_rop(canvas, rects, n_rects,
+ tile, offset_x, offset_y, rop);
+ }
+ pixman_image_unref(tile);
+ }
+ break;
+ }
+ case SPICE_BRUSH_TYPE_NONE:
+ /* Still need to do *something* here, because rop could be e.g invert dest */
+ canvas->ops->fill_solid_rects_rop(canvas, rects, n_rects, 0, rop);
+ break;
+ default:
+ spice_warn_if_reached();
+ return;
+ }
+}
+
+/* If we're exiting early we may still have to load an image in case
+ it has to be cached or something */
+static void touch_brush(CanvasBase *canvas, SpiceBrush *brush)
+{
+ SpicePattern *pattern;
+
+ if (brush->type == SPICE_BRUSH_TYPE_PATTERN) {
+ pattern = &brush->u.pattern;
+ canvas_touch_image(canvas, pattern->pat);
+ }
+}
+
+static void canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ pixman_region32_t dest_region;
+ SpiceROP rop;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+
+ canvas_clip_pixman(canvas, &dest_region, clip);
+ canvas_mask_pixman(canvas, &dest_region, &fill->mask,
+ bbox->left, bbox->top);
+
+ rop = ropd_descriptor_to_rop(fill->rop_descriptor,
+ ROP_INPUT_BRUSH,
+ ROP_INPUT_DEST);
+
+ if (rop == SPICE_ROP_NOOP || !pixman_region32_not_empty(&dest_region)) {
+ touch_brush(canvas, &fill->brush);
+ pixman_region32_fini(&dest_region);
+ return;
+ }
+
+ draw_brush(spice_canvas, &dest_region, &fill->brush, rop);
+
+ pixman_region32_fini(&dest_region);
+}
+
+static void canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ pixman_region32_t dest_region;
+ SpiceCanvas *surface_canvas;
+ pixman_image_t *src_image;
+ SpiceROP rop;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+ canvas_clip_pixman(canvas, &dest_region, clip);
+ canvas_mask_pixman(canvas, &dest_region, ©->mask,
+ bbox->left, bbox->top);
+
+ rop = ropd_descriptor_to_rop(copy->rop_descriptor,
+ ROP_INPUT_SRC,
+ ROP_INPUT_DEST);
+
+ if (rop == SPICE_ROP_NOOP || !pixman_region32_not_empty(&dest_region)) {
+ canvas_touch_image(canvas, copy->src_bitmap);
+ pixman_region32_fini(&dest_region);
+ return;
+ }
+
+ surface_canvas = canvas_get_surface(canvas, copy->src_bitmap);
+ if (surface_canvas) {
+ if (rect_is_same_size(bbox, ©->src_area)) {
+ if (rop == SPICE_ROP_COPY) {
+ spice_canvas->ops->blit_image_from_surface(spice_canvas, &dest_region,
+ surface_canvas,
+ bbox->left - copy->src_area.left,
+ bbox->top - copy->src_area.top);
+ } else {
+ spice_canvas->ops->blit_image_rop_from_surface(spice_canvas, &dest_region,
+ surface_canvas,
+ bbox->left - copy->src_area.left,
+ bbox->top - copy->src_area.top,
+ rop);
+ }
+ } else {
+ if (rop == SPICE_ROP_COPY) {
+ spice_canvas->ops->scale_image_from_surface(spice_canvas, &dest_region,
+ surface_canvas,
+ copy->src_area.left,
+ copy->src_area.top,
+ copy->src_area.right - copy->src_area.left,
+ copy->src_area.bottom - copy->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ copy->scale_mode);
+ } else {
+ spice_canvas->ops->scale_image_rop_from_surface(spice_canvas, &dest_region,
+ surface_canvas,
+ copy->src_area.left,
+ copy->src_area.top,
+ copy->src_area.right - copy->src_area.left,
+ copy->src_area.bottom - copy->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ copy->scale_mode,
+ rop);
+ }
+ }
+ } else {
+ src_image = canvas_get_image(canvas, copy->src_bitmap, FALSE);
+ spice_return_if_fail(src_image != NULL);
+
+ if (rect_is_same_size(bbox, ©->src_area)) {
+ if (rop == SPICE_ROP_COPY) {
+ spice_canvas->ops->blit_image(spice_canvas, &dest_region,
+ src_image,
+ bbox->left - copy->src_area.left,
+ bbox->top - copy->src_area.top);
+ } else {
+ spice_canvas->ops->blit_image_rop(spice_canvas, &dest_region,
+ src_image,
+ bbox->left - copy->src_area.left,
+ bbox->top - copy->src_area.top,
+ rop);
+ }
+ } else {
+ if (rop == SPICE_ROP_COPY) {
+ spice_canvas->ops->scale_image(spice_canvas, &dest_region,
+ src_image,
+ copy->src_area.left,
+ copy->src_area.top,
+ copy->src_area.right - copy->src_area.left,
+ copy->src_area.bottom - copy->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ copy->scale_mode);
+ } else {
+ spice_canvas->ops->scale_image_rop(spice_canvas, &dest_region,
+ src_image,
+ copy->src_area.left,
+ copy->src_area.top,
+ copy->src_area.right - copy->src_area.left,
+ copy->src_area.bottom - copy->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ copy->scale_mode,
+ rop);
+ }
+ }
+ pixman_image_unref(src_image);
+ }
+ pixman_region32_fini(&dest_region);
+}
+
+static void canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ SpiceCanvas *surface_canvas;
+ pixman_image_t *src_image;
+ pixman_region32_t dest_region;
+ uint32_t transparent_color;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+ canvas_clip_pixman(canvas, &dest_region, clip);
+
+ if (pixman_region32_n_rects (&dest_region) == 0) {
+ canvas_touch_image(canvas, transparent->src_bitmap);
+ pixman_region32_fini(&dest_region);
+ return;
+ }
+
+ switch (canvas->format) {
+ case SPICE_SURFACE_FMT_32_xRGB:
+ case SPICE_SURFACE_FMT_32_ARGB:
+ transparent_color = transparent->true_color;
+ break;
+ case SPICE_SURFACE_FMT_16_555:
+ transparent_color = rgb_32_to_16_555(transparent->true_color);
+ break;
+ case SPICE_SURFACE_FMT_16_565:
+ transparent_color = rgb_32_to_16_565(transparent->true_color);
+ break;
+ default:
+ transparent_color = 0;
+ }
+
+ surface_canvas = canvas_get_surface(canvas, transparent->src_bitmap);
+ if (surface_canvas) {
+ if (rect_is_same_size(bbox, &transparent->src_area)) {
+ spice_canvas->ops->colorkey_image_from_surface(spice_canvas, &dest_region,
+ surface_canvas,
+ bbox->left - transparent->src_area.left,
+ bbox->top - transparent->src_area.top,
+ transparent_color);
+ } else {
+ spice_canvas->ops->colorkey_scale_image_from_surface(spice_canvas, &dest_region,
+ surface_canvas,
+ transparent->src_area.left,
+ transparent->src_area.top,
+ transparent->src_area.right - transparent->src_area.left,
+ transparent->src_area.bottom - transparent->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ transparent_color);
+ }
+ } else {
+ src_image = canvas_get_image(canvas, transparent->src_bitmap, FALSE);
+ spice_return_if_fail(src_image != NULL);
+
+ if (rect_is_same_size(bbox, &transparent->src_area)) {
+ spice_canvas->ops->colorkey_image(spice_canvas, &dest_region,
+ src_image,
+ bbox->left - transparent->src_area.left,
+ bbox->top - transparent->src_area.top,
+ transparent_color);
+ } else {
+ spice_canvas->ops->colorkey_scale_image(spice_canvas, &dest_region,
+ src_image,
+ transparent->src_area.left,
+ transparent->src_area.top,
+ transparent->src_area.right - transparent->src_area.left,
+ transparent->src_area.bottom - transparent->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ transparent_color);
+ }
+ pixman_image_unref(src_image);
+ }
+ pixman_region32_fini(&dest_region);
+}
+
+static void canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend* alpha_blend)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ pixman_region32_t dest_region;
+ SpiceCanvas *surface_canvas;
+ pixman_image_t *src_image;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+ canvas_clip_pixman(canvas, &dest_region, clip);
+
+ if (alpha_blend->alpha == 0 ||
+ !pixman_region32_not_empty(&dest_region)) {
+ canvas_touch_image(canvas, alpha_blend->src_bitmap);
+ pixman_region32_fini(&dest_region);
+ return;
+ }
+
+ surface_canvas = canvas_get_surface(canvas, alpha_blend->src_bitmap);
+ if (surface_canvas) {
+ if (rect_is_same_size(bbox, &alpha_blend->src_area)) {
+ spice_canvas->ops->blend_image_from_surface(spice_canvas, &dest_region,
+ alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_DEST_HAS_ALPHA,
+ surface_canvas,
+ alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_SRC_SURFACE_HAS_ALPHA,
+ alpha_blend->src_area.left,
+ alpha_blend->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ alpha_blend->alpha);
+ } else {
+ spice_canvas->ops->blend_scale_image_from_surface(spice_canvas, &dest_region,
+ alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_DEST_HAS_ALPHA,
+ surface_canvas,
+ alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_SRC_SURFACE_HAS_ALPHA,
+ alpha_blend->src_area.left,
+ alpha_blend->src_area.top,
+ alpha_blend->src_area.right - alpha_blend->src_area.left,
+ alpha_blend->src_area.bottom - alpha_blend->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ SPICE_IMAGE_SCALE_MODE_NEAREST,
+ alpha_blend->alpha);
+ }
+ } else {
+ src_image = canvas_get_image(canvas, alpha_blend->src_bitmap, TRUE);
+ spice_return_if_fail(src_image != NULL);
+
+ if (rect_is_same_size(bbox, &alpha_blend->src_area)) {
+ spice_canvas->ops->blend_image(spice_canvas, &dest_region,
+ alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_DEST_HAS_ALPHA,
+ src_image,
+ alpha_blend->src_area.left,
+ alpha_blend->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ alpha_blend->alpha);
+ } else {
+ spice_canvas->ops->blend_scale_image(spice_canvas, &dest_region,
+ alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_DEST_HAS_ALPHA,
+ src_image,
+ alpha_blend->src_area.left,
+ alpha_blend->src_area.top,
+ alpha_blend->src_area.right - alpha_blend->src_area.left,
+ alpha_blend->src_area.bottom - alpha_blend->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ SPICE_IMAGE_SCALE_MODE_NEAREST,
+ alpha_blend->alpha);
+ }
+
+ pixman_image_unref(src_image);
+ }
+
+ pixman_region32_fini(&dest_region);
+}
+
+static void canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ pixman_image_t *src_image;
+ pixman_region32_t dest_region;
+ SpiceCanvas *surface_canvas;
+ SpiceROP rop;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+ canvas_clip_pixman(canvas, &dest_region, clip);
+ canvas_mask_pixman(canvas, &dest_region, &opaque->mask,
+ bbox->left, bbox->top);
+
+ rop = ropd_descriptor_to_rop(opaque->rop_descriptor,
+ ROP_INPUT_BRUSH,
+ ROP_INPUT_SRC);
+
+ if (rop == SPICE_ROP_NOOP || !pixman_region32_not_empty(&dest_region)) {
+ canvas_touch_image(canvas, opaque->src_bitmap);
+ touch_brush(canvas, &opaque->brush);
+ pixman_region32_fini(&dest_region);
+ return;
+ }
+
+ surface_canvas = canvas_get_surface(canvas, opaque->src_bitmap);
+ if (surface_canvas) {
+ if (rect_is_same_size(bbox, &opaque->src_area)) {
+ spice_canvas->ops->blit_image_from_surface(spice_canvas, &dest_region,
+ surface_canvas,
+ bbox->left - opaque->src_area.left,
+ bbox->top - opaque->src_area.top);
+ } else {
+ spice_canvas->ops->scale_image_from_surface(spice_canvas, &dest_region,
+ surface_canvas,
+ opaque->src_area.left,
+ opaque->src_area.top,
+ opaque->src_area.right - opaque->src_area.left,
+ opaque->src_area.bottom - opaque->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ opaque->scale_mode);
+ }
+ } else {
+ src_image = canvas_get_image(canvas, opaque->src_bitmap, FALSE);
+ spice_return_if_fail(src_image != NULL);
+
+ if (rect_is_same_size(bbox, &opaque->src_area)) {
+ spice_canvas->ops->blit_image(spice_canvas, &dest_region,
+ src_image,
+ bbox->left - opaque->src_area.left,
+ bbox->top - opaque->src_area.top);
+ } else {
+ spice_canvas->ops->scale_image(spice_canvas, &dest_region,
+ src_image,
+ opaque->src_area.left,
+ opaque->src_area.top,
+ opaque->src_area.right - opaque->src_area.left,
+ opaque->src_area.bottom - opaque->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ opaque->scale_mode);
+ }
+ pixman_image_unref(src_image);
+ }
+
+ draw_brush(spice_canvas, &dest_region, &opaque->brush, rop);
+
+ pixman_region32_fini(&dest_region);
+}
+
+static void canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ SpiceCanvas *surface_canvas;
+ pixman_image_t *src_image;
+ pixman_region32_t dest_region;
+ SpiceROP rop;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+ canvas_clip_pixman(canvas, &dest_region, clip);
+ canvas_mask_pixman(canvas, &dest_region, &blend->mask,
+ bbox->left, bbox->top);
+
+ rop = ropd_descriptor_to_rop(blend->rop_descriptor,
+ ROP_INPUT_SRC,
+ ROP_INPUT_DEST);
+
+ if (rop == SPICE_ROP_NOOP || !pixman_region32_not_empty(&dest_region)) {
+ canvas_touch_image(canvas, blend->src_bitmap);
+ pixman_region32_fini(&dest_region);
+ return;
+ }
+
+ surface_canvas = canvas_get_surface(canvas, blend->src_bitmap);
+ if (surface_canvas) {
+ if (rect_is_same_size(bbox, &blend->src_area)) {
+ if (rop == SPICE_ROP_COPY)
+ spice_canvas->ops->blit_image_from_surface(spice_canvas, &dest_region,
+ surface_canvas,
+ bbox->left - blend->src_area.left,
+ bbox->top - blend->src_area.top);
+ else
+ spice_canvas->ops->blit_image_rop_from_surface(spice_canvas, &dest_region,
+ surface_canvas,
+ bbox->left - blend->src_area.left,
+ bbox->top - blend->src_area.top,
+ rop);
+ } else {
+ if (rop == SPICE_ROP_COPY) {
+ spice_canvas->ops->scale_image_from_surface(spice_canvas, &dest_region,
+ surface_canvas,
+ blend->src_area.left,
+ blend->src_area.top,
+ blend->src_area.right - blend->src_area.left,
+ blend->src_area.bottom - blend->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ blend->scale_mode);
+ } else {
+ spice_canvas->ops->scale_image_rop_from_surface(spice_canvas, &dest_region,
+ surface_canvas,
+ blend->src_area.left,
+ blend->src_area.top,
+ blend->src_area.right - blend->src_area.left,
+ blend->src_area.bottom - blend->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ blend->scale_mode, rop);
+ }
+ }
+ } else {
+ src_image = canvas_get_image(canvas, blend->src_bitmap, FALSE);
+ spice_return_if_fail(src_image != NULL);
+
+ if (rect_is_same_size(bbox, &blend->src_area)) {
+ if (rop == SPICE_ROP_COPY)
+ spice_canvas->ops->blit_image(spice_canvas, &dest_region,
+ src_image,
+ bbox->left - blend->src_area.left,
+ bbox->top - blend->src_area.top);
+ else
+ spice_canvas->ops->blit_image_rop(spice_canvas, &dest_region,
+ src_image,
+ bbox->left - blend->src_area.left,
+ bbox->top - blend->src_area.top,
+ rop);
+ } else {
+ if (rop == SPICE_ROP_COPY) {
+ spice_canvas->ops->scale_image(spice_canvas, &dest_region,
+ src_image,
+ blend->src_area.left,
+ blend->src_area.top,
+ blend->src_area.right - blend->src_area.left,
+ blend->src_area.bottom - blend->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ blend->scale_mode);
+ } else {
+ spice_canvas->ops->scale_image_rop(spice_canvas, &dest_region,
+ src_image,
+ blend->src_area.left,
+ blend->src_area.top,
+ blend->src_area.right - blend->src_area.left,
+ blend->src_area.bottom - blend->src_area.top,
+ bbox->left,
+ bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top,
+ blend->scale_mode, rop);
+ }
+ }
+ pixman_image_unref(src_image);
+ }
+ pixman_region32_fini(&dest_region);
+}
+
+static void canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ pixman_region32_t dest_region;
+ pixman_box32_t *rects;
+ int n_rects;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+
+ canvas_clip_pixman(canvas, &dest_region, clip);
+ canvas_mask_pixman(canvas, &dest_region, &blackness->mask,
+ bbox->left, bbox->top);
+
+ if (!pixman_region32_not_empty(&dest_region)) {
+ pixman_region32_fini (&dest_region);
+ return;
+ }
+
+ rects = pixman_region32_rectangles(&dest_region, &n_rects);
+
+ spice_canvas->ops->fill_solid_rects(spice_canvas, rects, n_rects, 0x000000);
+
+ pixman_region32_fini(&dest_region);
+}
+
+static void canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ pixman_region32_t dest_region;
+ pixman_box32_t *rects;
+ int n_rects;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+
+ canvas_clip_pixman(canvas, &dest_region, clip);
+ canvas_mask_pixman(canvas, &dest_region, &whiteness->mask,
+ bbox->left, bbox->top);
+
+ if (!pixman_region32_not_empty(&dest_region)) {
+ pixman_region32_fini(&dest_region);
+ return;
+ }
+
+ rects = pixman_region32_rectangles(&dest_region, &n_rects);
+ spice_canvas->ops->fill_solid_rects(spice_canvas, rects, n_rects, 0xffffffff);
+
+ pixman_region32_fini(&dest_region);
+}
+
+static void canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ pixman_region32_t dest_region;
+ pixman_box32_t *rects;
+ int n_rects;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+
+ canvas_clip_pixman(canvas, &dest_region, clip);
+ canvas_mask_pixman(canvas, &dest_region, &invers->mask,
+ bbox->left, bbox->top);
+
+ if (!pixman_region32_not_empty(&dest_region)) {
+ pixman_region32_fini(&dest_region);
+ return;
+ }
+
+ rects = pixman_region32_rectangles(&dest_region, &n_rects);
+ spice_canvas->ops->fill_solid_rects_rop(spice_canvas, rects, n_rects, 0x00000000,
+ SPICE_ROP_INVERT);
+
+ pixman_region32_fini(&dest_region);
+}
+
+typedef struct {
+ lineGC base;
+ SpiceCanvas *canvas;
+ pixman_region32_t dest_region;
+ SpiceROP fore_rop;
+ SpiceROP back_rop;
+ int solid;
+ uint32_t color;
+ int use_surface_canvas;
+ union {
+ SpiceCanvas *surface_canvas;
+ pixman_image_t *tile;
+ };
+ int tile_offset_x;
+ int tile_offset_y;
+} StrokeGC;
+
+static void stroke_fill_spans(lineGC * pGC,
+ int num_spans,
+ SpicePoint *points,
+ int *widths,
+ int sorted,
+ int foreground)
+{
+ SpiceCanvas *canvas;
+ StrokeGC *strokeGC;
+ int i;
+ SpiceROP rop;
+
+ strokeGC = (StrokeGC *)pGC;
+ canvas = strokeGC->canvas;
+
+ num_spans = spice_canvas_clip_spans(&strokeGC->dest_region,
+ points, widths, num_spans,
+ points, widths, sorted);
+
+ if (foreground) {
+ rop = strokeGC->fore_rop;
+ } else {
+ rop = strokeGC->back_rop;
+ }
+
+ if (strokeGC->solid) {
+ if (rop == SPICE_ROP_COPY) {
+ canvas->ops->fill_solid_spans(canvas, points, widths, num_spans,
+ strokeGC->color);
+ } else {
+ for (i = 0; i < num_spans; i++) {
+ pixman_box32_t r;
+ r.x1 = points[i].x;
+ r.y1 = points[i].y;
+ r.x2 = points[i].x + widths[i];
+ r.y2 = r.y1 + 1;
+ canvas->ops->fill_solid_rects_rop(canvas, &r, 1,
+ strokeGC->color, rop);
+ }
+ }
+ } else {
+ if (rop == SPICE_ROP_COPY) {
+ for (i = 0; i < num_spans; i++) {
+ pixman_box32_t r;
+ r.x1 = points[i].x;
+ r.y1 = points[i].y;
+ r.x2 = points[i].x + widths[i];
+ r.y2 = r.y1 + 1;
+ canvas->ops->fill_tiled_rects(canvas, &r, 1,
+ strokeGC->tile,
+ strokeGC->tile_offset_x,
+ strokeGC->tile_offset_y);
+ }
+ } else {
+ for (i = 0; i < num_spans; i++) {
+ pixman_box32_t r;
+ r.x1 = points[i].x;
+ r.y1 = points[i].y;
+ r.x2 = points[i].x + widths[i];
+ r.y2 = r.y1 + 1;
+ canvas->ops->fill_tiled_rects_rop(canvas, &r, 1,
+ strokeGC->tile,
+ strokeGC->tile_offset_x,
+ strokeGC->tile_offset_y, rop);
+ }
+ }
+ }
+}
+
+static void stroke_fill_rects(lineGC * pGC,
+ int num_rects,
+ pixman_rectangle32_t *rects,
+ int foreground)
+{
+ SpiceCanvas *canvas;
+ pixman_region32_t area;
+ pixman_box32_t *boxes;
+ StrokeGC *strokeGC;
+ SpiceROP rop;
+ int i;
+ pixman_box32_t *area_rects;
+ int n_area_rects;
+
+ strokeGC = (StrokeGC *)pGC;
+ canvas = strokeGC->canvas;
+
+ if (foreground) {
+ rop = strokeGC->fore_rop;
+ } else {
+ rop = strokeGC->back_rop;
+ }
+
+ /* TODO: We can optimize this for more common cases where
+ dest is one rect */
+
+ boxes = spice_new(pixman_box32_t, num_rects);
+ for (i = 0; i < num_rects; i++) {
+ boxes[i].x1 = rects[i].x;
+ boxes[i].y1 = rects[i].y;
+ boxes[i].x2 = rects[i].x + rects[i].width;
+ boxes[i].y2 = rects[i].y + rects[i].height;
+ }
+ pixman_region32_init_rects(&area, boxes, num_rects);
+ pixman_region32_intersect(&area, &area, &strokeGC->dest_region);
+ free(boxes);
+
+ area_rects = pixman_region32_rectangles(&area, &n_area_rects);
+
+ if (strokeGC->solid) {
+ if (rop == SPICE_ROP_COPY) {
+ canvas->ops->fill_solid_rects(canvas, area_rects, n_area_rects,
+ strokeGC->color);
+ } else {
+ canvas->ops->fill_solid_rects_rop(canvas, area_rects, n_area_rects,
+ strokeGC->color, rop);
+ }
+ } else {
+ if (rop == SPICE_ROP_COPY) {
+ if (strokeGC->use_surface_canvas) {
+ canvas->ops->fill_tiled_rects_from_surface(canvas, area_rects, n_area_rects,
+ strokeGC->surface_canvas,
+ strokeGC->tile_offset_x,
+ strokeGC->tile_offset_y);
+ } else {
+ canvas->ops->fill_tiled_rects(canvas, area_rects, n_area_rects,
+ strokeGC->tile,
+ strokeGC->tile_offset_x,
+ strokeGC->tile_offset_y);
+ }
+ } else {
+ if (strokeGC->use_surface_canvas) {
+ canvas->ops->fill_tiled_rects_rop_from_surface(canvas, area_rects, n_area_rects,
+ strokeGC->surface_canvas,
+ strokeGC->tile_offset_x,
+ strokeGC->tile_offset_y,
+ rop);
+ } else {
+ canvas->ops->fill_tiled_rects_rop(canvas, area_rects, n_area_rects,
+ strokeGC->tile,
+ strokeGC->tile_offset_x,
+ strokeGC->tile_offset_y,
+ rop);
+ }
+ }
+ }
+
+ pixman_region32_fini(&area);
+}
+
+typedef struct {
+ SpicePoint *points;
+ int num_points;
+ int size;
+} StrokeLines;
+
+static void stroke_lines_init(StrokeLines *lines)
+{
+ lines->points = spice_new(SpicePoint, 10);
+ lines->size = 10;
+ lines->num_points = 0;
+}
+
+static void stroke_lines_free(StrokeLines *lines)
+{
+ free(lines->points);
+}
+
+static void stroke_lines_append(StrokeLines *lines,
+ int x, int y)
+{
+ if (lines->num_points == lines->size) {
+ lines->size *= 2;
+ lines->points = spice_renew(SpicePoint, lines->points, lines->size);
+ }
+ lines->points[lines->num_points].x = x;
+ lines->points[lines->num_points].y = y;
+ lines->num_points++;
+}
+
+static void stroke_lines_append_fix(StrokeLines *lines,
+ SpicePointFix *point)
+{
+ stroke_lines_append(lines,
+ fix_to_int(point->x),
+ fix_to_int(point->y));
+}
+
+static inline int64_t dot(SPICE_FIXED28_4 x1,
+ SPICE_FIXED28_4 y1,
+ SPICE_FIXED28_4 x2,
+ SPICE_FIXED28_4 y2)
+{
+ return (((int64_t)x1) *((int64_t)x2) +
+ ((int64_t)y1) *((int64_t)y2)) >> 4;
+}
+
+static inline int64_t dot2(SPICE_FIXED28_4 x,
+ SPICE_FIXED28_4 y)
+{
+ return (((int64_t)x) *((int64_t)x) +
+ ((int64_t)y) *((int64_t)y)) >> 4;
+}
+
+static void subdivide_bezier(StrokeLines *lines,
+ SpicePointFix point0,
+ SpicePointFix point1,
+ SpicePointFix point2,
+ SpicePointFix point3)
+{
+ int64_t A2, B2, C2, AB, CB, h1, h2;
+
+ A2 = dot2(point1.x - point0.x,
+ point1.y - point0.y);
+ B2 = dot2(point3.x - point0.x,
+ point3.y - point0.y);
+ C2 = dot2(point2.x - point3.x,
+ point2.y - point3.y);
+
+ AB = dot(point1.x - point0.x,
+ point1.y - point0.y,
+ point3.x - point0.x,
+ point3.y - point0.y);
+
+ CB = dot(point2.x - point3.x,
+ point2.y - point3.y,
+ point0.x - point3.x,
+ point0.y - point3.y);
+
+ h1 = (A2*B2 - AB*AB) >> 3;
+ h2 = (C2*B2 - CB*CB) >> 3;
+
+ if (h1 < B2 && h2 < B2) {
+ /* deviation squared less than half a pixel, use straight line */
+ stroke_lines_append_fix(lines, &point3);
+ } else {
+ SpicePointFix point01, point23, point12, point012, point123, point0123;
+
+ point01.x = (point0.x + point1.x) / 2;
+ point01.y = (point0.y + point1.y) / 2;
+ point12.x = (point1.x + point2.x) / 2;
+ point12.y = (point1.y + point2.y) / 2;
+ point23.x = (point2.x + point3.x) / 2;
+ point23.y = (point2.y + point3.y) / 2;
+ point012.x = (point01.x + point12.x) / 2;
+ point012.y = (point01.y + point12.y) / 2;
+ point123.x = (point12.x + point23.x) / 2;
+ point123.y = (point12.y + point23.y) / 2;
+ point0123.x = (point012.x + point123.x) / 2;
+ point0123.y = (point012.y + point123.y) / 2;
+
+ subdivide_bezier(lines, point0, point01, point012, point0123);
+ subdivide_bezier(lines, point0123, point123, point23, point3);
+ }
+}
+
+static void stroke_lines_append_bezier(StrokeLines *lines,
+ SpicePointFix *point1,
+ SpicePointFix *point2,
+ SpicePointFix *point3)
+{
+ SpicePointFix point0;
+
+ point0.x = int_to_fix(lines->points[lines->num_points-1].x);
+ point0.y = int_to_fix(lines->points[lines->num_points-1].y);
+
+ subdivide_bezier(lines, point0, *point1, *point2, *point3);
+}
+
+static void stroke_lines_draw(StrokeLines *lines,
+ lineGC *gc,
+ int dashed)
+{
+ if (lines->num_points != 0) {
+ if (dashed) {
+ spice_canvas_zero_dash_line(gc, CoordModeOrigin,
+ lines->num_points, lines->points);
+ } else {
+ spice_canvas_zero_line(gc, CoordModeOrigin,
+ lines->num_points, lines->points);
+ }
+ lines->num_points = 0;
+ }
+}
+
+
+static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
+ SpiceClip *clip, SpiceStroke *stroke)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ SpiceCanvas *surface_canvas = NULL;
+ StrokeGC gc;
+ lineGCOps ops = {
+ stroke_fill_spans,
+ stroke_fill_rects
+ };
+ StrokeLines lines;
+ unsigned int i;
+ int dashed;
+
+ memset(&gc, 0, sizeof(gc));
+
+ pixman_region32_init_rect(&gc.dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+ canvas_clip_pixman(canvas, &gc.dest_region, clip);
+
+ if (!pixman_region32_not_empty(&gc.dest_region)) {
+ touch_brush(canvas, &stroke->brush);
+ pixman_region32_fini(&gc.dest_region);
+ return;
+ }
+
+ gc.canvas = spice_canvas;
+ gc.fore_rop = ropd_descriptor_to_rop(stroke->fore_mode,
+ ROP_INPUT_BRUSH,
+ ROP_INPUT_DEST);
+ gc.back_rop = ropd_descriptor_to_rop(stroke->back_mode,
+ ROP_INPUT_BRUSH,
+ ROP_INPUT_DEST);
+
+ gc.base.width = canvas->width;
+ gc.base.height = canvas->height;
+ gc.base.alu = gc.fore_rop;
+ gc.base.lineWidth = 0;
+
+ /* dash */
+ gc.base.dashOffset = 0;
+ gc.base.dash = NULL;
+ gc.base.numInDashList = 0;
+ gc.base.lineStyle = LineSolid;
+ /* win32 cosmetic lines are endpoint-exclusive, so use CapNotLast */
+ gc.base.capStyle = CapNotLast;
+ gc.base.joinStyle = JoinMiter;
+ gc.base.ops = &ops;
+
+ dashed = 0;
+ if (stroke->attr.flags & SPICE_LINE_FLAGS_STYLED) {
+ SPICE_FIXED28_4 *style = stroke->attr.style;
+ int nseg;
+
+ dashed = 1;
+
+ nseg = stroke->attr.style_nseg;
+
+ /* To truly handle back_mode we should use LineDoubleDash here
+ and treat !foreground as back_rop using the same brush.
+ However, using the same brush for that seems wrong.
+ The old cairo backend was stroking the non-dashed line with
+ rop_mode before enabling dashes for the foreground which is
+ not right either. The gl an gdi backend don't use back_mode
+ at all */
+ gc.base.lineStyle = LineOnOffDash;
+ gc.base.dash = (unsigned char *)spice_malloc(nseg);
+ gc.base.numInDashList = nseg;
+
+ if (stroke->attr.flags & SPICE_LINE_FLAGS_START_WITH_GAP) {
+ gc.base.dash[stroke->attr.style_nseg - 1] = fix_to_int(style[0]);
+ for (i = 0; i < (unsigned int)(stroke->attr.style_nseg - 1); i++) {
+ gc.base.dash[i] = fix_to_int(style[i+1]);
+ }
+ gc.base.dashOffset = gc.base.dash[0];
+ } else {
+ for (i = 0; i < stroke->attr.style_nseg; i++) {
+ gc.base.dash[i] = fix_to_int(style[i]);
+ }
+ }
+ }
+
+ switch (stroke->brush.type) {
+ case SPICE_BRUSH_TYPE_NONE:
+ gc.solid = TRUE;
+ gc.color = 0;
+ break;
+ case SPICE_BRUSH_TYPE_SOLID:
+ gc.solid = TRUE;
+ gc.color = stroke->brush.u.color;
+ break;
+ case SPICE_BRUSH_TYPE_PATTERN:
+ gc.solid = FALSE;
+ surface_canvas = canvas_get_surface(canvas,
+ stroke->brush.u.pattern.pat);
+ if (surface_canvas) {
+ gc.use_surface_canvas = TRUE;
+ gc.surface_canvas = surface_canvas;
+ } else {
+ gc.use_surface_canvas = FALSE;
+ gc.tile = canvas_get_image(canvas,
+ stroke->brush.u.pattern.pat,
+ FALSE);
+ }
+ gc.tile_offset_x = stroke->brush.u.pattern.pos.x;
+ gc.tile_offset_y = stroke->brush.u.pattern.pos.y;
+ break;
+ default:
+ spice_warn_if_reached();
+ return;
+ }
+
+ stroke_lines_init(&lines);
+
+ for (i = 0; i < stroke->path->num_segments; i++) {
+ SpicePathSeg *seg = stroke->path->segments[i];
+ SpicePointFix* point, *end_point;
+
+ point = seg->points;
+ end_point = point + seg->count;
+
+ if (seg->flags & SPICE_PATH_BEGIN) {
+ stroke_lines_draw(&lines, (lineGC *)&gc, dashed);
+ stroke_lines_append_fix(&lines, point);
+ point++;
+ }
+
+ if (seg->flags & SPICE_PATH_BEZIER) {
+ spice_return_if_fail((point - end_point) % 3 == 0);
+ for (; point + 2 < end_point; point += 3) {
+ stroke_lines_append_bezier(&lines,
+ &point[0],
+ &point[1],
+ &point[2]);
+ }
+ } else
+ {
+ for (; point < end_point; point++) {
+ stroke_lines_append_fix(&lines, point);
+ }
+ }
+ if (seg->flags & SPICE_PATH_END) {
+ if (seg->flags & SPICE_PATH_CLOSE) {
+ stroke_lines_append(&lines,
+ lines.points[0].x, lines.points[0].y);
+ }
+ stroke_lines_draw(&lines, (lineGC *)&gc, dashed);
+ }
+ }
+
+ stroke_lines_draw(&lines, (lineGC *)&gc, dashed);
+
+ free(gc.base.dash);
+ stroke_lines_free(&lines);
+
+ if (!gc.solid && gc.tile && !surface_canvas) {
+ pixman_image_unref(gc.tile);
+ }
+
+ pixman_region32_fini(&gc.dest_region);
+}
+
+
+//need surfaces handling here !!!
+static void canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox,
+ SpiceClip *clip, SpiceRop3 *rop3)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ SpiceCanvas *surface_canvas;
+ pixman_region32_t dest_region;
+ pixman_image_t *d;
+ pixman_image_t *s;
+ SpicePoint src_pos;
+ int width;
+ int heigth;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+ canvas_clip_pixman(canvas, &dest_region, clip);
+ canvas_mask_pixman(canvas, &dest_region, &rop3->mask,
+ bbox->left, bbox->top);
+
+ width = bbox->right - bbox->left;
+ heigth = bbox->bottom - bbox->top;
+
+ d = canvas_get_image_from_self(spice_canvas, bbox->left, bbox->top, width, heigth, FALSE);
+ surface_canvas = canvas_get_surface(canvas, rop3->src_bitmap);
+ if (surface_canvas) {
+ s = surface_canvas->ops->get_image(surface_canvas, FALSE);
+ } else {
+ s = canvas_get_image(canvas, rop3->src_bitmap, FALSE);
+ }
+
+ if (!rect_is_same_size(bbox, &rop3->src_area)) {
+ pixman_image_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, width, heigth,
+ rop3->scale_mode);
+ pixman_image_unref(s);
+ s = scaled_s;
+ src_pos.x = 0;
+ src_pos.y = 0;
+ } else {
+ src_pos.x = rop3->src_area.left;
+ src_pos.y = rop3->src_area.top;
+ }
+ if (pixman_image_get_width(s) - src_pos.x < width ||
+ pixman_image_get_height(s) - src_pos.y < heigth) {
+ spice_critical("bad src bitmap size");
+ return;
+ }
+ if (rop3->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ SpiceCanvas *_surface_canvas;
+ pixman_image_t *p;
+
+ _surface_canvas = canvas_get_surface(canvas, rop3->brush.u.pattern.pat);
+ if (_surface_canvas) {
+ p = _surface_canvas->ops->get_image(_surface_canvas, FALSE);
+ } else {
+ p = canvas_get_image(canvas, rop3->brush.u.pattern.pat, FALSE);
+ }
+ SpicePoint pat_pos;
+
+ pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % pixman_image_get_width(p);
+ pat_pos.y = (bbox->top - rop3->brush.u.pattern.pos.y) % pixman_image_get_height(p);
+ do_rop3_with_pattern(rop3->rop3, d, s, &src_pos, p, &pat_pos);
+ pixman_image_unref(p);
+ } else {
+ do_rop3_with_color(rop3->rop3, d, s, &src_pos, rop3->brush.u.color);
+ }
+ pixman_image_unref(s);
+
+ spice_canvas->ops->blit_image(spice_canvas, &dest_region, d,
+ bbox->left,
+ bbox->top);
+
+ pixman_image_unref(d);
+
+ pixman_region32_fini(&dest_region);
+}
+
+static void transform_to_pixman_transform(SpiceTransform *transform,
+ pixman_transform_t *p)
+{
+ p->matrix[0][0] = transform->t00;
+ p->matrix[0][1] = transform->t01;
+ p->matrix[0][2] = transform->t02;
+ p->matrix[1][0] = transform->t10;
+ p->matrix[1][1] = transform->t11;
+ p->matrix[1][2] = transform->t12;
+ p->matrix[2][0] = 0;
+ p->matrix[2][1] = 0;
+ p->matrix[2][2] = pixman_fixed_1;
+}
+
+#define MASK(lo, hi) \
+ (((1U << (hi)) - 1) - (((1U << (lo))) - 1))
+
+#define EXTRACT(v, lo, hi) \
+ ((v & MASK(lo, hi)) >> lo)
+
+static void canvas_draw_composite(SpiceCanvas *spice_canvas, SpiceRect *bbox,
+ SpiceClip *clip, SpiceComposite *composite)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ SpiceCanvas *surface_canvas;
+ pixman_region32_t dest_region;
+ pixman_image_t *d;
+ pixman_image_t *s;
+ pixman_image_t *m;
+ pixman_repeat_t src_repeat;
+ pixman_filter_t src_filter;
+ pixman_op_t op;
+ pixman_transform_t transform;
+ int width, height;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+ canvas_clip_pixman(canvas, &dest_region, clip);
+
+ width = bbox->right - bbox->left;
+ height = bbox->bottom - bbox->top;
+
+ /* Dest */
+ d = canvas_get_image_from_self(spice_canvas, bbox->left, bbox->top, width, height,
+ (composite->flags & SPICE_COMPOSITE_DEST_OPAQUE));
+
+ /* Src */
+ surface_canvas = canvas_get_surface(canvas, composite->src_bitmap);
+ if (surface_canvas) {
+ s = surface_canvas->ops->get_image(surface_canvas,
+ (composite->flags & SPICE_COMPOSITE_SOURCE_OPAQUE));
+ } else {
+ s = canvas_get_image(canvas, composite->src_bitmap, FALSE);
+ }
+ if (composite->flags & SPICE_COMPOSITE_HAS_SRC_TRANSFORM)
+ {
+ transform_to_pixman_transform (&composite->src_transform, &transform);
+ pixman_image_set_transform (s, &transform);
+ }
+ src_filter = (pixman_filter_t) EXTRACT (composite->flags, 8, 11);
+ src_repeat = (pixman_repeat_t) EXTRACT (composite->flags, 14, 16);
+ pixman_image_set_filter (s, src_filter, NULL, 0);
+ pixman_image_set_repeat (s, src_repeat);
+
+ /* Mask */
+ m = NULL;
+ if (composite->flags & SPICE_COMPOSITE_HAS_MASK) {
+ pixman_filter_t mask_filter = (pixman_filter_t) EXTRACT (composite->flags, 11, 14);
+ pixman_repeat_t mask_repeat = (pixman_repeat_t) EXTRACT (composite->flags, 16, 18);
+ pixman_bool_t component_alpha = EXTRACT (composite->flags, 18, 19);
+
+ surface_canvas = canvas_get_surface(canvas, composite->mask_bitmap);
+ if (surface_canvas) {
+ m = surface_canvas->ops->get_image(surface_canvas, FALSE);
+ } else {
+ m = canvas_get_image(canvas, composite->mask_bitmap, FALSE);
+ }
+
+ if (composite->flags & SPICE_COMPOSITE_HAS_MASK_TRANSFORM) {
+ transform_to_pixman_transform (&composite->mask_transform, &transform);
+ pixman_image_set_transform (m, &transform);
+ }
+
+ pixman_image_set_repeat (m, mask_repeat);
+ pixman_image_set_filter (m, mask_filter, NULL, 0);
+ pixman_image_set_component_alpha (m, component_alpha);
+ }
+
+ op = (pixman_op_t) EXTRACT (composite->flags, 0, 8);
+
+ pixman_image_composite32 (op, s, m, d,
+ composite->src_origin.x, composite->src_origin.y,
+ composite->mask_origin.x, composite->mask_origin.y,
+ 0, 0, width, height);
+
+ pixman_image_unref(s);
+ if (m)
+ pixman_image_unref(m);
+
+ spice_canvas->ops->blit_image(spice_canvas, &dest_region, d,
+ bbox->left,
+ bbox->top);
+
+ pixman_image_unref(d);
+
+ pixman_region32_fini(&dest_region);
+}
+
+static void canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ pixman_region32_t dest_region;
+ int dx, dy;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+ canvas_clip_pixman(canvas, &dest_region, clip);
+
+ dx = bbox->left - src_pos->x;
+ dy = bbox->top - src_pos->y;
+
+ if (dx != 0 || dy != 0) {
+ pixman_region32_t src_region;
+
+ /* Clip so we don't read outside canvas */
+ pixman_region32_init_rect(&src_region,
+ dx, dy,
+ canvas->width,
+ canvas->height);
+ pixman_region32_intersect(&dest_region, &dest_region, &src_region);
+ pixman_region32_fini(&src_region);
+
+ spice_canvas->ops->copy_region(spice_canvas, &dest_region, dx, dy);
+ }
+
+ pixman_region32_fini(&dest_region);
+}
+
+
+
+static void canvas_base_group_start(SpiceCanvas *spice_canvas, QRegion *region)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ pixman_region32_fini(&canvas->canvas_region);
+
+ /* Make sure we always clip to canvas size */
+ pixman_region32_init_rect(&canvas->canvas_region,
+ 0, 0,
+ canvas->width,
+ canvas->height);
+
+ pixman_region32_intersect(&canvas->canvas_region, &canvas->canvas_region, region);
+}
+
+static void canvas_base_group_end(SpiceCanvas *spice_canvas)
+{
+ CanvasBase *canvas = (CanvasBase *)spice_canvas;
+ pixman_region32_fini(&canvas->canvas_region);
+ pixman_region32_init_rect(&canvas->canvas_region,
+ 0, 0,
+ canvas->width,
+ canvas->height);
+}
+
+
+static void unimplemented_op(SpiceCanvas *canvas)
+{
+ spice_critical("unimplemented canvas operation");
+}
+
+inline static void canvas_base_init_ops(SpiceCanvasOps *ops)
+{
+ void **ops_cast;
+ unsigned i;
+
+ ops_cast = (void **)ops;
+ for (i = 0; i < sizeof(SpiceCanvasOps) / sizeof(void *); i++) {
+ ops_cast[i] = (void *) unimplemented_op;
+ }
+
+ ops->draw_fill = canvas_draw_fill;
+ ops->draw_copy = canvas_draw_copy;
+ ops->draw_opaque = canvas_draw_opaque;
+ ops->copy_bits = canvas_copy_bits;
+ ops->draw_blend = canvas_draw_blend;
+ ops->draw_blackness = canvas_draw_blackness;
+ ops->draw_whiteness = canvas_draw_whiteness;
+ ops->draw_invers = canvas_draw_invers;
+ ops->draw_transparent = canvas_draw_transparent;
+ ops->draw_alpha_blend = canvas_draw_alpha_blend;
+ ops->draw_stroke = canvas_draw_stroke;
+ ops->draw_rop3 = canvas_draw_rop3;
+ ops->draw_composite = canvas_draw_composite;
+ ops->group_start = canvas_base_group_start;
+ ops->group_end = canvas_base_group_end;
+}
+
+static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops,
+ int width, int height, uint32_t format
+ , SpiceImageCache *bits_cache
+#ifdef SW_CANVAS_CACHE
+ , SpicePaletteCache *palette_cache
+#endif
+ , SpiceImageSurfaces *surfaces
+ , SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
+ , SpiceZlibDecoder *zlib_decoder
+ )
+{
+ canvas->parent.ops = ops;
+ canvas->quic_data.usr.error = quic_usr_error;
+ canvas->quic_data.usr.warn = quic_usr_warn;
+ canvas->quic_data.usr.info = quic_usr_warn;
+ canvas->quic_data.usr.malloc = quic_usr_malloc;
+ canvas->quic_data.usr.free = quic_usr_free;
+ canvas->quic_data.usr.more_space = quic_usr_more_space;
+ canvas->quic_data.usr.more_lines = quic_usr_more_lines;
+ if (!(canvas->quic_data.quic = quic_create(&canvas->quic_data.usr))) {
+ return 0;
+ }
+
+ canvas->lz_data.usr.error = lz_usr_error;
+ canvas->lz_data.usr.warn = lz_usr_warn;
+ canvas->lz_data.usr.info = lz_usr_warn;
+ canvas->lz_data.usr.malloc = lz_usr_malloc;
+ canvas->lz_data.usr.free = lz_usr_free;
+ canvas->lz_data.usr.more_space = lz_usr_more_space;
+ canvas->lz_data.usr.more_lines = lz_usr_more_lines;
+ if (!(canvas->lz_data.lz = lz_create(&canvas->lz_data.usr))) {
+ return 0;
+ }
+
+ canvas->surfaces = surfaces;
+ canvas->glz_data.decoder = glz_decoder;
+ canvas->jpeg = jpeg_decoder;
+ canvas->zlib = zlib_decoder;
+
+ canvas->format = format;
+
+ /* TODO: This is all wrong now */
+ if (SPICE_SURFACE_FMT_DEPTH(format) == 16) {
+ canvas->color_shift = 5;
+ canvas->color_mask = 0x1f;
+ } else {
+ canvas->color_shift = 8;
+ canvas->color_mask = 0xff;
+ }
+
+ canvas->width = width;
+ canvas->height = height;
+ pixman_region32_init_rect(&canvas->canvas_region,
+ 0, 0,
+ canvas->width,
+ canvas->height);
+
+ canvas->bits_cache = bits_cache;
+#ifdef SW_CANVAS_CACHE
+ canvas->palette_cache = palette_cache;
+#endif
+
+#ifdef WIN32
+ canvas->dc = NULL;
+#endif
+
+#ifdef GDI_CANVAS
+ canvas->dc = create_compatible_dc();
+ if (!canvas->dc) {
+ lz_destroy(canvas->lz_data.lz);
+ return 0;
+ }
+#endif
+ return 1;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_CANVAS_BASE
+#define _H_CANVAS_BASE
+
+#include <spice/macros.h>
+
+#include "pixman_utils.h"
+#include "lz.h"
+#include "region.h"
+#include "draw.h"
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+SPICE_BEGIN_DECLS
+
+typedef void (*spice_destroy_fn_t)(void *data);
+
+typedef struct _SpiceImageCache SpiceImageCache;
+typedef struct _SpiceImageSurfaces SpiceImageSurfaces;
+typedef struct _SpicePaletteCache SpicePaletteCache;
+typedef struct _SpiceGlzDecoder SpiceGlzDecoder;
+typedef struct _SpiceJpegDecoder SpiceJpegDecoder;
+typedef struct _SpiceZlibDecoder SpiceZlibDecoder;
+typedef struct _SpiceCanvas SpiceCanvas;
+
+typedef struct {
+ void (*put)(SpiceImageCache *cache,
+ uint64_t id,
+ pixman_image_t *surface);
+ pixman_image_t *(*get)(SpiceImageCache *cache,
+ uint64_t id);
+#ifdef SW_CANVAS_CACHE
+ void (*put_lossy)(SpiceImageCache *cache,
+ uint64_t id,
+ pixman_image_t *surface);
+ void (*replace_lossy)(SpiceImageCache *cache,
+ uint64_t id,
+ pixman_image_t *surface);
+ pixman_image_t *(*get_lossless)(SpiceImageCache *cache,
+ uint64_t id);
+#endif
+} SpiceImageCacheOps;
+
+struct _SpiceImageCache {
+ SpiceImageCacheOps *ops;
+};
+
+typedef struct {
+ SpiceCanvas *(*get)(SpiceImageSurfaces *surfaces,
+ uint32_t surface_id);
+} SpiceImageSurfacesOps;
+
+struct _SpiceImageSurfaces {
+ SpiceImageSurfacesOps *ops;
+};
+
+typedef struct {
+ void (*put)(SpicePaletteCache *cache,
+ SpicePalette *palette);
+ SpicePalette *(*get)(SpicePaletteCache *cache,
+ uint64_t id);
+ void (*release)(SpicePaletteCache *cache,
+ SpicePalette *palette);
+} SpicePaletteCacheOps;
+
+struct _SpicePaletteCache {
+ SpicePaletteCacheOps *ops;
+};
+
+typedef struct {
+ void (*decode)(SpiceGlzDecoder *decoder,
+ uint8_t *data,
+ SpicePalette *plt,
+ void *usr_data);
+} SpiceGlzDecoderOps;
+
+struct _SpiceGlzDecoder {
+ SpiceGlzDecoderOps *ops;
+};
+
+
+typedef struct SpiceJpegDecoderOps {
+ void (*begin_decode)(SpiceJpegDecoder *decoder,
+ uint8_t* data,
+ int data_size,
+ int* out_width,
+ int* out_height);
+ void (*decode)(SpiceJpegDecoder *decoder,
+ uint8_t* dest,
+ int stride,
+ int format);
+} SpiceJpegDecoderOps;
+
+struct _SpiceJpegDecoder {
+ SpiceJpegDecoderOps *ops;
+};
+
+typedef struct {
+ void (*decode)(SpiceZlibDecoder *decoder,
+ uint8_t *data,
+ int data_size,
+ uint8_t *dest,
+ int dest_size);
+} SpiceZlibDecoderOps;
+
+struct _SpiceZlibDecoder {
+ SpiceZlibDecoderOps *ops;
+};
+
+typedef struct {
+ void (*draw_fill)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill);
+ void (*draw_copy)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy);
+ void (*draw_opaque)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque);
+ void (*copy_bits)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos);
+ void (*draw_text)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text);
+ void (*draw_stroke)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke);
+ void (*draw_rop3)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3);
+ void (*draw_composite)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceComposite *composite);
+ void (*draw_blend)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend);
+ void (*draw_blackness)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness);
+ void (*draw_whiteness)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness);
+ void (*draw_invers)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers);
+ void (*draw_transparent)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent);
+ void (*draw_alpha_blend)(SpiceCanvas *canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend* alpha_blend);
+ void (*put_image)(SpiceCanvas *canvas,
+#ifdef WIN32
+ HDC dc,
+#endif
+ const SpiceRect *dest, const uint8_t *src_data,
+ uint32_t src_width, uint32_t src_height, int src_stride,
+ const QRegion *clip);
+ void (*clear)(SpiceCanvas *canvas);
+ void (*read_bits)(SpiceCanvas *canvas, uint8_t *dest, int dest_stride, const SpiceRect *area);
+ void (*group_start)(SpiceCanvas *canvas, QRegion *region);
+ void (*group_end)(SpiceCanvas *canvas);
+ void (*destroy)(SpiceCanvas *canvas);
+
+ /* Implementation vfuncs */
+ void (*fill_solid_spans)(SpiceCanvas *canvas,
+ SpicePoint *points,
+ int *widths,
+ int n_spans,
+ uint32_t color);
+ void (*fill_solid_rects)(SpiceCanvas *canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ uint32_t color);
+ void (*fill_solid_rects_rop)(SpiceCanvas *canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ uint32_t color,
+ SpiceROP rop);
+ void (*fill_tiled_rects)(SpiceCanvas *canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ pixman_image_t *tile,
+ int offset_x, int offset_y);
+ void (*fill_tiled_rects_from_surface)(SpiceCanvas *canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ SpiceCanvas *tile,
+ int offset_x, int offset_y);
+ void (*fill_tiled_rects_rop)(SpiceCanvas *canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ pixman_image_t *tile,
+ int offset_x, int offset_y,
+ SpiceROP rop);
+ void (*fill_tiled_rects_rop_from_surface)(SpiceCanvas *canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ SpiceCanvas *tile,
+ int offset_x, int offset_y,
+ SpiceROP rop);
+ void (*blit_image)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src_image,
+ int offset_x, int offset_y);
+ void (*blit_image_from_surface)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ SpiceCanvas *src_image,
+ int offset_x, int offset_y);
+ void (*blit_image_rop)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src_image,
+ int offset_x, int offset_y,
+ SpiceROP rop);
+ void (*blit_image_rop_from_surface)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ SpiceCanvas *src_image,
+ int offset_x, int offset_y,
+ SpiceROP rop);
+ void (*scale_image)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src_image,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode);
+ void (*scale_image_from_surface)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ SpiceCanvas *src_image,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode);
+ void (*scale_image_rop)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src_image,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode, SpiceROP rop);
+ void (*scale_image_rop_from_surface)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ SpiceCanvas *src_image,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode, SpiceROP rop);
+ void (*blend_image)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ int dest_has_alpha,
+ pixman_image_t *src_image,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height,
+ int overall_alpha);
+ void (*blend_image_from_surface)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ int dest_has_alpha,
+ SpiceCanvas *src_image,
+ int src_has_alpha,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height,
+ int overall_alpha);
+ void (*blend_scale_image)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ int dest_has_alpha,
+ pixman_image_t *src_image,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode,
+ int overall_alpha);
+ void (*blend_scale_image_from_surface)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ int dest_has_alpha,
+ SpiceCanvas *src_image,
+ int src_has_alpha,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode,
+ int overall_alpha);
+ void (*colorkey_image)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src_image,
+ int offset_x, int offset_y,
+ uint32_t transparent_color);
+ void (*colorkey_image_from_surface)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ SpiceCanvas *src_image,
+ int offset_x, int offset_y,
+ uint32_t transparent_color);
+ void (*colorkey_scale_image)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src_image,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ uint32_t transparent_color);
+ void (*colorkey_scale_image_from_surface)(SpiceCanvas *canvas,
+ pixman_region32_t *region,
+ SpiceCanvas *src_image,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ uint32_t transparent_color);
+ void (*copy_region)(SpiceCanvas *canvas,
+ pixman_region32_t *dest_region,
+ int dx, int dy);
+ pixman_image_t *(*get_image)(SpiceCanvas *canvas, int force_opaque);
+} SpiceCanvasOps;
+
+void spice_canvas_set_usr_data(SpiceCanvas *canvas, void *data, spice_destroy_fn_t destroy_fn);
+void *spice_canvas_get_usr_data(SpiceCanvas *canvas);
+
+struct _SpiceCanvas {
+ SpiceCanvasOps *ops;
+};
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spice_common.h"
+
+#include "canvas_utils.h"
+#include "mem.h"
+
+#ifdef WIN32
+static int gdi_handlers = 0;
+#endif
+
+static void release_data(SPICE_GNUC_UNUSED pixman_image_t *image,
+ void *release_data)
+{
+ PixmanData *data = (PixmanData *)release_data;
+
+#ifdef WIN32
+ if (data->bitmap) {
+ DeleteObject((HBITMAP)data->bitmap);
+ CloseHandle(data->mutex);
+ gdi_handlers--;
+ }
+#endif
+ free(data->data);
+
+ free(data);
+}
+
+static PixmanData *
+pixman_image_add_data(pixman_image_t *image)
+{
+ PixmanData *data;
+
+ data = (PixmanData *)pixman_image_get_destroy_data(image);
+ if (data == NULL) {
+ data = (PixmanData *)calloc(1, sizeof(PixmanData));
+ if (data == NULL) {
+ spice_error("out of memory");
+ }
+ pixman_image_set_destroy_function(image,
+ release_data,
+ data);
+ }
+
+ return data;
+}
+
+void
+spice_pixman_image_set_format(pixman_image_t *image,
+ pixman_format_code_t format)
+{
+ PixmanData *data;
+
+ data = pixman_image_add_data(image);
+ data->format = format;
+}
+
+
+int spice_pixman_image_get_format(pixman_image_t *image, pixman_format_code_t *format)
+{
+ PixmanData *data;
+
+ spice_return_val_if_fail(format != NULL, 0);
+
+ data = (PixmanData *)pixman_image_get_destroy_data(image);
+ if (data != NULL && data->format != 0) {
+ *format = data->format;
+ return 1;
+ }
+
+ spice_warn_if_reached();
+ return 0;
+}
+
+static inline pixman_image_t *__surface_create_stride(pixman_format_code_t format, int width, int height,
+ int stride)
+{
+ uint8_t *data;
+ uint8_t *stride_data;
+ pixman_image_t *surface;
+ PixmanData *pixman_data;
+
+ data = (uint8_t *)spice_malloc_n(abs(stride), height);
+ if (stride < 0) {
+ stride_data = data + (-stride) * (height - 1);
+ } else {
+ stride_data = data;
+ }
+
+ surface = pixman_image_create_bits(format, width, height, (uint32_t *)stride_data, stride);
+
+ if (surface == NULL) {
+ free(data);
+ data = NULL;
+ spice_error("create surface failed, out of memory");
+ }
+
+ pixman_data = pixman_image_add_data(surface);
+ pixman_data->data = data;
+ pixman_data->format = format;
+
+ return surface;
+}
+
+#ifdef WIN32
+pixman_image_t *surface_create(HDC dc, pixman_format_code_t format,
+ int width, int height, int top_down)
+#else
+pixman_image_t * surface_create(pixman_format_code_t format, int width, int height, int top_down)
+#endif
+{
+#ifdef WIN32
+ /*
+ * Windows xp allow only 10,000 of gdi handlers, considering the fact that
+ * we limit here the number to 5000, we dont use atomic operations to sync
+ * this calculation against the other canvases (in case of multiple
+ * monitors), in worst case there will be little more than 5000 gdi
+ * handlers.
+ */
+ if (dc && gdi_handlers < 5000) {
+ uint8_t *data;
+ uint8_t *src;
+ struct {
+ BITMAPINFO inf;
+ RGBQUAD palette[255];
+ } bitmap_info;
+ int nstride;
+ pixman_image_t *surface;
+ PixmanData *pixman_data;
+ HBITMAP bitmap;
+ HANDLE mutex;
+
+ memset(&bitmap_info, 0, sizeof(bitmap_info));
+ bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader);
+ bitmap_info.inf.bmiHeader.biWidth = width;
+
+ bitmap_info.inf.bmiHeader.biHeight = (!top_down) ? height : -height;
+
+ bitmap_info.inf.bmiHeader.biPlanes = 1;
+ switch (format) {
+ case PIXMAN_a8r8g8b8:
+ case PIXMAN_x8r8g8b8:
+#ifdef WORDS_BIGENDIAN
+ case PIXMAN_b8g8r8a8:
+ case PIXMAN_b8g8r8x8:
+#endif
+ bitmap_info.inf.bmiHeader.biBitCount = 32;
+ nstride = width * 4;
+ break;
+ case PIXMAN_r8g8b8:
+#ifdef WORDS_BIGENDIAN
+ case PIXMAN_b8g8r8:
+#endif
+ bitmap_info.inf.bmiHeader.biBitCount = 24;
+ nstride = SPICE_ALIGN(width * 3, 4);
+ break;
+ case PIXMAN_x1r5g5b5:
+ case PIXMAN_r5g6b5:
+ bitmap_info.inf.bmiHeader.biBitCount = 16;
+ nstride = SPICE_ALIGN(width * 2, 4);
+ break;
+ case PIXMAN_a8:
+ bitmap_info.inf.bmiHeader.biBitCount = 8;
+ nstride = SPICE_ALIGN(width, 4);
+ break;
+ case PIXMAN_a1:
+ bitmap_info.inf.bmiHeader.biBitCount = 1;
+ nstride = SPICE_ALIGN(width, 32) / 8;
+ break;
+ default:
+ spice_error("invalid format");
+ return NULL;
+ }
+
+ bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
+
+ mutex = CreateMutex(NULL, 0, NULL);
+ if (!mutex) {
+ spice_error("Unable to CreateMutex");
+ }
+
+ bitmap = CreateDIBSection(dc, &bitmap_info.inf, 0, (VOID **)&data, NULL, 0);
+ if (!bitmap) {
+ CloseHandle(mutex);
+ spice_error("Unable to CreateDIBSection");
+ }
+
+ if (top_down) {
+ src = data;
+ } else {
+ src = data + nstride * (height - 1);
+ nstride = -nstride;
+ }
+
+ surface = pixman_image_create_bits(format, width, height, (uint32_t *)src, nstride);
+ if (surface == NULL) {
+ CloseHandle(mutex);
+ DeleteObject(bitmap);
+ spice_error("create surface failed, out of memory");
+ }
+ pixman_data = pixman_image_add_data(surface);
+ pixman_data->format = format;
+ pixman_data->bitmap = bitmap;
+ pixman_data->mutex = mutex;
+ gdi_handlers++;
+ return surface;
+ } else {
+#endif
+ if (top_down) {
+ pixman_image_t *surface;
+ PixmanData *data;
+
+ surface = pixman_image_create_bits(format, width, height, NULL, 0);
+ data = pixman_image_add_data(surface);
+ data->format = format;
+ return surface;
+ } else {
+ // NOTE: we assume here that the lz decoders always decode to RGB32.
+ int stride = 0;
+ switch (format) {
+ case PIXMAN_a8r8g8b8:
+ case PIXMAN_x8r8g8b8:
+#ifdef WORDS_BIGENDIAN
+ case PIXMAN_b8g8r8a8:
+ case PIXMAN_b8g8r8x8:
+#endif
+ stride = width * 4;
+ break;
+ case PIXMAN_r8g8b8:
+#ifdef WORDS_BIGENDIAN
+ case PIXMAN_b8g8r8:
+#endif
+ // NOTE: LZ4 also decodes to RGB24
+ stride = SPICE_ALIGN(width * 3, 4);
+ break;
+ case PIXMAN_x1r5g5b5:
+ case PIXMAN_r5g6b5:
+ stride = SPICE_ALIGN(width * 2, 4);
+ break;
+ case PIXMAN_a8:
+ stride = SPICE_ALIGN(width, 4);
+ break;
+ case PIXMAN_a1:
+ stride = SPICE_ALIGN(width, 32) / 8;
+ break;
+ default:
+ spice_error("invalid format");
+ }
+ stride = -stride;
+ return __surface_create_stride(format, width, height, stride);
+ }
+#ifdef WIN32
+}
+
+#endif
+}
+
+#ifdef WIN32
+pixman_image_t *surface_create_stride(HDC dc, pixman_format_code_t format, int width, int height,
+ int stride)
+#else
+pixman_image_t *surface_create_stride(pixman_format_code_t format, int width, int height,
+ int stride)
+#endif
+{
+#ifdef WIN32
+ if (dc) {
+ if (abs(stride) == (width * 4)) {
+ return surface_create(dc, format, width, height, (stride > 0));
+ }
+ }
+#endif
+
+ return __surface_create_stride(format, width, height, stride);
+}
+
+pixman_image_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data,
+ pixman_format_code_t pixman_format, int width,
+ int height, int gross_pixels, int top_down)
+{
+ int stride;
+ pixman_image_t *surface = NULL;
+
+ stride = (gross_pixels / height) * (PIXMAN_FORMAT_BPP (pixman_format) / 8);
+
+ /* pixman requires strides to be 4-byte aligned */
+ stride = SPICE_ALIGN(stride, 4);
+
+ if (!top_down) {
+ stride = -stride;
+ }
+
+ surface = surface_create_stride(
+#ifdef WIN32
+ canvas_data->dc,
+#endif
+ pixman_format, width, height, stride);
+ canvas_data->out_surface = surface;
+ return surface;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_CANVAS_UTILS
+#define _H_CANVAS_UTILS
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <spice/types.h>
+#include <spice/macros.h>
+
+#include "pixman_utils.h"
+#include "lz.h"
+
+SPICE_BEGIN_DECLS
+
+typedef struct PixmanData {
+#ifdef WIN32
+ HBITMAP bitmap;
+ HANDLE mutex;
+#endif
+ uint8_t *data;
+ pixman_format_code_t format;
+} PixmanData;
+
+void spice_pixman_image_set_format(pixman_image_t *image,
+ pixman_format_code_t format);
+int spice_pixman_image_get_format(pixman_image_t *image, pixman_format_code_t *format);
+
+
+#ifdef WIN32
+pixman_image_t *surface_create(HDC dc, pixman_format_code_t format,
+ int width, int height, int top_down);
+#else
+pixman_image_t *surface_create(pixman_format_code_t format, int width, int height, int top_down);
+#endif
+
+#ifdef WIN32
+pixman_image_t *surface_create_stride(HDC dc, pixman_format_code_t format, int width, int height,
+ int stride);
+#else
+pixman_image_t *surface_create_stride(pixman_format_code_t format, int width, int height,
+ int stride);
+#endif
+
+
+typedef struct LzDecodeUsrData {
+#ifdef WIN32
+ HDC dc;
+#endif
+ pixman_image_t *out_surface;
+} LzDecodeUsrData;
+
+
+pixman_image_t *alloc_lz_image_surface(LzDecodeUsrData *canvas_data,
+ pixman_format_code_t pixman_format, int width,
+ int height, int gross_pixels, int top_down);
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef _H_DEMARSHAL
+#define _H_DEMARSHAL
+
+#include <stddef.h>
+#include <spice/macros.h>
+
+SPICE_BEGIN_DECLS
+
+typedef void (*message_destructor_t)(uint8_t *message);
+typedef uint8_t * (*spice_parse_channel_func_t)(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, int minor,
+ size_t *size_out, message_destructor_t *free_message);
+
+spice_parse_channel_func_t spice_get_server_channel_parser(uint32_t channel, unsigned int *max_message_type);
+spice_parse_channel_func_t spice_get_server_channel_parser1(uint32_t channel, unsigned int *max_message_type);
+
+SPICE_END_DECLS
+
+#endif
+
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_MARSHALLERS
+#define _H_MARSHALLERS
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <spice/protocol.h>
+
+#include "common/generated_client_marshallers.h"
+#include "marshaller.h"
+#include "messages.h"
+
+SPICE_BEGIN_DECLS
+
+SpiceMessageMarshallers *spice_message_marshallers_get(void);
+SpiceMessageMarshallers *spice_message_marshallers_get1(void);
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef _H_SPICE_DRAW
+#define _H_SPICE_DRAW
+
+#include <spice/macros.h>
+#include <spice/types.h>
+#include <spice/enums.h>
+#include "mem.h"
+
+SPICE_BEGIN_DECLS
+
+#define SPICE_GET_ADDRESS(addr) ((void *)(uintptr_t)(addr))
+#define SPICE_SET_ADDRESS(addr, val) ((addr) = (uintptr_t)(val))
+
+typedef int32_t SPICE_FIXED28_4;
+
+typedef struct SpicePointFix {
+ SPICE_FIXED28_4 x;
+ SPICE_FIXED28_4 y;
+} SpicePointFix;
+
+typedef struct SpicePoint {
+ int32_t x;
+ int32_t y;
+} SpicePoint;
+
+typedef struct SpicePoint16 {
+ int16_t x;
+ int16_t y;
+} SpicePoint16;
+
+typedef struct SpiceRect {
+ int32_t left;
+ int32_t top;
+ int32_t right;
+ int32_t bottom;
+} SpiceRect;
+
+typedef struct SpicePathSeg {
+ uint32_t flags;
+ uint32_t count;
+ SpicePointFix points[0];
+} SpicePathSeg;
+
+typedef struct SpicePath {
+ uint32_t num_segments;
+ SpicePathSeg *segments[0];
+} SpicePath;
+
+typedef struct SpiceClipRects {
+ uint32_t num_rects;
+ SpiceRect rects[0];
+} SpiceClipRects;
+
+typedef struct SpiceClip {
+ uint8_t type;
+ SpiceClipRects *rects;
+} SpiceClip;
+
+typedef struct SpicePalette {
+ uint64_t unique;
+ uint16_t num_ents;
+ uint32_t ents[0];
+} SpicePalette;
+
+#define SPICE_SURFACE_FMT_DEPTH(_d) ((_d) & 0x3f)
+
+typedef struct SpiceImageDescriptor {
+ uint64_t id;
+ uint8_t type;
+ uint8_t flags;
+ uint32_t width;
+ uint32_t height;
+} SpiceImageDescriptor;
+
+typedef struct SpiceBitmap {
+ uint8_t format;
+ uint8_t flags;
+ uint32_t x;
+ uint32_t y;
+ uint32_t stride;
+ SpicePalette *palette;
+ uint64_t palette_id;
+ SpiceChunks *data;
+} SpiceBitmap;
+
+typedef struct SpiceSurface {
+ uint32_t surface_id;
+} SpiceSurface;
+
+typedef struct SpiceQUICData {
+ uint32_t data_size;
+ SpiceChunks *data;
+} SpiceQUICData, SpiceLZRGBData, SpiceJPEGData, SpiceLZ4Data;
+
+typedef struct SpiceLZPLTData {
+ uint8_t flags;
+ uint32_t data_size;
+ SpicePalette *palette;
+ uint64_t palette_id;
+ SpiceChunks *data;
+} SpiceLZPLTData;
+
+typedef struct SpiceZlibGlzRGBData {
+ uint32_t glz_data_size;
+ uint32_t data_size;
+ SpiceChunks *data;
+} SpiceZlibGlzRGBData;
+
+typedef struct SpiceJPEGAlphaData {
+ uint8_t flags;
+ uint32_t jpeg_size;
+ uint32_t data_size;
+ SpiceChunks *data;
+} SpiceJPEGAlphaData;
+
+
+typedef struct SpiceImage {
+ SpiceImageDescriptor descriptor;
+ union {
+ SpiceBitmap bitmap;
+ SpiceQUICData quic;
+ SpiceSurface surface;
+ SpiceLZRGBData lz_rgb;
+ SpiceLZPLTData lz_plt;
+ SpiceJPEGData jpeg;
+ SpiceLZ4Data lz4;
+ SpiceZlibGlzRGBData zlib_glz;
+ SpiceJPEGAlphaData jpeg_alpha;
+ } u;
+} SpiceImage;
+
+typedef struct SpicePattern {
+ SpiceImage *pat;
+ SpicePoint pos;
+} SpicePattern;
+
+typedef struct SpiceBrush {
+ uint32_t type;
+ union {
+ uint32_t color;
+ SpicePattern pattern;
+ } u;
+} SpiceBrush;
+
+typedef struct SpiceQMask {
+ uint8_t flags;
+ SpicePoint pos;
+ SpiceImage *bitmap;
+} SpiceQMask;
+
+typedef struct SpiceFill {
+ SpiceBrush brush;
+ uint16_t rop_descriptor;
+ SpiceQMask mask;
+} SpiceFill;
+
+typedef struct SpiceOpaque {
+ SpiceImage *src_bitmap;
+ SpiceRect src_area;
+ SpiceBrush brush;
+ uint16_t rop_descriptor;
+ uint8_t scale_mode;
+ SpiceQMask mask;
+} SpiceOpaque;
+
+typedef struct SpiceCopy {
+ SpiceImage *src_bitmap;
+ SpiceRect src_area;
+ uint16_t rop_descriptor;
+ uint8_t scale_mode;
+ SpiceQMask mask;
+} SpiceCopy, SpiceBlend;
+
+typedef struct SpiceTransparent {
+ SpiceImage *src_bitmap;
+ SpiceRect src_area;
+ uint32_t src_color;
+ uint32_t true_color;
+} SpiceTransparent;
+
+typedef struct SpiceAlphaBlend {
+ uint16_t alpha_flags;
+ uint8_t alpha;
+ SpiceImage *src_bitmap;
+ SpiceRect src_area;
+} SpiceAlphaBlend;
+
+typedef struct SpiceRop3 {
+ SpiceImage *src_bitmap;
+ SpiceRect src_area;
+ SpiceBrush brush;
+ uint8_t rop3;
+ uint8_t scale_mode;
+ SpiceQMask mask;
+} SpiceRop3;
+
+/* Given in 16.16 fixed point */
+typedef struct SpiceTransform {
+ uint32_t t00;
+ uint32_t t01;
+ uint32_t t02;
+ uint32_t t10;
+ uint32_t t11;
+ uint32_t t12;
+} SpiceTransform;
+
+typedef struct SpiceComposite {
+ uint32_t flags;
+ SpiceImage *src_bitmap;
+ SpiceImage *mask_bitmap;
+ SpiceTransform src_transform;
+ SpiceTransform mask_transform;
+ SpicePoint16 src_origin;
+ SpicePoint16 mask_origin;
+} SpiceComposite;
+
+typedef struct SpiceBlackness {
+ SpiceQMask mask;
+} SpiceBlackness, SpiceInvers, SpiceWhiteness;
+
+typedef struct SpiceLineAttr {
+ uint8_t flags;
+ uint8_t style_nseg;
+ SPICE_FIXED28_4 *style;
+} SpiceLineAttr;
+
+typedef struct SpiceStroke {
+ SpicePath *path;
+ SpiceLineAttr attr;
+ SpiceBrush brush;
+ uint16_t fore_mode;
+ uint16_t back_mode;
+} SpiceStroke;
+
+typedef struct SpiceRasterGlyph {
+ SpicePoint render_pos;
+ SpicePoint glyph_origin;
+ uint16_t width;
+ uint16_t height;
+ uint8_t data[0];
+} SpiceRasterGlyph;
+
+typedef struct SpiceString {
+ uint16_t length;
+ uint16_t flags;
+ SpiceRasterGlyph *glyphs[0];
+} SpiceString;
+
+typedef struct SpiceText {
+ SpiceString *str;
+ SpiceRect back_area;
+ SpiceBrush fore_brush;
+ SpiceBrush back_brush;
+ uint16_t fore_mode;
+ uint16_t back_mode;
+} SpiceText;
+
+typedef struct SpiceCursorHeader {
+ uint64_t unique;
+ uint16_t type;
+ uint16_t width;
+ uint16_t height;
+ uint16_t hot_spot_x;
+ uint16_t hot_spot_y;
+} SpiceCursorHeader;
+
+static inline int spice_image_descriptor_is_lossy(const SpiceImageDescriptor *descriptor)
+{
+ return descriptor->type == SPICE_IMAGE_TYPE_JPEG ||
+ descriptor->type == SPICE_IMAGE_TYPE_JPEG_ALPHA;
+}
+
+SPICE_END_DECLS
+
+#endif /* _H_SPICE_DRAW */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+#ifdef __MINGW32__
+#undef HAVE_STDLIB_H
+#endif
+#include <config.h>
+#endif
+
+#include <windows.h>
+#include <wingdi.h>
+#include "gdi_canvas.h"
+#define GDI_CANVAS
+#include "canvas_base.c"
+#include "rop3.h"
+#include "rect.h"
+#include "region.h"
+#include "threads.h"
+
+typedef struct GdiCanvas GdiCanvas;
+
+struct GdiCanvas {
+ CanvasBase base;
+ HDC dc;
+ RecurciveMutex* lock;
+};
+
+
+struct BitmapData {
+ HBITMAP hbitmap;
+ HBITMAP prev_hbitmap;
+ SpicePoint pos;
+ uint8_t flags;
+ HDC dc;
+ int cache;
+ int from_surface;
+};
+
+#define _rop3_brush 0xf0
+#define _rop3_src 0xcc
+#define _rop3_dest 0xaa
+
+uint32_t raster_ops[] = {
+ 0x00000042,
+ 0x00010289,
+ 0x00020C89,
+ 0x000300AA,
+ 0x00040C88,
+ 0x000500A9,
+ 0x00060865,
+ 0x000702C5,
+ 0x00080F08,
+ 0x00090245,
+ 0x000A0329,
+ 0x000B0B2A,
+ 0x000C0324,
+ 0x000D0B25,
+ 0x000E08A5,
+ 0x000F0001,
+ 0x00100C85,
+ 0x001100A6,
+ 0x00120868,
+ 0x001302C8,
+ 0x00140869,
+ 0x001502C9,
+ 0x00165CCA,
+ 0x00171D54,
+ 0x00180D59,
+ 0x00191CC8,
+ 0x001A06C5,
+ 0x001B0768,
+ 0x001C06CA,
+ 0x001D0766,
+ 0x001E01A5,
+ 0x001F0385,
+ 0x00200F09,
+ 0x00210248,
+ 0x00220326,
+ 0x00230B24,
+ 0x00240D55,
+ 0x00251CC5,
+ 0x002606C8,
+ 0x00271868,
+ 0x00280369,
+ 0x002916CA,
+ 0x002A0CC9,
+ 0x002B1D58,
+ 0x002C0784,
+ 0x002D060A,
+ 0x002E064A,
+ 0x002F0E2A,
+ 0x0030032A,
+ 0x00310B28,
+ 0x00320688,
+ 0x00330008,
+ 0x003406C4,
+ 0x00351864,
+ 0x003601A8,
+ 0x00370388,
+ 0x0038078A, // PSDPoax
+ 0x00390604, // SPDnox
+ 0x003A0644, // SPDSxox
+ 0x003B0E24, // SPDnoan
+ 0x003C004A, // PSx
+ 0x003D18A4, // SPDSonox
+ 0x003E1B24, // SPDSnaox
+ 0x003F00EA, // PSan
+ 0x00400F0A, // PSDnaa
+ 0x00410249, // DPSxon
+ 0x00420D5D, // SDxPDxa
+ 0x00431CC4, // SPDSanaxn
+ 0x00440328, // SDna SRCERASE
+ 0x00450B29, // DPSnaon
+ 0x004606C6, // DSPDaox
+ 0x0047076A, // PSDPxaxn
+ 0x00480368, // SDPxa
+ 0x004916C5, // PDSPDaoxxn
+ 0x004A0789, // DPSDoax
+ 0x004B0605, // PDSnox
+ 0x004C0CC8, // SDPana
+ 0x004D1954, // SSPxDSxoxn
+ 0x004E0645, // PDSPxox
+ 0x004F0E25, // PDSnoan
+ 0x00500325, // PDna
+ 0x00510B26, // DSPnaon
+ 0x005206C9, // DPSDaox
+ 0x00530764, // SPDSxaxn
+ 0x005408A9, // DPSonon
+ 0x00550009, // Dn DSTINVERT
+ 0x005601A9, // DPSox
+ 0x00570389, // DPSoan
+ 0x00580785, // PDSPoax
+ 0x00590609, // DPSnox
+ 0x005A0049, // DPx PATINVERT
+ 0x005B18A9, // DPSDonox
+ 0x005C0649, // DPSDxox
+ 0x005D0E29, // DPSnoan
+ 0x005E1B29, // DPSDnaox
+ 0x005F00E9, // DPan
+ 0x00600365, // PDSxa
+ 0x006116C6, // DSPDSaoxxn
+ 0x00620786, // DSPDoax
+ 0x00630608, // SDPnox
+ 0x00640788, // SDPSoax
+ 0x00650606, // DSPnox
+ 0x00660046, // DSx SRCINVERT
+ 0x006718A8, // SDPSonox
+ 0x006858A6, // DSPDSonoxxn
+ 0x00690145, // PDSxxn
+ 0x006A01E9, // DPSax
+ 0x006B178A, // PSDPSoaxxn
+ 0x006C01E8, // SDPax
+ 0x006D1785, // PDSPDoaxxn
+ 0x006E1E28, // SDPSnoax
+ 0x006F0C65, // PDSxnan
+ 0x00700CC5, // PDSana
+ 0x00711D5C, // SSDxPDxaxn
+ 0x00720648, // SDPSxox
+ 0x00730E28, // SDPnoan
+ 0x00740646, // DSPDxox
+ 0x00750E26, // DSPnoan
+ 0x00761B28, // SDPSnaox
+ 0x007700E6, // DSan
+ 0x007801E5, // PDSax
+ 0x00791786, // DSPDSoaxxn
+ 0x007A1E29, // DPSDnoax
+ 0x007B0C68, // SDPxnan
+ 0x007C1E24, // SPDSnoax
+ 0x007D0C69, // DPSxnan
+ 0x007E0955, // SPxDSxo
+ 0x007F03C9, // DPSaan
+ 0x008003E9, // DPSaa
+ 0x00810975, // SPxDSxon
+ 0x00820C49, // DPSxna
+ 0x00831E04, // SPDSnoaxn
+ 0x00840C48, // SDPxna
+ 0x00851E05, // PDSPnoaxn
+ 0x008617A6, // DSPDSoaxx
+ 0x008701C5, // PDSaxn
+ 0x008800C6, // DSa SRCAND
+ 0x00891B08, // SDPSnaoxn
+ 0x008A0E06, // DSPnoa
+ 0x008B0666, // DSPDxoxn
+ 0x008C0E08, // SDPnoa
+ 0x008D0668, // SDPSxoxn
+ 0x008E1D7C, // SSDxPDxax
+ 0x008F0CE5, // PDSanan
+ 0x00900C45, // PDSxna
+ 0x00911E08, // SDPSnoaxn
+ 0x009217A9, // DPSDPoaxx
+ 0x009301C4, // SPDaxn
+ 0x009417AA, // PSDPSoaxx
+ 0x009501C9, // DPSaxn
+ 0x00960169, // DPSxx
+ 0x0097588A, // PSDPSonoxx
+ 0x00981888, // SDPSonoxn
+ 0x00990066, // DSxn
+ 0x009A0709, // DPSnax
+ 0x009B07A8, // SDPSoaxn
+ 0x009C0704, // SPDnax
+ 0x009D07A6, // DSPDoaxn
+ 0x009E16E6, // DSPDSaoxx
+ 0x009F0345, // PDSxan
+ 0x00A000C9, // DPa
+ 0x00A11B05, // PDSPnaoxn
+ 0x00A20E09, // DPSnoa
+ 0x00A30669, // DPSDxoxn
+ 0x00A41885, // PDSPonoxn
+ 0x00A50065, // PDxn
+ 0x00A60706, // DSPnax
+ 0x00A707A5, // PDSPoaxn
+ 0x00A803A9, // DPSoa
+ 0x00A90189, // DPSoxn
+ 0x00AA0029, // D
+ 0x00AB0889, // DPSono
+ 0x00AC0744, // SPDSxax
+ 0x00AD06E9, // DPSDaoxn
+ 0x00AE0B06, // DSPnao
+ 0x00AF0229, // DPno
+ 0x00B00E05, // PDSnoa
+ 0x00B10665, // PDSPxoxn
+ 0x00B21974, // SSPxDSxox
+ 0x00B30CE8, // SDPanan
+ 0x00B4070A, // PSDnax
+ 0x00B507A9, // DPSDoaxn
+ 0x00B616E9, // DPSDPaoxx
+ 0x00B70348, // SDPxan
+ 0x00B8074A, // PSDPxax
+ 0x00B906E6, // DSPDaoxn
+ 0x00BA0B09, // DPSnao
+ 0x00BB0226, // DSno MERGEPAINT
+ 0x00BC1CE4, // SPDSanax
+ 0x00BD0D7D, // SDxPDxan
+ 0x00BE0269, // DPSxo
+ 0x00BF08C9, // DPSano
+ 0x00C000CA, // PSa MERGECOPY
+ 0x00C11B04, // SPDSnaoxn
+ 0x00C21884, // SPDSonoxn
+ 0x00C3006A, // PSxn
+ 0x00C40E04, // SPDnoa
+ 0x00C50664, // SPDSxoxn
+ 0x00C60708, // SDPnax
+ 0x00C707AA, // PSDPoaxn
+ 0x00C803A8, // SDPoa
+ 0x00C90184, // SPDoxn
+ 0x00CA0749, // DPSDxax
+ 0x00CB06E4, // SPDSaoxn
+ 0x00CC0020, // S SRCCOPY
+ 0x00CD0888, // SDPono
+ 0x00CE0B08, // SDPnao
+ 0x00CF0224, // SPno
+ 0x00D00E0A, // PSDnoa
+ 0x00D1066A, // PSDPxoxn
+ 0x00D20705, // PDSnax
+ 0x00D307A4, // SPDSoaxn
+ 0x00D41D78, // SSPxPDxax
+ 0x00D50CE9, // DPSanan
+ 0x00D616EA, // PSDPSaoxx
+ 0x00D70349, // DPSxan
+ 0x00D80745, // PDSPxax
+ 0x00D906E8, // SDPSaoxn
+ 0x00DA1CE9, // DPSDanax
+ 0x00DB0D75, // SPxDSxan
+ 0x00DC0B04, // SPDnao
+ 0x00DD0228, // SDno
+ 0x00DE0268, // SDPxo
+ 0x00DF08C8, // SDPano
+ 0x00E003A5, // PDSoa
+ 0x00E10185, // PDSoxn
+ 0x00E20746, // DSPDxax
+ 0x00E306EA, // PSDPaoxn
+ 0x00E40748, // SDPSxax
+ 0x00E506E5, // PDSPaoxn
+ 0x00E61CE8, // SDPSanax
+ 0x00E70D79, // SPxPDxan
+ 0x00E81D74, // SSPxDSxax
+ 0x00E95CE6, // DSPDSanaxxn
+ 0x00EA02E9, // DPSao
+ 0x00EB0849, // DPSxno
+ 0x00EC02E8, // SDPao
+ 0x00ED0848, // SDPxno
+ 0x00EE0086, // DSo SRCPAINT
+ 0x00EF0A08, // SDPnoo
+ 0x00F00021, // P PATCOPY
+ 0x00F10885, // PDSono
+ 0x00F20B05, // PDSnao
+ 0x00F3022A, // PSno
+ 0x00F40B0A, // PSDnao
+ 0x00F50225, // PDno
+ 0x00F60265, // PDSxo
+ 0x00F708C5, // PDSano
+ 0x00F802E5, // PDSao
+ 0x00F90845, // PDSxno
+ 0x00FA0089, // DPo
+ 0x00FB0A09, // DPSnoo PATPAINT
+ 0x00FC008A, // PSo
+ 0x00FD0A0A, // PSDnoo
+ 0x00FE02A9, // DPSoo
+ 0x00FF0062 // 1 WHITENESS
+};
+
+static void set_path(GdiCanvas *canvas, SpicePath *s)
+{
+ unsigned int i;
+
+ for (i = 0; i < s->num_segments; i++) {
+ SpicePathSeg* seg = s->segments[i];
+ SpicePointFix* point = seg->points;
+ SpicePointFix* end_point = point + seg->count;
+
+ if (seg->flags & SPICE_PATH_BEGIN) {
+ BeginPath(canvas->dc);
+ if (!MoveToEx(canvas->dc, (int)fix_to_double(point->x), (int)fix_to_double(point->y),
+ NULL)) {
+ spice_critical("MoveToEx failed");
+ return;
+ }
+ point++;
+ }
+
+ if (seg->flags & SPICE_PATH_BEZIER) {
+ spice_return_if_fail((point - end_point) % 3 == 0);
+ for (; point + 2 < end_point; point += 3) {
+ POINT points[3];
+
+ points[0].x = (int)fix_to_double(point[0].x);
+ points[0].y = (int)fix_to_double(point[0].y);
+ points[1].x = (int)fix_to_double(point[1].x);
+ points[1].y = (int)fix_to_double(point[1].y);
+ points[2].x = (int)fix_to_double(point[2].x);
+ points[2].y = (int)fix_to_double(point[2].y);
+ if (!PolyBezierTo(canvas->dc, points, 3)) {
+ spice_critical("PolyBezierTo failed");
+ return;
+ }
+ }
+ } else {
+ for (; point < end_point; point++) {
+ if (!LineTo(canvas->dc, (int)fix_to_double(point->x),
+ (int)fix_to_double(point->y))) {
+ spice_critical("LineTo failed");
+ }
+ }
+ }
+
+ if (seg->flags & SPICE_PATH_END) {
+
+ if (seg->flags & SPICE_PATH_CLOSE) {
+ if (!CloseFigure(canvas->dc)) {
+ spice_critical("CloseFigure failed");
+ }
+ }
+
+ if (!EndPath(canvas->dc)) {
+ spice_critical("EndPath failed");
+ }
+ }
+
+ }
+}
+
+static void set_scale_mode(GdiCanvas *canvas, uint8_t scale_mode)
+{
+ if (scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE) {
+ SetStretchBltMode(canvas->dc, HALFTONE);
+ } else if (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) {
+ SetStretchBltMode(canvas->dc, COLORONCOLOR);
+ } else {
+ spice_critical("Unknown ScaleMode");
+ }
+}
+
+static void set_clip(GdiCanvas *canvas, SpiceClip *clip)
+{
+ switch (clip->type) {
+ case SPICE_CLIP_TYPE_NONE:
+ if (SelectClipRgn(canvas->dc, NULL) == ERROR) {
+ spice_critical("SelectClipRgn failed");
+ }
+ break;
+ case SPICE_CLIP_TYPE_RECTS: {
+ uint32_t n = clip->rects->num_rects;
+
+ SpiceRect *now = clip->rects->rects;
+ SpiceRect *end = now + n;
+
+ if (now < end) {
+ HRGN main_hrgn;
+
+ main_hrgn = CreateRectRgn(now->left, now->top, now->right, now->bottom);
+ if (!main_hrgn) {
+ return;
+ }
+ now++;
+ for (; now < end; now++) {
+ HRGN combaine_hrgn;
+ combaine_hrgn = CreateRectRgn(now->left, now->top, now->right,
+ now->bottom);
+ if (!combaine_hrgn) {
+ spice_critical("Unable to CreateRectRgn");
+ DeleteObject(main_hrgn);
+ return;
+ }
+ if (CombineRgn(main_hrgn, main_hrgn, combaine_hrgn, RGN_OR) == ERROR) {
+ spice_critical("Unable to CombineRgn");
+ DeleteObject(combaine_hrgn);
+ return;
+ }
+ DeleteObject(combaine_hrgn);
+ }
+ if (SelectClipRgn(canvas->dc, main_hrgn) == ERROR) {
+ spice_critical("Unable to SelectClipRgn");
+ }
+ DeleteObject(main_hrgn);
+ }
+ break;
+ }
+ default:
+ spice_warn_if_reached();
+ return;
+ }
+}
+
+static void copy_bitmap(const uint8_t *src_image, int height, int src_stride,
+ uint8_t *dest_bitmap, int dest_stride)
+{
+ int copy_width = MIN(dest_stride, src_stride);
+ int y = 0;
+
+ spice_return_if_fail(dest_stride >= 0 && src_stride >= 0);
+
+ while (y < height) {
+ memcpy(dest_bitmap, src_image, copy_width);
+ src_image += src_stride;
+ dest_bitmap += dest_stride;
+ y++;
+ }
+}
+
+static void copy_bitmap_alpha(const uint8_t *src_alpha, int height, int width, int src_stride,
+ uint8_t *dest_bitmap, int dest_stride, int alpha_bits_size)
+{
+ int y = 0;
+ uint8_t i_offset;
+ int i_count = 0;
+ int i = 0;
+
+ if (alpha_bits_size == 1) {
+ i_offset = 1;
+ } else {
+ i_offset = 8;
+ }
+
+
+ while (y < height) {
+ int x;
+
+ for (x = 0; x < width; ++x) {
+ uint8_t alphaval;
+ double alpha;
+
+ alphaval = src_alpha[i];
+ alphaval = alphaval >> (i_count * i_offset);
+ alphaval &= ((uint8_t)0xff >> (8 - i_offset));
+ alphaval = ((255 * alphaval) / ((uint8_t)0xff >> (8 - i_offset)));
+
+ dest_bitmap[x * 4 + 3] = alphaval;
+ alpha = (double)alphaval / 0xff;
+ dest_bitmap[x * 4 + 2] = (uint8_t)(alpha * dest_bitmap[x * 4 + 2]);
+ dest_bitmap[x * 4 + 1] = (uint8_t)(alpha * dest_bitmap[x * 4 + 1]);
+ dest_bitmap[x * 4] = (uint8_t)(alpha * dest_bitmap[x * 4]);
+
+ i_count++;
+ if (i_count == (8 / i_offset)) {
+ i++;
+ i_count = 0;
+ }
+ }
+
+ dest_bitmap += width * 4;
+ i = 0;
+ src_alpha += src_stride;
+ i_count = 0;
+ y++;
+ }
+}
+
+static uint8_t *create_bitmap(HBITMAP *bitmap, HBITMAP *prev_bitmap, HDC *dc,
+ const uint8_t *bitmap_data, int width, int height,
+ int stride, int bits, int rotate)
+{
+ uint8_t *data;
+ const uint8_t *src_data;
+ uint32_t nstride;
+ struct {
+ BITMAPINFO inf;
+ RGBQUAD palette[255];
+ } bitmap_info;
+
+ memset(&bitmap_info, 0, sizeof(bitmap_info));
+ bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader);
+ bitmap_info.inf.bmiHeader.biWidth = width;
+ if (stride < 0) {
+ bitmap_info.inf.bmiHeader.biHeight = height;
+ } else {
+ bitmap_info.inf.bmiHeader.biHeight = -height;
+ }
+
+ if (rotate) {
+ bitmap_info.inf.bmiHeader.biHeight = -bitmap_info.inf.bmiHeader.biHeight;
+ }
+
+ bitmap_info.inf.bmiHeader.biPlanes = 1;
+ bitmap_info.inf.bmiHeader.biBitCount = bits;
+ bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
+
+ *dc = create_compatible_dc();
+ if (!*dc) {
+ spice_critical("create_compatible_dc() failed");
+ return NULL;
+ }
+
+ *bitmap = CreateDIBSection(*dc, &bitmap_info.inf, 0, (VOID **)&data, NULL, 0);
+ if (!*bitmap) {
+ spice_critical("Unable to CreateDIBSection");
+ DeleteDC(*dc);
+ return NULL;
+ }
+ *prev_bitmap = (HBITMAP)SelectObject(*dc, *bitmap);
+
+ if (stride < 0) {
+ src_data = bitmap_data - (height - 1) * -stride;
+ } else {
+ src_data = bitmap_data;
+ }
+
+ switch (bits) {
+ case 1:
+ nstride = SPICE_ALIGN(width, 32) / 8;
+ break;
+ case 8:
+ nstride = SPICE_ALIGN(width, 4);
+ break;
+ case 16:
+ nstride = SPICE_ALIGN(width * 2, 4);
+ break;
+ case 32:
+ nstride = width * 4;
+ break;
+ default:
+ spice_warn_if_reached();
+ return NULL;
+ }
+
+ if (bitmap_data) {
+ if (stride < 0) {
+ copy_bitmap(src_data, height, -stride, data, nstride);
+ } else {
+ copy_bitmap(src_data, height, stride, data, nstride);
+ }
+ }
+
+ return data;
+}
+
+static uint8_t *create_bitmap_from_pixman(HBITMAP *bitmap, HBITMAP *prev_bitmap, HDC *dc,
+ pixman_image_t *surface, int rotate)
+{
+ return create_bitmap(bitmap, prev_bitmap, dc,
+ (uint8_t*)pixman_image_get_data(surface),
+ pixman_image_get_width(surface),
+ pixman_image_get_height(surface),
+ pixman_image_get_stride(surface),
+ spice_pixman_image_get_bpp(surface),
+ rotate);
+}
+
+
+static void release_bitmap(HDC dc, HBITMAP bitmap, HBITMAP prev_bitmap, int cache)
+{
+ bitmap = (HBITMAP)SelectObject(dc, prev_bitmap);
+ if (!cache) {
+ DeleteObject(bitmap);
+ }
+ DeleteDC(dc);
+}
+
+static inline uint8_t get_converted_color(uint8_t color)
+{
+ uint8_t msb;
+
+ msb = color & 0xE0;
+ msb = msb >> 5;
+ color |= msb;
+ return color;
+}
+
+static inline COLORREF get_color_ref(GdiCanvas *canvas, uint32_t color)
+{
+ int shift = canvas->base.color_shift == 8 ? 0 : 3;
+ uint8_t r, g, b;
+
+ b = (color & canvas->base.color_mask);
+ color >>= canvas->base.color_shift;
+ g = (color & canvas->base.color_mask);
+ color >>= canvas->base.color_shift;
+ r = (color & canvas->base.color_mask);
+ if (shift) {
+ r = get_converted_color(r << shift);
+ g = get_converted_color(g << shift);
+ b = get_converted_color(b << shift);
+ }
+ return RGB(r, g, b);
+}
+
+static HBRUSH get_brush(GdiCanvas *canvas, SpiceBrush *brush, RecurciveMutex **brush_lock)
+{
+ HBRUSH hbrush;
+
+ *brush_lock = NULL;
+
+ switch (brush->type) {
+ case SPICE_BRUSH_TYPE_SOLID:
+ if (!(hbrush = CreateSolidBrush(get_color_ref(canvas, brush->u.color)))) {
+ spice_critical("CreateSolidBrush failed");
+ return NULL;
+ }
+ return hbrush;
+ case SPICE_BRUSH_TYPE_PATTERN: {
+ GdiCanvas *gdi_surface = NULL;
+ HBRUSH hbrush;
+ pixman_image_t *surface = NULL;
+ HDC dc;
+ HBITMAP bitmap;
+ HBITMAP prev_bitmap;
+
+ gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, brush->u.pattern.pat);
+ if (gdi_surface) {
+ bitmap = (HBITMAP)GetCurrentObject(gdi_surface->dc, OBJ_BITMAP);
+ if (!bitmap) {
+ spice_critical("GetCurrentObject failed");
+ return NULL;
+ }
+ *brush_lock = gdi_surface->lock;
+ } else {
+ surface = canvas_get_image(&canvas->base, brush->u.pattern.pat, FALSE);
+ if (!create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, surface, 0)) {
+ spice_critical("create_bitmap failed");
+ return NULL;
+ }
+ }
+
+ if (!(hbrush = CreatePatternBrush(bitmap))) {
+ spice_critical("CreatePatternBrush failed");
+ return NULL;
+ }
+
+ if (!gdi_surface) {
+ release_bitmap(dc, bitmap, prev_bitmap, 0);
+ pixman_image_unref(surface);
+ }
+ return hbrush;
+ }
+ case SPICE_BRUSH_TYPE_NONE:
+ return NULL;
+ default:
+ spice_warn_if_reached();
+ return NULL;
+ }
+}
+
+static HBRUSH set_brush(HDC dc, HBRUSH hbrush, SpiceBrush *brush)
+{
+ switch (brush->type) {
+ case SPICE_BRUSH_TYPE_SOLID: {
+ return (HBRUSH)SelectObject(dc, hbrush);
+ }
+ case SPICE_BRUSH_TYPE_PATTERN: {
+ HBRUSH prev_hbrush;
+ prev_hbrush = (HBRUSH)SelectObject(dc, hbrush);
+ if (!SetBrushOrgEx(dc, brush->u.pattern.pos.x, brush->u.pattern.pos.y, NULL)) {
+ spice_critical("SetBrushOrgEx failed");
+ return NULL;
+ }
+ return prev_hbrush;
+ }
+ default:
+ spice_warn_if_reached();
+ return NULL;
+ }
+}
+
+static void unset_brush(HDC dc, HBRUSH prev_hbrush)
+{
+ if (!prev_hbrush) {
+ return;
+ }
+ prev_hbrush = (HBRUSH)SelectObject(dc, prev_hbrush);
+ DeleteObject(prev_hbrush);
+}
+
+uint8_t calc_rop3(uint16_t rop3_bits, int brush)
+{
+ uint8_t rop3 = 0;
+ uint8_t rop3_src = _rop3_src;
+ uint8_t rop3_dest = _rop3_dest;
+ uint8_t rop3_brush = _rop3_brush;
+ uint8_t rop3_src_brush;
+
+ if (rop3_bits & SPICE_ROPD_INVERS_SRC) {
+ rop3_src = ~rop3_src;
+ }
+ if (rop3_bits & SPICE_ROPD_INVERS_BRUSH) {
+ rop3_brush = ~rop3_brush;
+ }
+ if (rop3_bits & SPICE_ROPD_INVERS_DEST) {
+ rop3_dest = ~rop3_dest;
+ }
+
+ if (brush) {
+ rop3_src_brush = rop3_brush;
+ } else {
+ rop3_src_brush = rop3_src;
+ }
+
+ if (rop3_bits & SPICE_ROPD_OP_PUT) {
+ rop3 = rop3_src_brush;
+ }
+ if (rop3_bits & SPICE_ROPD_OP_OR) {
+ rop3 = rop3_src_brush | rop3_dest;
+ }
+ if (rop3_bits & SPICE_ROPD_OP_AND) {
+ rop3 = rop3_src_brush & rop3_dest;
+ }
+ if (rop3_bits & SPICE_ROPD_OP_XOR) {
+ rop3 = rop3_src_brush ^ rop3_dest;
+ }
+ if (rop3_bits & SPICE_ROPD_INVERS_RES) {
+ rop3 = ~rop3_dest;
+ }
+
+ if (rop3_bits & SPICE_ROPD_OP_BLACKNESS || rop3_bits & SPICE_ROPD_OP_WHITENESS ||
+ rop3_bits & SPICE_ROPD_OP_INVERS) {
+ spice_warning("invalid rop3 type");
+ return 0;
+ }
+ return rop3;
+}
+
+uint8_t calc_rop3_src_brush(uint16_t rop3_bits)
+{
+ uint8_t rop3 = 0;
+ uint8_t rop3_src = _rop3_src;
+ uint8_t rop3_brush = _rop3_brush;
+
+ if (rop3_bits & SPICE_ROPD_INVERS_SRC) {
+ rop3_src = ~rop3_src;
+ }
+ if (rop3_bits & SPICE_ROPD_INVERS_BRUSH) {
+ rop3_brush = ~rop3_brush;
+ }
+
+ if (rop3_bits & SPICE_ROPD_OP_OR) {
+ rop3 = rop3_src | rop3_brush;
+ }
+ if (rop3_bits & SPICE_ROPD_OP_AND) {
+ rop3 = rop3_src & rop3_brush;
+ }
+ if (rop3_bits & SPICE_ROPD_OP_XOR) {
+ rop3 = rop3_src ^ rop3_brush;
+ }
+
+ return rop3;
+}
+
+static struct BitmapData get_mask_bitmap(struct GdiCanvas *canvas, struct SpiceQMask *mask)
+{
+ GdiCanvas *gdi_surface;
+ pixman_image_t *surface;
+ struct BitmapData bitmap;
+ PixmanData *pixman_data;
+
+ bitmap.hbitmap = NULL;
+ if (!mask->bitmap) {
+ return bitmap;
+ }
+
+ gdi_surface = (GdiCanvas *)canvas_get_surface_mask(&canvas->base, mask->bitmap);
+ if (gdi_surface) {
+ HBITMAP _bitmap;
+
+ _bitmap = (HBITMAP)GetCurrentObject(gdi_surface->dc, OBJ_BITMAP);
+ if (!_bitmap) {
+ spice_critical("GetCurrentObject failed");
+ return bitmap;
+ }
+ bitmap.dc = gdi_surface->dc;
+ bitmap.hbitmap = _bitmap;
+ bitmap.prev_hbitmap = (HBITMAP)0;
+ bitmap.cache = 0;
+ bitmap.from_surface = 1;
+ } else {
+
+ if (!(surface = canvas_get_mask(&canvas->base, mask, NULL))) {
+ return bitmap;
+ }
+
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data (surface);
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
+ bitmap.dc = create_compatible_dc();
+ bitmap.prev_hbitmap = (HBITMAP)SelectObject(bitmap.dc, pixman_data->bitmap);
+ bitmap.hbitmap = pixman_data->bitmap;
+ ReleaseMutex(pixman_data->mutex);
+ bitmap.cache = 1;
+ } else if (!create_bitmap_from_pixman(&bitmap.hbitmap, &bitmap.prev_hbitmap, &bitmap.dc,
+ surface, 0)) {
+ bitmap.hbitmap = NULL;
+ } else {
+ bitmap.cache = 0;
+ }
+
+ bitmap.from_surface = 0;
+ }
+
+ bitmap.flags = mask->flags;
+ bitmap.pos = mask->pos;
+
+ return bitmap;
+}
+
+static void gdi_draw_bitmap(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
+ HDC src_dc, struct BitmapData *bitmapmask, uint32_t rop3_val)
+{
+ uint32_t rast_oper;
+
+ rast_oper = raster_ops[rop3_val];
+
+ if (!bitmapmask || !bitmapmask->hbitmap) {
+ if ((dest->right - dest->left) == (src->right - src->left) &&
+ (dest->bottom - dest->top) == (src->bottom - src->top)) {
+ if (!BitBlt(dest_dc, dest->left, dest->top, dest->right - dest->left,
+ dest->bottom - dest->top, src_dc, src->left, src->top, rast_oper)) {
+ spice_critical("BitBlt failed");
+ return;
+ }
+ } else {
+ if (!StretchBlt(dest_dc, dest->left, dest->top, dest->right - dest->left,
+ dest->bottom - dest->top, src_dc, src->left, src->top,
+ src->right - src->left, src->bottom - src->top, rast_oper)) {
+ spice_critical("StretchBlt failed");
+ return;
+ }
+ }
+ } else {
+ rast_oper = MAKEROP4(rast_oper, raster_ops[_rop3_dest]);
+
+ if (!MaskBlt(dest_dc, dest->left, dest->top, dest->right - dest->left,
+ dest->bottom - dest->top, src_dc, src->left, src->top,
+ bitmapmask->hbitmap, bitmapmask->pos.x, bitmapmask->pos.y,
+ rast_oper)) {
+ spice_critical("MaskBlt failed");
+ return;
+ }
+ }
+}
+
+static void gdi_draw_bitmap_redrop(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
+ HDC src_dc, struct BitmapData *bitmapmask,
+ uint16_t rop, int brush)
+{
+ uint32_t rop3_val;
+
+ rop3_val = calc_rop3(rop, brush);
+ gdi_draw_bitmap(dest_dc, src, dest, src_dc, bitmapmask, rop3_val);
+}
+
+static void free_mask(struct BitmapData *bitmap)
+{
+ if (bitmap->hbitmap) {
+ if (!bitmap->from_surface) {
+ release_bitmap(bitmap->dc, bitmap->hbitmap, bitmap->prev_hbitmap, bitmap->cache);
+ }
+ }
+}
+
+static void draw_str_mask_bitmap(struct GdiCanvas *canvas,
+ SpiceString *str, int n, SpiceRect *dest,
+ SpiceRect *src, SpiceBrush *brush)
+{
+ pixman_image_t *surface;
+ struct BitmapData bitmap;
+ SpicePoint pos;
+ int dest_stride;
+ uint8_t *bitmap_data;
+ HBRUSH prev_hbrush;
+ HBRUSH hbrush;
+ RecurciveMutex *brush_lock;
+
+ bitmap.hbitmap = (HBITMAP)1;
+ if (!(surface = canvas_get_str_mask(&canvas->base, str, n, &pos))) {
+ spice_critical("unable to canvas_get_str_mask");
+ return;
+ }
+
+ bitmap.from_surface = 0;
+ bitmap.cache = 0;
+ bitmap_data = create_bitmap(&bitmap.hbitmap, &bitmap.prev_hbitmap,
+ &bitmap.dc, NULL,
+ pixman_image_get_width(surface),
+ pixman_image_get_height(surface),
+ pixman_image_get_stride(surface), 32, 0);
+
+ if (!bitmap_data) {
+ return;
+ }
+
+ bitmap.flags = 0;
+ bitmap.pos.x = 0;
+ bitmap.pos.y = 0;
+
+ dest->left = pos.x;
+ dest->top = pos.y;
+ dest->right = pos.x + pixman_image_get_width(surface);
+ dest->bottom = pos.y + pixman_image_get_height(surface);
+ src->left = 0;
+ src->top = 0;
+ src->right = pixman_image_get_width(surface);
+ src->bottom = pixman_image_get_height(surface);
+
+ dest_stride = pixman_image_get_width(surface);
+ switch (n) {
+ case 1:
+ dest_stride = dest_stride / 8;
+ break;
+ case 4:
+ dest_stride = dest_stride / 2;
+ break;
+ case 32:
+ dest_stride = dest_stride * 4;
+ break;
+ default:
+ spice_warn_if_reached();
+ return;
+ }
+ dest_stride = dest_stride + 3;
+ dest_stride = dest_stride & ~3;
+
+ hbrush = get_brush(canvas, brush, &brush_lock);
+ prev_hbrush = set_brush(bitmap.dc, hbrush, brush);
+ if (brush_lock) {
+ RecurciveLock b_lock(*brush_lock);
+ gdi_draw_bitmap(bitmap.dc, src, src, bitmap.dc, NULL, _rop3_brush);
+ } else {
+ gdi_draw_bitmap(bitmap.dc, src, src, bitmap.dc, NULL, _rop3_brush);
+ }
+
+ unset_brush(bitmap.dc, prev_hbrush);
+
+ copy_bitmap_alpha((uint8_t *)pixman_image_get_data(surface),
+ pixman_image_get_height(surface),
+ pixman_image_get_width(surface),
+ pixman_image_get_stride(surface),
+ bitmap_data, dest_stride, n);
+
+ BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
+
+ RecurciveLock lock(*canvas->lock);
+ AlphaBlend(canvas->dc, dest->left, dest->top, dest->right - dest->left,
+ dest->bottom - dest->top, bitmap.dc, src->left, src->top,
+ src->right - src->left, src->bottom - src->top, bf);
+
+ free_mask(&bitmap);
+}
+
+static void gdi_draw_image(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
+ pixman_image_t *image, struct BitmapData *bitmapmask, uint16_t rop,
+ int rotate)
+{
+ HDC dc;
+ HBITMAP bitmap;
+ HBITMAP prev_bitmap;
+
+ create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, image, rotate);
+
+ gdi_draw_bitmap_redrop(dest_dc, src, dest, dc, bitmapmask, rop, 0);
+
+ release_bitmap(dc, bitmap, prev_bitmap, 0);
+}
+
+static void gdi_draw_image_rop3(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
+ pixman_image_t *image, struct BitmapData *bitmapmask, uint8_t rop3,
+ int rotate)
+{
+ HDC dc;
+ HBITMAP bitmap;
+ HBITMAP prev_bitmap;
+
+ create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, image, rotate);
+
+ gdi_draw_bitmap(dest_dc, src, dest, dc, bitmapmask, rop3);
+
+ release_bitmap(dc, bitmap, prev_bitmap, 0);
+}
+
+static void gdi_canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceFill *fill)
+{
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ HBRUSH prev_hbrush;
+ HBRUSH brush;
+ struct BitmapData bitmapmask;
+ RecurciveMutex *brush_lock;
+
+ RecurciveLock lock(*canvas->lock);
+
+ brush = get_brush(canvas, &fill->brush, &brush_lock);
+ spice_return_if_fail(brush != NULL);
+
+ bitmapmask = get_mask_bitmap(canvas, &fill->mask);
+
+ set_clip(canvas, clip);
+ prev_hbrush = set_brush(canvas->dc, brush, &fill->brush);
+ if (brush_lock) {
+ RecurciveLock b_lock(*brush_lock);
+ gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask,
+ fill->rop_descriptor, fill->brush.type != SPICE_BRUSH_TYPE_NONE);
+ } else {
+ gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask,
+ fill->rop_descriptor, fill->brush.type != SPICE_BRUSH_TYPE_NONE);
+ }
+
+ free_mask(&bitmapmask);
+ unset_brush(canvas->dc, prev_hbrush);
+}
+
+static void gdi_canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
+{
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ GdiCanvas *gdi_surface;
+ pixman_image_t *surface;
+ struct BitmapData bitmapmask;
+ PixmanData *pixman_data;
+
+ gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, copy->src_bitmap);
+ if (gdi_surface) {
+ RecurciveLock lock(*canvas->lock);
+ RecurciveLock s_lock(*gdi_surface->lock);
+ bitmapmask = get_mask_bitmap(canvas, ©->mask);
+ set_scale_mode(canvas, copy->scale_mode);
+ set_clip(canvas, clip);
+ gdi_draw_bitmap_redrop(canvas->dc, ©->src_area, bbox, gdi_surface->dc,
+ &bitmapmask, copy->rop_descriptor, 0);
+ } else {
+ surface = canvas_get_image(&canvas->base, copy->src_bitmap, FALSE);
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
+
+ RecurciveLock lock(*canvas->lock);
+ bitmapmask = get_mask_bitmap(canvas, ©->mask);
+ set_scale_mode(canvas, copy->scale_mode);
+ set_clip(canvas, clip);
+
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
+ HDC dc;
+ HBITMAP prev_bitmap;
+
+ dc = create_compatible_dc();
+ prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
+ gdi_draw_bitmap_redrop(canvas->dc, ©->src_area, bbox, dc,
+ &bitmapmask, copy->rop_descriptor, 0);
+ SelectObject(dc, prev_bitmap);
+ DeleteObject(dc);
+ ReleaseMutex(pixman_data->mutex);
+ } else {
+ gdi_draw_image(canvas->dc, ©->src_area, bbox, surface, &bitmapmask,
+ copy->rop_descriptor, 0);
+ }
+
+ pixman_image_unref(surface);
+ }
+ free_mask(&bitmapmask);
+}
+
+static void gdi_canvas_put_image(SpiceCanvas *spice_canvas, HDC dc, const SpiceRect *dest, const uint8_t *src_data,
+ uint32_t src_width, uint32_t src_height, int src_stride,
+ const QRegion *clip)
+{
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ SpiceRect src;
+ src.top = 0;
+ src.bottom = src_height;
+ src.left = 0;
+ src.right = src_width;
+ int num_rects;
+ pixman_box32_t *rects;
+
+ RecurciveLock lock(*canvas->lock);
+ set_scale_mode(canvas, SPICE_IMAGE_SCALE_MODE_NEAREST);
+ if (clip) {
+ rects = pixman_region32_rectangles((pixman_region32_t*)clip, &num_rects);
+ if (num_rects == 0) {
+ return;
+ } else {
+ HRGN main_hrgn;
+ int i;
+
+ main_hrgn = CreateRectRgn(rects[0].x1, rects[0].y1, rects[0].x2,
+ rects[0].y2);
+ if (!main_hrgn) {
+ return;
+ }
+
+ for (i = 1; i < num_rects; i++) {
+ HRGN combaine_hrgn;
+
+ combaine_hrgn = CreateRectRgn(rects[i].x1, rects[i].y1,
+ rects[i].x2,
+ rects[i].y2);
+ if (!combaine_hrgn) {
+ spice_critical("CreateRectRgn failed");
+ DeleteObject(main_hrgn);
+ return;
+ }
+ if (!CombineRgn(main_hrgn, main_hrgn, combaine_hrgn, RGN_OR)) {
+ spice_critical("CombineRgn failed in put_image");
+ return;
+ }
+ DeleteObject(combaine_hrgn);
+ }
+ if (SelectClipRgn(canvas->dc, main_hrgn) == ERROR) {
+ spice_critical("SelectClipRgn failed in put_image");
+ DeleteObject(main_hrgn);
+ return;
+ }
+ DeleteObject(main_hrgn);
+ }
+ } else {
+ SelectClipRgn(canvas->dc, NULL);
+ }
+
+ if (dc) {
+ gdi_draw_bitmap_redrop(canvas->dc, &src, dest, dc,
+ NULL, SPICE_ROPD_OP_PUT, 0);
+ } else {
+ pixman_image_t *image = pixman_image_create_bits(PIXMAN_a8r8g8b8, src_width, src_height,
+ (uint32_t *)src_data, src_stride);
+ gdi_draw_image(canvas->dc, &src, dest, image, NULL, SPICE_ROPD_OP_PUT, 0);
+ pixman_image_unref(image);
+ }
+}
+
+static void gdi_draw_bitmap_transparent(GdiCanvas *canvas, HDC dest_dc, const SpiceRect *src,
+ const SpiceRect *dest, HDC src_dc, uint32_t color)
+{
+ TransparentBlt(dest_dc, dest->left, dest->top, dest->right - dest->left,
+ dest->bottom - dest->top, src_dc, src->left, src->top,
+ src->right - src->left, src->bottom - src->top,
+ RGB(((uint8_t*)&color)[2], ((uint8_t*)&color)[1], ((uint8_t*)&color)[0]));
+}
+
+static void gdi_draw_image_transparent(GdiCanvas *canvas, HDC dest_dc, const SpiceRect *src,
+ const SpiceRect *dest, pixman_image_t *image,
+ uint32_t color, int rotate)
+{
+ HDC dc;
+ HBITMAP bitmap;
+ HBITMAP prev_bitmap;
+
+ create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, image, rotate);
+
+ gdi_draw_bitmap_transparent(canvas, dest_dc, src, dest, dc, color);
+
+ release_bitmap(dc, bitmap, prev_bitmap, 0);
+}
+
+static void gdi_canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip,
+ SpiceTransparent* transparent)
+{
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ GdiCanvas *gdi_surface;
+ pixman_image_t *surface;
+ PixmanData *pixman_data;
+
+ gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, transparent->src_bitmap);
+ if (gdi_surface) {
+ RecurciveLock lock(*canvas->lock);
+ RecurciveLock s_lock(*gdi_surface->lock);
+ set_clip(canvas, clip);
+ gdi_draw_bitmap_transparent(canvas, canvas->dc, &transparent->src_area, bbox,
+ gdi_surface->dc, transparent->true_color);
+ } else {
+ surface = canvas_get_image(&canvas->base, transparent->src_bitmap, FALSE);
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
+ RecurciveLock lock(*canvas->lock);
+ set_clip(canvas, clip);
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
+ HDC dc;
+ HBITMAP prev_bitmap;
+
+ dc = create_compatible_dc();
+ prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
+ gdi_draw_bitmap_transparent(canvas, canvas->dc, &transparent->src_area, bbox, dc,
+ transparent->true_color);
+
+ SelectObject(dc, prev_bitmap);
+ DeleteObject(dc);
+ ReleaseMutex(pixman_data->mutex);
+ } else {
+ gdi_draw_image_transparent(canvas, canvas->dc, &transparent->src_area, bbox, surface,
+ transparent->true_color, 0);
+ }
+
+ pixman_image_unref(surface);
+ }
+}
+
+static void gdi_draw_bitmap_alpha(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
+ HDC src_dc, uint8_t alpha, int use_bitmap_alpha)
+{
+ BLENDFUNCTION bf;
+
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = alpha;
+
+ if (use_bitmap_alpha) {
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ } else {
+ bf.AlphaFormat = 0;
+ }
+
+ if (!AlphaBlend(dest_dc, dest->left, dest->top, dest->right - dest->left,
+ dest->bottom - dest->top, src_dc, src->left, src->top,
+ src->right - src->left, src->bottom - src->top, bf)) {
+ spice_critical("AlphaBlend failed");
+ return;
+ }
+}
+
+static void gdi_draw_image_alpha(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
+ pixman_image_t *image, uint8_t alpha,
+ int rotate, int use_bitmap_alpha)
+{
+ HDC dc;
+ HBITMAP bitmap;
+ HBITMAP prev_bitmap;
+
+ create_bitmap_from_pixman(&bitmap, &prev_bitmap, &dc, image, rotate);
+
+ gdi_draw_bitmap_alpha(dest_dc, src, dest, dc, alpha, use_bitmap_alpha);
+
+ release_bitmap(dc, bitmap, prev_bitmap, 0);
+}
+
+static void gdi_canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlend* alpha_blend)
+{
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ GdiCanvas *gdi_surface;
+ pixman_image_t *surface;
+ PixmanData *pixman_data;
+ int use_bitmap_alpha;
+
+ gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, alpha_blend->src_bitmap);
+ if (gdi_surface) {
+ RecurciveLock lock(*canvas->lock);
+ RecurciveLock s_lock(*gdi_surface->lock);
+ set_clip(canvas, clip);
+ use_bitmap_alpha = alpha_blend->alpha_flags & SPICE_ALPHA_FLAGS_SRC_SURFACE_HAS_ALPHA;
+ gdi_draw_bitmap_alpha(canvas->dc, &alpha_blend->src_area, bbox, gdi_surface->dc,
+ alpha_blend->alpha, use_bitmap_alpha);
+ } else {
+ surface = canvas_get_image(&canvas->base, alpha_blend->src_bitmap, TRUE);
+ use_bitmap_alpha = pixman_image_get_depth(surface) == 32;
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
+
+ RecurciveLock lock(*canvas->lock);
+ set_clip(canvas, clip);
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
+ HDC dc;
+ HBITMAP prev_bitmap;
+
+ dc = create_compatible_dc();
+ prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
+ gdi_draw_bitmap_alpha(canvas->dc, &alpha_blend->src_area, bbox, dc, alpha_blend->alpha,
+ use_bitmap_alpha);
+ SelectObject(dc, prev_bitmap);
+ DeleteObject(dc);
+ ReleaseMutex(pixman_data->mutex);
+ } else {
+ gdi_draw_image_alpha(canvas->dc, &alpha_blend->src_area, bbox, surface,
+ alpha_blend->alpha, 0, use_bitmap_alpha);
+ }
+
+ pixman_image_unref(surface);
+ }
+}
+
+static void gdi_canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
+{
+ GdiCanvas *gdi_surface;
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ pixman_image_t *surface;
+ struct BitmapData bitmapmask;
+ PixmanData *pixman_data;
+ HBRUSH prev_hbrush;
+ HBRUSH hbrush;
+ uint8_t rop3;
+ RecurciveMutex *brush_lock;
+
+ rop3 = calc_rop3_src_brush(opaque->rop_descriptor);
+
+ gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, opaque->src_bitmap);
+ if (gdi_surface) {
+ RecurciveLock lock(*canvas->lock);
+ RecurciveLock s_lock(*gdi_surface->lock);
+ bitmapmask = get_mask_bitmap(canvas, &opaque->mask);
+ hbrush = get_brush(canvas, &opaque->brush, &brush_lock);
+ set_scale_mode(canvas, opaque->scale_mode);
+ set_clip(canvas, clip);
+ prev_hbrush = set_brush(canvas->dc, hbrush, &opaque->brush);
+ if (brush_lock) {
+ RecurciveLock b_lock(*brush_lock);
+ gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, gdi_surface->dc, &bitmapmask, rop3);
+ } else {
+ gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, gdi_surface->dc, &bitmapmask, rop3);
+ }
+ unset_brush(canvas->dc, prev_hbrush);
+ } else {
+ surface = canvas_get_image(&canvas->base, opaque->src_bitmap, FALSE);
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
+
+ RecurciveLock lock(*canvas->lock);
+ bitmapmask = get_mask_bitmap(canvas, &opaque->mask);
+ hbrush = get_brush(canvas, &opaque->brush, &brush_lock);
+ set_scale_mode(canvas, opaque->scale_mode);
+ set_clip(canvas, clip);
+ prev_hbrush = set_brush(canvas->dc, hbrush, &opaque->brush);
+
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
+ HDC dc;
+ HBITMAP prev_bitmap;
+
+ dc = create_compatible_dc();
+ prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
+ if (brush_lock) {
+ RecurciveLock b_lock(*brush_lock);
+ gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, dc, &bitmapmask, rop3);
+ } else {
+ gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, dc, &bitmapmask, rop3);
+ }
+ SelectObject(dc, prev_bitmap);
+ DeleteObject(dc);
+ ReleaseMutex(pixman_data->mutex);
+ } else {
+ if (brush_lock) {
+ RecurciveLock b_lock(*brush_lock);
+ gdi_draw_image_rop3(canvas->dc, &opaque->src_area, bbox, surface, &bitmapmask, rop3, 0);
+ } else {
+ gdi_draw_image_rop3(canvas->dc, &opaque->src_area, bbox, surface, &bitmapmask, rop3, 0);
+ }
+ }
+ unset_brush(canvas->dc, prev_hbrush);
+ pixman_image_unref(surface);
+ }
+
+ free_mask(&bitmapmask);
+}
+
+static void gdi_canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
+{
+ GdiCanvas *gdi_surface;
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ pixman_image_t *surface;
+ struct BitmapData bitmapmask;
+ PixmanData *pixman_data;
+
+ gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, blend->src_bitmap);
+ if (gdi_surface) {
+ RecurciveLock lock(*canvas->lock);
+ RecurciveLock s_lock(*gdi_surface->lock);
+ bitmapmask = get_mask_bitmap(canvas, &blend->mask);
+ set_scale_mode(canvas, blend->scale_mode);
+ set_clip(canvas, clip);
+ gdi_draw_bitmap_redrop(canvas->dc, &blend->src_area, bbox, gdi_surface->dc,
+ &bitmapmask, blend->rop_descriptor, 0);
+ } else {
+ surface = canvas_get_image(&canvas->base, blend->src_bitmap, FALSE);
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
+
+ RecurciveLock lock(*canvas->lock);
+ bitmapmask = get_mask_bitmap(canvas, &blend->mask);
+ set_scale_mode(canvas, blend->scale_mode);
+ set_clip(canvas, clip);
+
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
+ HDC dc;
+ HBITMAP prev_bitmap;
+
+ dc = create_compatible_dc();
+ prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
+ gdi_draw_bitmap_redrop(canvas->dc, &blend->src_area, bbox, dc,
+ &bitmapmask, blend->rop_descriptor, 0);
+ SelectObject(dc, prev_bitmap);
+ DeleteObject(dc);
+ ReleaseMutex(pixman_data->mutex);
+ } else {
+ gdi_draw_image(canvas->dc, &blend->src_area, bbox, surface,
+ &bitmapmask, blend->rop_descriptor, 0);
+ }
+
+ pixman_image_unref(surface);
+ }
+
+ free_mask(&bitmapmask);
+}
+
+static void gdi_canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
+{
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ struct BitmapData bitmapmask;
+
+ RecurciveLock lock(*canvas->lock);
+ bitmapmask = get_mask_bitmap(canvas, &blackness->mask);
+ set_clip(canvas, clip);
+ gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, 0x0);
+
+ free_mask(&bitmapmask);
+}
+
+static void gdi_canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceInvers *invers)
+{
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ struct BitmapData bitmapmask;
+
+ RecurciveLock lock(*canvas->lock);
+ bitmapmask = get_mask_bitmap(canvas, &invers->mask);
+ set_clip(canvas, clip);
+ gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, 0x55);
+
+ free_mask(&bitmapmask);
+}
+
+static void gdi_canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceWhiteness *whiteness)
+{
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ struct BitmapData bitmapmask;
+
+ RecurciveLock lock(*canvas->lock);
+ bitmapmask = get_mask_bitmap(canvas, &whiteness->mask);
+ set_clip(canvas, clip);
+ gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, 0xff);
+
+ free_mask(&bitmapmask);
+}
+
+static void gdi_canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
+{
+ GdiCanvas *gdi_surface;
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ pixman_image_t *surface;
+ struct BitmapData bitmapmask;
+ HBRUSH prev_hbrush;
+ HBRUSH hbrush;
+ PixmanData *pixman_data;
+ RecurciveMutex *brush_lock;
+
+ gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, rop3->src_bitmap);
+ if (gdi_surface) {
+ RecurciveLock lock(*canvas->lock);
+ RecurciveLock s_lock(*gdi_surface->lock);
+ hbrush = get_brush(canvas, &rop3->brush, &brush_lock);
+ bitmapmask = get_mask_bitmap(canvas, &rop3->mask);
+ set_scale_mode(canvas, rop3->scale_mode);
+ set_clip(canvas, clip);
+ prev_hbrush = set_brush(canvas->dc, hbrush, &rop3->brush);
+ if (brush_lock) {
+ RecurciveLock b_lock(*brush_lock);
+ gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, gdi_surface->dc,
+ &bitmapmask, rop3->rop3);
+ } else {
+ gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, gdi_surface->dc,
+ &bitmapmask, rop3->rop3);
+ }
+ unset_brush(canvas->dc, prev_hbrush);
+ } else {
+ surface = canvas_get_image(&canvas->base, rop3->src_bitmap, FALSE);
+ pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
+ RecurciveLock lock(*canvas->lock);
+ hbrush = get_brush(canvas, &rop3->brush, &brush_lock);
+ bitmapmask = get_mask_bitmap(canvas, &rop3->mask);
+ set_scale_mode(canvas, rop3->scale_mode);
+ set_clip(canvas, clip);
+ prev_hbrush = set_brush(canvas->dc, hbrush, &rop3->brush);
+
+ if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
+ HDC dc;
+ HBITMAP prev_bitmap;
+
+ dc = create_compatible_dc();
+ prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
+ if (brush_lock) {
+ RecurciveLock b_lock(*brush_lock);
+ gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, dc,
+ &bitmapmask, rop3->rop3);
+ } else {
+ gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, dc,
+ &bitmapmask, rop3->rop3);
+ }
+ SelectObject(dc, prev_bitmap);
+ DeleteObject(dc);
+ ReleaseMutex(pixman_data->mutex);
+ } else {
+ if (brush_lock) {
+ RecurciveLock b_lock(*brush_lock);
+ gdi_draw_image_rop3(canvas->dc, &rop3->src_area, bbox, surface, &bitmapmask, rop3->rop3, 0);
+ } else {
+ gdi_draw_image_rop3(canvas->dc, &rop3->src_area, bbox, surface, &bitmapmask, rop3->rop3, 0);
+ }
+ }
+
+ unset_brush(canvas->dc, prev_hbrush);
+ pixman_image_unref(surface);
+ }
+
+ free_mask(&bitmapmask);
+}
+
+static void gdi_canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
+{
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ RecurciveLock lock(*canvas->lock);
+
+ set_clip(canvas, clip);
+
+ BitBlt(canvas->dc, bbox->left, bbox->top, bbox->right - bbox->left,
+ bbox->bottom - bbox->top, canvas->dc, src_pos->x, src_pos->y, SRCCOPY);
+}
+
+static void gdi_canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceText *text)
+{
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ SpiceString *str;
+ RecurciveMutex *brush_lock;
+
+ RecurciveLock lock(*canvas->lock);
+ set_clip(canvas, clip);
+ lock.unlock();
+
+ if (!rect_is_empty(&text->back_area)) {
+ HBRUSH prev_hbrush;
+ HBRUSH hbrush;
+
+ RecurciveLock lock(*canvas->lock);
+ hbrush = get_brush(canvas, &text->back_brush, &brush_lock);
+ prev_hbrush = set_brush(canvas->dc, hbrush, &text->back_brush);
+ if (brush_lock) {
+ RecurciveLock b_lock(*brush_lock);
+ gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, NULL,
+ text->back_mode, 1);
+ } else {
+ gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, NULL,
+ text->back_mode, 1);
+ }
+ unset_brush(canvas->dc, prev_hbrush);
+ }
+
+ str = (SpiceString *)SPICE_GET_ADDRESS(text->str);
+
+ if (str->flags & SPICE_STRING_FLAGS_RASTER_A1) {
+ SpiceRect dest;
+ SpiceRect src;
+
+ draw_str_mask_bitmap(canvas, str, 1, &dest, &src, &text->fore_brush);
+ } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A4) {
+ SpiceRect dest;
+ SpiceRect src;
+
+ draw_str_mask_bitmap(canvas, str, 4, &dest, &src, &text->fore_brush);
+ } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A8) {
+ spice_warning("untested path A8 glyphs, doing nothing");
+ if (0) {
+ SpiceRect dest;
+ SpiceRect src;
+
+ draw_str_mask_bitmap(canvas, str, 8, &dest, &src, &text->fore_brush);
+ }
+ } else {
+ spice_warning("untested path vector glyphs, doing nothing");
+ if (0) {
+ }
+ }
+}
+
+static uint32_t *gdi_get_userstyle(GdiCanvas *canvas, uint8_t nseg, SPICE_FIXED28_4* style, int start_is_gap)
+{
+ uint32_t *local_style;
+ int i;
+
+ spice_return_val_if_fail(nseg != 0, NULL);
+
+ local_style = spice_new(uint32_t , nseg);
+
+ if (start_is_gap) {
+ local_style[nseg - 1] = (uint32_t)fix_to_double(*style);
+ style++;
+
+ for (i = 0; i < nseg - 1; i++, style++) {
+ local_style[i] = (uint32_t)fix_to_double(*style);
+ }
+ } else {
+ for (i = 0; i < nseg; i++, style++) {
+ local_style[i] = (uint32_t)fix_to_double(*style);
+ }
+ }
+
+ return local_style;
+}
+
+static void gdi_canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceStroke *stroke)
+{
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ HPEN hpen;
+ HPEN prev_hpen;
+ LOGBRUSH logbrush;
+ uint32_t *user_style = NULL;
+ pixman_image_t *surface = NULL;
+
+ if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ surface = canvas_get_image(&canvas->base, stroke->brush.u.pattern.pat, FALSE);
+ }
+
+ RecurciveLock lock(*canvas->lock);
+ set_clip(canvas, clip);
+
+ switch (stroke->fore_mode) {
+ case SPICE_ROPD_OP_WHITENESS:
+ SetROP2(canvas->dc, R2_WHITE); //0
+ break;
+ case SPICE_ROPD_OP_BLACKNESS:
+ SetROP2(canvas->dc, R2_BLACK); //1
+ break;
+ case SPICE_ROPD_OP_INVERS:
+ SetROP2(canvas->dc, R2_NOT); //Dn
+ break;
+ case SPICE_ROPD_OP_PUT:
+ SetROP2(canvas->dc, R2_COPYPEN); //P
+ break;
+ case SPICE_ROPD_OP_OR:
+ SetROP2(canvas->dc, R2_MERGEPEN); //DPo
+ break;
+ case SPICE_ROPD_OP_XOR:
+ SetROP2(canvas->dc, R2_XORPEN); //DPx
+ break;
+ case SPICE_ROPD_OP_AND:
+ SetROP2(canvas->dc, R2_MASKPEN); //DPa
+ break;
+ case SPICE_ROPD_INVERS_BRUSH | SPICE_ROPD_OP_PUT: //Pn
+ SetROP2(canvas->dc, R2_NOTCOPYPEN);
+ break;
+ case SPICE_ROPD_OP_XOR | SPICE_ROPD_INVERS_RES:
+ SetROP2(canvas->dc, R2_NOTXORPEN); //DPxn
+ break;
+ case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_RES:
+ SetROP2(canvas->dc, R2_NOTMERGEPEN); //DPon
+ break;
+ case SPICE_ROPD_OP_AND | SPICE_ROPD_INVERS_RES:
+ SetROP2(canvas->dc, R2_NOTMASKPEN); //DPan
+ break;
+ case SPICE_ROPD_INVERS_DEST | SPICE_ROPD_OP_AND:
+ SetROP2(canvas->dc, R2_MASKPENNOT); //PDna
+ break;
+ case SPICE_ROPD_INVERS_BRUSH | SPICE_ROPD_OP_AND:
+ SetROP2(canvas->dc, R2_MASKNOTPEN); //DPna
+ break;
+ case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_BRUSH:
+ SetROP2(canvas->dc, R2_MERGENOTPEN); //DPno
+ break;
+ case SPICE_ROPD_OP_OR | SPICE_ROPD_INVERS_DEST:
+ SetROP2(canvas->dc, R2_MERGEPENNOT); //PDno
+ break;
+ default:
+ SetROP2(canvas->dc, R2_NOP); //D
+ }
+
+
+ if (stroke->brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ logbrush.lbStyle = BS_SOLID | DIB_RGB_COLORS;
+ logbrush.lbHatch = 0;
+ logbrush.lbColor = get_color_ref(canvas, stroke->brush.u.color);
+ } else if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+#if 0
+ struct {
+ BITMAPINFO inf;
+ RGBQUAD palette[255];
+ } bitmap_info;
+ GdiImage image;
+#endif
+#if 0
+ spice_return_if_fail(surface != NULL)
+ surface_to_image(surface, &image);
+
+ memset(&bitmap_info, 0, sizeof(bitmap_info));
+ bitmap_info.inf.bmiHeader.biSize = sizeof(bitmap_info.inf.bmiHeader);
+ bitmap_info.inf.bmiHeader.biWidth = image.width;
+ if (image.stride < 0) {
+ bitmap_info.inf.bmiHeader.biHeight = image.height;
+ } else {
+ bitmap_info.inf.bmiHeader.biHeight = -image.height;
+ }
+ bitmap_info.inf.bmiHeader.biPlanes = 1;
+ bitmap_info.inf.bmiHeader.biBitCount = 32;
+ bitmap_info.inf.bmiHeader.biCompression = BI_RGB;
+
+ if (image.stride < 0) {
+ logbrush.lbHatch = (LONG)GlobalAlloc(GMEM_MOVEABLE,
+ image.height * -image.stride + sizeof(BITMAPINFO));
+ if (!logbrush.lbHatch) {
+ spice_critical("GlobalAlloc failed");
+ return;
+ }
+ copy_bitmap(image.pixels - (image.height - 1) * -image.stride,
+ image.height, -image.stride,
+ (uint8_t *)logbrush.lbHatch, image.width);
+ } else {
+ logbrush.lbHatch = (LONG)GlobalAlloc(GMEM_MOVEABLE,
+ image.height * image.stride + sizeof(BITMAPINFO));
+ if (!logbrush.lbHatch) {
+ spice_critical("GlobalAlloc failed");
+ return;
+ }
+ copy_bitmap(image.pixels, image.height, image.stride,
+ (uint8_t *)logbrush.lbHatch, image.width);
+ }
+
+ memcpy((void *)logbrush.lbHatch, &bitmap_info.inf, sizeof(BITMAPINFO));
+
+ logbrush.lbStyle = BS_DIBPATTERN | DIB_RGB_COLORS;
+ logbrush.lbColor = 0;
+#endif
+ pixman_image_unref(surface);
+ }
+
+ if (stroke->attr.flags & SPICE_LINE_FLAGS_STYLED) {
+ user_style = gdi_get_userstyle(canvas, stroke->attr.style_nseg,
+ stroke->attr.style,
+ !!(stroke->attr.flags & SPICE_LINE_FLAGS_START_WITH_GAP));
+ hpen = ExtCreatePen(PS_COSMETIC | PS_USERSTYLE,
+ 1,
+ &logbrush, stroke->attr.style_nseg, (DWORD *)user_style);
+ } else {
+ hpen = ExtCreatePen(PS_COSMETIC,
+ 1,
+ &logbrush, 0, NULL);
+ }
+ prev_hpen = (HPEN)SelectObject(canvas->dc, hpen);
+
+ set_path(canvas, stroke->path);
+
+ StrokePath(canvas->dc);
+
+ SelectObject(canvas->dc, prev_hpen);
+ DeleteObject(hpen);
+
+#if 0
+ if (stroke->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ GlobalFree((HGLOBAL)logbrush.lbHatch);
+ }
+#endif
+
+ free(user_style);
+}
+
+static void gdi_canvas_clear(SpiceCanvas *spice_canvas)
+{
+}
+
+static void gdi_canvas_destroy(SpiceCanvas *spice_canvas)
+{
+ GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
+ if (!canvas) {
+ return;
+ }
+ canvas_base_destroy(&canvas->base);
+ free(canvas);
+}
+
+static int need_init = 1;
+static SpiceCanvasOps gdi_canvas_ops;
+
+SpiceCanvas *gdi_canvas_create(int width, int height,
+ HDC dc, RecurciveMutex* lock, uint32_t format
+ , SpiceImageCache *bits_cache
+#ifdef SW_CANVAS_CACHE
+ , SpicePaletteCache *palette_cache
+#endif
+ , SpiceImageSurfaces *surfaces
+ , SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
+ , SpiceZlibDecoder *zlib_decoder
+ )
+{
+ GdiCanvas *canvas;
+
+ if (need_init) {
+ return NULL;
+ }
+ canvas = spice_new0(GdiCanvas, 1);
+ canvas_base_init(&canvas->base, &gdi_canvas_ops,
+ width, height, format,
+ bits_cache,
+#ifdef SW_CANVAS_CACHE
+ palette_cache,
+#endif
+ surfaces,
+ glz_decoder,
+ jpeg_decoder,
+ zlib_decoder);
+ canvas->dc = dc;
+ canvas->lock = lock;
+ return (SpiceCanvas *)canvas;
+}
+
+void gdi_canvas_init(void) //unsafe global function
+{
+ if (!need_init) {
+ return;
+ }
+ need_init = 0;
+
+ canvas_base_init_ops(&gdi_canvas_ops);
+ gdi_canvas_ops.draw_fill = gdi_canvas_draw_fill;
+ gdi_canvas_ops.draw_copy = gdi_canvas_draw_copy;
+ gdi_canvas_ops.draw_opaque = gdi_canvas_draw_opaque;
+ gdi_canvas_ops.copy_bits = gdi_canvas_copy_bits;
+ gdi_canvas_ops.draw_text = gdi_canvas_draw_text;
+ gdi_canvas_ops.draw_stroke = gdi_canvas_draw_stroke;
+ gdi_canvas_ops.draw_rop3 = gdi_canvas_draw_rop3;
+ gdi_canvas_ops.draw_blend = gdi_canvas_draw_blend;
+ gdi_canvas_ops.draw_blackness = gdi_canvas_draw_blackness;
+ gdi_canvas_ops.draw_whiteness = gdi_canvas_draw_whiteness;
+ gdi_canvas_ops.draw_invers = gdi_canvas_draw_invers;
+ gdi_canvas_ops.draw_transparent = gdi_canvas_draw_transparent;
+ gdi_canvas_ops.draw_alpha_blend = gdi_canvas_draw_alpha_blend;
+ gdi_canvas_ops.put_image = gdi_canvas_put_image;
+ gdi_canvas_ops.clear = gdi_canvas_clear;
+ gdi_canvas_ops.destroy = gdi_canvas_destroy;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H__GDI_CANVAS
+#define _H__GDI_CANVAS
+
+#include <stdint.h>
+#include <spice/macros.h>
+
+#include "pixman_utils.h"
+#include "canvas_base.h"
+#include "region.h"
+
+SPICE_BEGIN_DECLS
+
+SpiceCanvas *gdi_canvas_create(int width, int height,
+ HDC dc, class RecurciveMutex *lock, uint32_t format,
+ SpiceImageCache *bits_cache,
+ SpicePaletteCache *palette_cache,
+ SpiceImageSurfaces *surfaces,
+ SpiceGlzDecoder *glz_decoder,
+ SpiceJpegDecoder *jpeg_decoder,
+ SpiceZlibDecoder *zlib_decoder);
+
+void gdi_canvas_init(void);
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/* this is a file autogenerated by spice_codegen.py */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "common/messages.h"
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <spice/protocol.h>
+#include <spice/macros.h>
+#include <common/mem.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable:4101)
+#endif
+
+
+
+#ifdef WORDS_BIGENDIAN
+#define read_int8(ptr) (*((int8_t *)(ptr)))
+#define write_int8(ptr, val) *(int8_t *)(ptr) = val
+#define read_uint8(ptr) (*((uint8_t *)(ptr)))
+#define write_uint8(ptr, val) *(uint8_t *)(ptr) = val
+#define read_int16(ptr) ((int16_t)SPICE_BYTESWAP16(*((uint16_t *)(ptr))))
+#define write_int16(ptr, val) *(uint16_t *)(ptr) = SPICE_BYTESWAP16((uint16_t)val)
+#define read_uint16(ptr) ((uint16_t)SPICE_BYTESWAP16(*((uint16_t *)(ptr))))
+#define write_uint16(ptr, val) *(uint16_t *)(ptr) = SPICE_BYTESWAP16((uint16_t)val)
+#define read_int32(ptr) ((int32_t)SPICE_BYTESWAP32(*((uint32_t *)(ptr))))
+#define write_int32(ptr, val) *(uint32_t *)(ptr) = SPICE_BYTESWAP32((uint32_t)val)
+#define read_uint32(ptr) ((uint32_t)SPICE_BYTESWAP32(*((uint32_t *)(ptr))))
+#define write_uint32(ptr, val) *(uint32_t *)(ptr) = SPICE_BYTESWAP32((uint32_t)val)
+#define read_int64(ptr) ((int64_t)SPICE_BYTESWAP64(*((uint64_t *)(ptr))))
+#define write_int64(ptr, val) *(uint64_t *)(ptr) = SPICE_BYTESWAP64((uint64_t)val)
+#define read_uint64(ptr) ((uint64_t)SPICE_BYTESWAP64(*((uint64_t *)(ptr))))
+#define write_uint64(ptr, val) *(uint64_t *)(ptr) = SPICE_BYTESWAP64((uint64_t)val)
+#else
+#define read_int8(ptr) (*((int8_t *)(ptr)))
+#define write_int8(ptr, val) (*((int8_t *)(ptr))) = val
+#define read_uint8(ptr) (*((uint8_t *)(ptr)))
+#define write_uint8(ptr, val) (*((uint8_t *)(ptr))) = val
+#define read_int16(ptr) (*((int16_t *)(ptr)))
+#define write_int16(ptr, val) (*((int16_t *)(ptr))) = val
+#define read_uint16(ptr) (*((uint16_t *)(ptr)))
+#define write_uint16(ptr, val) (*((uint16_t *)(ptr))) = val
+#define read_int32(ptr) (*((int32_t *)(ptr)))
+#define write_int32(ptr, val) (*((int32_t *)(ptr))) = val
+#define read_uint32(ptr) (*((uint32_t *)(ptr)))
+#define write_uint32(ptr, val) (*((uint32_t *)(ptr))) = val
+#define read_int64(ptr) (*((int64_t *)(ptr)))
+#define write_int64(ptr, val) (*((int64_t *)(ptr))) = val
+#define read_uint64(ptr) (*((uint64_t *)(ptr)))
+#define write_uint64(ptr, val) (*((uint64_t *)(ptr))) = val
+#endif
+
+static int8_t SPICE_GNUC_UNUSED consume_int8(uint8_t **ptr)
+{
+ int8_t val;
+ val = read_int8(*ptr);
+ *ptr += 1;
+ return val;
+}
+
+static uint8_t SPICE_GNUC_UNUSED consume_uint8(uint8_t **ptr)
+{
+ uint8_t val;
+ val = read_uint8(*ptr);
+ *ptr += 1;
+ return val;
+}
+
+static int16_t SPICE_GNUC_UNUSED consume_int16(uint8_t **ptr)
+{
+ int16_t val;
+ val = read_int16(*ptr);
+ *ptr += 2;
+ return val;
+}
+
+static uint16_t SPICE_GNUC_UNUSED consume_uint16(uint8_t **ptr)
+{
+ uint16_t val;
+ val = read_uint16(*ptr);
+ *ptr += 2;
+ return val;
+}
+
+static int32_t SPICE_GNUC_UNUSED consume_int32(uint8_t **ptr)
+{
+ int32_t val;
+ val = read_int32(*ptr);
+ *ptr += 4;
+ return val;
+}
+
+static uint32_t SPICE_GNUC_UNUSED consume_uint32(uint8_t **ptr)
+{
+ uint32_t val;
+ val = read_uint32(*ptr);
+ *ptr += 4;
+ return val;
+}
+
+static int64_t SPICE_GNUC_UNUSED consume_int64(uint8_t **ptr)
+{
+ int64_t val;
+ val = read_int64(*ptr);
+ *ptr += 8;
+ return val;
+}
+
+static uint64_t SPICE_GNUC_UNUSED consume_uint64(uint8_t **ptr)
+{
+ uint64_t val;
+ val = read_uint64(*ptr);
+ *ptr += 8;
+ return val;
+}
+static int SPICE_GNUC_UNUSED consume_fd(uint8_t **ptr)
+{
+ return -1;
+}
+
+typedef struct PointerInfo PointerInfo;
+typedef void (*message_destructor_t)(uint8_t *message);
+typedef uint8_t * (*parse_func_t)(uint8_t *message_start, uint8_t *message_end, uint8_t *struct_data, PointerInfo *ptr_info, int minor);
+typedef uint8_t * (*parse_msg_func_t)(uint8_t *message_start, uint8_t *message_end, int minor, size_t *size_out, message_destructor_t *free_message);
+typedef uint8_t * (*spice_parse_channel_func_t)(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, int minor, size_t *size_out, message_destructor_t *free_message);
+
+struct PointerInfo {
+ uint64_t offset;
+ parse_func_t parse;
+ void * *dest;
+ uint32_t nelements;
+};
+
+static uint8_t * parse_msg_migrate(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMigrate *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgMigrate);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMigrate);
+ in = start;
+
+ out = (SpiceMsgMigrate *)data;
+
+ out->flags = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static void nofree(SPICE_GNUC_UNUSED uint8_t *data)
+{
+}
+
+static uint8_t * parse_SpiceMsgData(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t data__nw_size;
+ uint32_t data__nelements;
+
+ { /* data */
+ data__nelements = message_end - (start + 0);
+
+ data__nw_size = data__nelements;
+ }
+
+ nw_size = 0 + data__nw_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = message_start;
+ *size = message_end - message_start;
+ *free_message = nofree;
+ return data;
+
+}
+
+static uint8_t * parse_msg_set_ack(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgSetAck *out;
+
+ nw_size = 8;
+ mem_size = sizeof(SpiceMsgSetAck);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgSetAck);
+ in = start;
+
+ out = (SpiceMsgSetAck *)data;
+
+ out->generation = consume_uint32(&in);
+ out->window = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_ping(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size;
+ uint32_t data__nelements;
+ SpiceMsgPing *out;
+
+ { /* data */
+ data__nelements = message_end - (start + 12);
+
+ data__nw_size = data__nelements;
+ }
+
+ nw_size = 12 + data__nw_size;
+ mem_size = sizeof(SpiceMsgPing);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgPing);
+ in = start;
+
+ out = (SpiceMsgPing *)data;
+
+ out->id = consume_uint32(&in);
+ out->timestamp = consume_uint64(&in);
+ /* use array as pointer */
+ out->data = (uint8_t *)in;
+ out->data_len = data__nelements;
+ in += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_wait_for_channels(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t wait_list__nw_size, wait_list__mem_size;
+ uint32_t wait_list__nelements;
+ SpiceMsgWaitForChannels *out;
+ uint32_t i;
+
+ { /* wait_list */
+ uint8_t wait_count__value;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ wait_count__value = read_uint8(pos);
+ wait_list__nelements = wait_count__value;
+
+ wait_list__nw_size = (10) * wait_list__nelements;
+ wait_list__mem_size = sizeof(SpiceWaitForChannel) * wait_list__nelements;
+ }
+
+ nw_size = 1 + wait_list__nw_size;
+ mem_size = sizeof(SpiceMsgWaitForChannels) + wait_list__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgWaitForChannels);
+ in = start;
+
+ out = (SpiceMsgWaitForChannels *)data;
+
+ out->wait_count = consume_uint8(&in);
+ for (i = 0; i < wait_list__nelements; i++) {
+ SpiceWaitForChannel *out2;
+ out2 = (SpiceWaitForChannel *)end;
+ end += sizeof(SpiceWaitForChannel);
+
+ out2->channel_type = consume_uint8(&in);
+ out2->channel_id = consume_uint8(&in);
+ out2->message_serial = consume_uint64(&in);
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_disconnecting(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisconnect *out;
+
+ nw_size = 12;
+ mem_size = sizeof(SpiceMsgDisconnect);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisconnect);
+ in = start;
+
+ out = (SpiceMsgDisconnect *)data;
+
+ out->time_stamp = consume_uint64(&in);
+ out->reason = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_notify(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t message__nw_size, message__mem_size;
+ uint32_t message__nelements;
+ SpiceMsgNotify *out;
+
+ { /* message */
+ uint32_t message_len__value;
+ pos = start + 20;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ message_len__value = read_uint32(pos);
+ message__nelements = message_len__value;
+
+ message__nw_size = message__nelements;
+ message__mem_size = sizeof(uint8_t) * message__nelements;
+ }
+
+ nw_size = 24 + message__nw_size;
+ mem_size = sizeof(SpiceMsgNotify) + message__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgNotify);
+ in = start;
+
+ out = (SpiceMsgNotify *)data;
+
+ out->time_stamp = consume_uint64(&in);
+ out->severity = consume_uint32(&in);
+ out->visibilty = consume_uint32(&in);
+ out->what = consume_uint32(&in);
+ out->message_len = consume_uint32(&in);
+ memcpy(out->message, in, message__nelements);
+ in += message__nelements;
+ end += message__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_SpiceMsgEmpty(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+
+ nw_size = 0;
+ mem_size = sizeof(SpiceMsgEmpty);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgEmpty);
+ in = start;
+
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_array_uint8(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+
+ end = struct_data;
+ memcpy(end, in, this_ptr_info->nelements);
+ in += this_ptr_info->nelements;
+ end += this_ptr_info->nelements;
+ return end;
+}
+
+static uint8_t * parse_msg_main_migrate_begin(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t dst_info__extra_size;
+ SpiceMsgMainMigrationBegin *out;
+ uint32_t i;
+
+ { /* dst_info */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t dst_info_host_data__extra_size;
+ uint32_t dst_info_host_data__array__nelements;
+ size_t dst_info_cert_subject_data__extra_size;
+ uint32_t dst_info_cert_subject_data__array__nelements;
+ { /* host_data */
+ uint32_t host_data__value;
+ uint32_t dst_info_host_data__array__nw_size;
+ uint32_t dst_info_host_data__array__mem_size;
+ uint32_t host_size__value;
+ pos = (start2 + 8);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ host_data__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(host_data__value == 0)) {
+ goto error;
+ }
+ if (SPICE_UNLIKELY(message_start + host_data__value >= message_end)) {
+ goto error;
+ }
+ pos = start2 + 4;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ host_size__value = read_uint32(pos);
+ dst_info_host_data__array__nelements = host_size__value;
+
+ dst_info_host_data__array__nw_size = dst_info_host_data__array__nelements;
+ dst_info_host_data__array__mem_size = sizeof(uint8_t) * dst_info_host_data__array__nelements;
+ if (SPICE_UNLIKELY(message_start + host_data__value + dst_info_host_data__array__nw_size > message_end)) {
+ goto error;
+ }
+ dst_info_host_data__extra_size = dst_info_host_data__array__mem_size + /* for alignment */ 3;
+ }
+
+ { /* cert_subject_data */
+ uint32_t cert_subject_data__value;
+ uint32_t dst_info_cert_subject_data__array__nw_size;
+ uint32_t dst_info_cert_subject_data__array__mem_size;
+ uint32_t cert_subject_size__value;
+ pos = (start2 + 16);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ cert_subject_data__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(message_start + cert_subject_data__value >= message_end)) {
+ goto error;
+ }
+ pos = start2 + 12;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ cert_subject_size__value = read_uint32(pos);
+ dst_info_cert_subject_data__array__nelements = cert_subject_size__value;
+
+ dst_info_cert_subject_data__array__nw_size = dst_info_cert_subject_data__array__nelements;
+ dst_info_cert_subject_data__array__mem_size = sizeof(uint8_t) * dst_info_cert_subject_data__array__nelements;
+ if (SPICE_UNLIKELY(message_start + cert_subject_data__value + dst_info_cert_subject_data__array__nw_size > message_end)) {
+ goto error;
+ }
+ dst_info_cert_subject_data__extra_size = dst_info_cert_subject_data__array__mem_size + /* for alignment */ 3;
+ }
+
+ dst_info__extra_size = dst_info_host_data__extra_size + dst_info_cert_subject_data__extra_size;
+ }
+
+ nw_size = 20;
+ mem_size = sizeof(SpiceMsgMainMigrationBegin) + dst_info__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainMigrationBegin);
+ in = start;
+
+ out = (SpiceMsgMainMigrationBegin *)data;
+
+ /* dst_info */ {
+ uint32_t host_data__array__nelements;
+ uint32_t cert_subject_data__array__nelements;
+ out->dst_info.port = consume_uint16(&in);
+ out->dst_info.sport = consume_uint16(&in);
+ out->dst_info.host_size = consume_uint32(&in);
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_array_uint8;
+ ptr_info[n_ptr].dest = (void **)&out->dst_info.host_data;
+ host_data__array__nelements = out->dst_info.host_size;
+ ptr_info[n_ptr].nelements = host_data__array__nelements;
+ n_ptr++;
+ out->dst_info.cert_subject_size = consume_uint32(&in);
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_array_uint8;
+ ptr_info[n_ptr].dest = (void **)&out->dst_info.cert_subject_data;
+ cert_subject_data__array__nelements = out->dst_info.cert_subject_size;
+ ptr_info[n_ptr].nelements = cert_subject_data__array__nelements;
+ n_ptr++;
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_init(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMainInit *out;
+
+ nw_size = 32;
+ mem_size = sizeof(SpiceMsgMainInit);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainInit);
+ in = start;
+
+ out = (SpiceMsgMainInit *)data;
+
+ out->session_id = consume_uint32(&in);
+ out->display_channels_hint = consume_uint32(&in);
+ out->supported_mouse_modes = consume_uint32(&in);
+ out->current_mouse_mode = consume_uint32(&in);
+ out->agent_connected = consume_uint32(&in);
+ out->agent_tokens = consume_uint32(&in);
+ out->multi_media_time = consume_uint32(&in);
+ out->ram_hint = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_channels_list(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t channels__nw_size, channels__mem_size;
+ uint32_t channels__nelements;
+ SpiceMsgChannels *out;
+ uint32_t i;
+
+ { /* channels */
+ uint32_t num_of_channels__value;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_of_channels__value = read_uint32(pos);
+ channels__nelements = num_of_channels__value;
+
+ channels__nw_size = (2) * channels__nelements;
+ channels__mem_size = sizeof(SpiceChannelId) * channels__nelements;
+ }
+
+ nw_size = 4 + channels__nw_size;
+ mem_size = sizeof(SpiceMsgChannels) + channels__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgChannels);
+ in = start;
+
+ out = (SpiceMsgChannels *)data;
+
+ out->num_of_channels = consume_uint32(&in);
+ for (i = 0; i < channels__nelements; i++) {
+ SpiceChannelId *out2;
+ out2 = (SpiceChannelId *)end;
+ end += sizeof(SpiceChannelId);
+
+ out2->type = consume_uint8(&in);
+ out2->id = consume_uint8(&in);
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_mouse_mode(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMainMouseMode *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgMainMouseMode);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainMouseMode);
+ in = start;
+
+ out = (SpiceMsgMainMouseMode *)data;
+
+ out->supported_modes = consume_uint16(&in);
+ out->current_mode = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_multi_media_time(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMainMultiMediaTime *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgMainMultiMediaTime);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainMultiMediaTime);
+ in = start;
+
+ out = (SpiceMsgMainMultiMediaTime *)data;
+
+ out->time = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_agent_disconnected(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMainAgentDisconnect *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgMainAgentDisconnect);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainAgentDisconnect);
+ in = start;
+
+ out = (SpiceMsgMainAgentDisconnect *)data;
+
+ out->error_code = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_agent_token(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMainAgentTokens *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgMainAgentTokens);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainAgentTokens);
+ in = start;
+
+ out = (SpiceMsgMainAgentTokens *)data;
+
+ out->num_tokens = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_migrate_switch_host(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t host_data__extra_size;
+ uint32_t host_data__array__nelements;
+ size_t cert_subject_data__extra_size;
+ uint32_t cert_subject_data__array__nelements;
+ SpiceMsgMainMigrationSwitchHost *out;
+ uint32_t i;
+
+ { /* host_data */
+ uint32_t host_data__value;
+ uint32_t host_data__array__nw_size;
+ uint32_t host_data__array__mem_size;
+ uint32_t host_size__value;
+ pos = (start + 8);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ host_data__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(message_start + host_data__value >= message_end)) {
+ goto error;
+ }
+ pos = start + 4;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ host_size__value = read_uint32(pos);
+ host_data__array__nelements = host_size__value;
+
+ host_data__array__nw_size = host_data__array__nelements;
+ host_data__array__mem_size = sizeof(uint8_t) * host_data__array__nelements;
+ if (SPICE_UNLIKELY(message_start + host_data__value + host_data__array__nw_size > message_end)) {
+ goto error;
+ }
+ host_data__extra_size = host_data__array__mem_size + /* for alignment */ 3;
+ }
+
+ { /* cert_subject_data */
+ uint32_t cert_subject_data__value;
+ uint32_t cert_subject_data__array__nw_size;
+ uint32_t cert_subject_data__array__mem_size;
+ uint32_t cert_subject_size__value;
+ pos = (start + 16);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ cert_subject_data__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(message_start + cert_subject_data__value >= message_end)) {
+ goto error;
+ }
+ pos = start + 12;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ cert_subject_size__value = read_uint32(pos);
+ cert_subject_data__array__nelements = cert_subject_size__value;
+
+ cert_subject_data__array__nw_size = cert_subject_data__array__nelements;
+ cert_subject_data__array__mem_size = sizeof(uint8_t) * cert_subject_data__array__nelements;
+ if (SPICE_UNLIKELY(message_start + cert_subject_data__value + cert_subject_data__array__nw_size > message_end)) {
+ goto error;
+ }
+ cert_subject_data__extra_size = cert_subject_data__array__mem_size + /* for alignment */ 3;
+ }
+
+ nw_size = 20;
+ mem_size = sizeof(SpiceMsgMainMigrationSwitchHost) + host_data__extra_size + cert_subject_data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainMigrationSwitchHost);
+ in = start;
+
+ out = (SpiceMsgMainMigrationSwitchHost *)data;
+
+ out->port = consume_uint16(&in);
+ out->sport = consume_uint16(&in);
+ out->host_size = consume_uint32(&in);
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_array_uint8;
+ ptr_info[n_ptr].dest = (void **)&out->host_data;
+ ptr_info[n_ptr].nelements = host_data__array__nelements;
+ n_ptr++;
+ out->cert_subject_size = consume_uint32(&in);
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_array_uint8;
+ ptr_info[n_ptr].dest = (void **)&out->cert_subject_data;
+ ptr_info[n_ptr].nelements = cert_subject_data__array__nelements;
+ n_ptr++;
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_name(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t name__nw_size, name__mem_size;
+ uint32_t name__nelements;
+ SpiceMsgMainName *out;
+
+ { /* name */
+ uint32_t name_len__value;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ name_len__value = read_uint32(pos);
+ name__nelements = name_len__value;
+
+ name__nw_size = name__nelements;
+ name__mem_size = sizeof(uint8_t) * name__nelements;
+ }
+
+ nw_size = 4 + name__nw_size;
+ mem_size = sizeof(SpiceMsgMainName) + name__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainName);
+ in = start;
+
+ out = (SpiceMsgMainName *)data;
+
+ out->name_len = consume_uint32(&in);
+ memcpy(out->name, in, name__nelements);
+ in += name__nelements;
+ end += name__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_uuid(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMainUuid *out;
+ uint32_t uuid__nelements;
+
+ nw_size = 16;
+ mem_size = sizeof(SpiceMsgMainUuid);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainUuid);
+ in = start;
+
+ out = (SpiceMsgMainUuid *)data;
+
+ uuid__nelements = 16;
+ memcpy(out->uuid, in, uuid__nelements);
+ in += uuid__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_agent_connected_tokens(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMainAgentConnectedTokens *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgMainAgentConnectedTokens);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainAgentConnectedTokens);
+ in = start;
+
+ out = (SpiceMsgMainAgentConnectedTokens *)data;
+
+ out->num_tokens = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_migrate_begin_seamless(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t dst_info__extra_size;
+ SpiceMsgMainMigrateBeginSeamless *out;
+ uint32_t i;
+
+ { /* dst_info */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t dst_info_host_data__extra_size;
+ uint32_t dst_info_host_data__array__nelements;
+ size_t dst_info_cert_subject_data__extra_size;
+ uint32_t dst_info_cert_subject_data__array__nelements;
+ { /* host_data */
+ uint32_t host_data__value;
+ uint32_t dst_info_host_data__array__nw_size;
+ uint32_t dst_info_host_data__array__mem_size;
+ uint32_t host_size__value;
+ pos = (start2 + 8);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ host_data__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(host_data__value == 0)) {
+ goto error;
+ }
+ if (SPICE_UNLIKELY(message_start + host_data__value >= message_end)) {
+ goto error;
+ }
+ pos = start2 + 4;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ host_size__value = read_uint32(pos);
+ dst_info_host_data__array__nelements = host_size__value;
+
+ dst_info_host_data__array__nw_size = dst_info_host_data__array__nelements;
+ dst_info_host_data__array__mem_size = sizeof(uint8_t) * dst_info_host_data__array__nelements;
+ if (SPICE_UNLIKELY(message_start + host_data__value + dst_info_host_data__array__nw_size > message_end)) {
+ goto error;
+ }
+ dst_info_host_data__extra_size = dst_info_host_data__array__mem_size + /* for alignment */ 3;
+ }
+
+ { /* cert_subject_data */
+ uint32_t cert_subject_data__value;
+ uint32_t dst_info_cert_subject_data__array__nw_size;
+ uint32_t dst_info_cert_subject_data__array__mem_size;
+ uint32_t cert_subject_size__value;
+ pos = (start2 + 16);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ cert_subject_data__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(message_start + cert_subject_data__value >= message_end)) {
+ goto error;
+ }
+ pos = start2 + 12;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ cert_subject_size__value = read_uint32(pos);
+ dst_info_cert_subject_data__array__nelements = cert_subject_size__value;
+
+ dst_info_cert_subject_data__array__nw_size = dst_info_cert_subject_data__array__nelements;
+ dst_info_cert_subject_data__array__mem_size = sizeof(uint8_t) * dst_info_cert_subject_data__array__nelements;
+ if (SPICE_UNLIKELY(message_start + cert_subject_data__value + dst_info_cert_subject_data__array__nw_size > message_end)) {
+ goto error;
+ }
+ dst_info_cert_subject_data__extra_size = dst_info_cert_subject_data__array__mem_size + /* for alignment */ 3;
+ }
+
+ dst_info__extra_size = dst_info_host_data__extra_size + dst_info_cert_subject_data__extra_size;
+ }
+
+ nw_size = 24;
+ mem_size = sizeof(SpiceMsgMainMigrateBeginSeamless) + dst_info__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainMigrateBeginSeamless);
+ in = start;
+
+ out = (SpiceMsgMainMigrateBeginSeamless *)data;
+
+ /* dst_info */ {
+ uint32_t host_data__array__nelements;
+ uint32_t cert_subject_data__array__nelements;
+ out->dst_info.port = consume_uint16(&in);
+ out->dst_info.sport = consume_uint16(&in);
+ out->dst_info.host_size = consume_uint32(&in);
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_array_uint8;
+ ptr_info[n_ptr].dest = (void **)&out->dst_info.host_data;
+ host_data__array__nelements = out->dst_info.host_size;
+ ptr_info[n_ptr].nelements = host_data__array__nelements;
+ n_ptr++;
+ out->dst_info.cert_subject_size = consume_uint32(&in);
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_array_uint8;
+ ptr_info[n_ptr].dest = (void **)&out->dst_info.cert_subject_data;
+ cert_subject_data__array__nelements = out->dst_info.cert_subject_size;
+ ptr_info[n_ptr].nelements = cert_subject_data__array__nelements;
+ n_ptr++;
+ }
+ out->src_mig_version = consume_uint32(&in);
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_MainChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[8] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify,
+ parse_SpiceMsgData
+ };
+ static parse_msg_func_t funcs2[19] = {
+ parse_SpiceMsgEmpty,
+ parse_msg_main_migrate_begin,
+ parse_SpiceMsgEmpty,
+ parse_msg_main_init,
+ parse_msg_main_channels_list,
+ parse_msg_main_mouse_mode,
+ parse_msg_main_multi_media_time,
+ parse_SpiceMsgEmpty,
+ parse_msg_main_agent_disconnected,
+ parse_SpiceMsgData,
+ parse_msg_main_agent_token,
+ parse_msg_main_migrate_switch_host,
+ parse_SpiceMsgEmpty,
+ parse_msg_main_name,
+ parse_msg_main_uuid,
+ parse_msg_main_agent_connected_tokens,
+ parse_msg_main_migrate_begin_seamless,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgEmpty
+ };
+ if (message_type >= 1 && message_type < 9) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 100 && message_type < 119) {
+ return funcs2[message_type-100](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msg_display_mode(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisplayMode *out;
+
+ nw_size = 12;
+ mem_size = sizeof(SpiceMsgDisplayMode);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayMode);
+ in = start;
+
+ out = (SpiceMsgDisplayMode *)data;
+
+ out->x_res = consume_uint32(&in);
+ out->y_res = consume_uint32(&in);
+ out->bits = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_struct_SpiceClipRects(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+ SpiceClipRects *out;
+ uint32_t rects__nelements;
+ uint32_t i;
+
+ end = struct_data + sizeof(SpiceClipRects);
+ out = (SpiceClipRects *)struct_data;
+
+ out->num_rects = consume_uint32(&in);
+ rects__nelements = out->num_rects;
+ for (i = 0; i < rects__nelements; i++) {
+ SpiceRect *out2;
+ out2 = (SpiceRect *)end;
+ end += sizeof(SpiceRect);
+
+ out2->top = consume_int32(&in);
+ out2->left = consume_int32(&in);
+ out2->bottom = consume_int32(&in);
+ out2->right = consume_int32(&in);
+ }
+ return end;
+}
+
+static uint8_t * parse_msg_display_copy_bits(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[1];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ SpiceMsgDisplayCopyBits *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ nw_size = 8 + base__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayCopyBits) + base__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayCopyBits);
+ in = start;
+
+ out = (SpiceMsgDisplayCopyBits *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* src_pos */ {
+ out->src_pos.x = consume_int32(&in);
+ out->src_pos.y = consume_int32(&in);
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_inval_list(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t resources__nw_size, resources__mem_size;
+ uint32_t resources__nelements;
+ SpiceResourceList *out;
+ uint32_t i;
+
+ { /* resources */
+ uint16_t count__value;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ count__value = read_uint16(pos);
+ resources__nelements = count__value;
+
+ resources__nw_size = (9) * resources__nelements;
+ resources__mem_size = sizeof(SpiceResourceID) * resources__nelements;
+ }
+
+ nw_size = 2 + resources__nw_size;
+ mem_size = sizeof(SpiceResourceList) + resources__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceResourceList);
+ in = start;
+
+ out = (SpiceResourceList *)data;
+
+ out->count = consume_uint16(&in);
+ for (i = 0; i < resources__nelements; i++) {
+ SpiceResourceID *out2;
+ out2 = (SpiceResourceID *)end;
+ end += sizeof(SpiceResourceID);
+
+ out2->type = consume_uint8(&in);
+ out2->id = consume_uint64(&in);
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_inval_all_pixmaps(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t wait_list__nw_size, wait_list__mem_size;
+ uint32_t wait_list__nelements;
+ SpiceMsgWaitForChannels *out;
+ uint32_t i;
+
+ { /* wait_list */
+ uint8_t wait_count__value;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ wait_count__value = read_uint8(pos);
+ wait_list__nelements = wait_count__value;
+
+ wait_list__nw_size = (10) * wait_list__nelements;
+ wait_list__mem_size = sizeof(SpiceWaitForChannel) * wait_list__nelements;
+ }
+
+ nw_size = 1 + wait_list__nw_size;
+ mem_size = sizeof(SpiceMsgWaitForChannels) + wait_list__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgWaitForChannels);
+ in = start;
+
+ out = (SpiceMsgWaitForChannels *)data;
+
+ out->wait_count = consume_uint8(&in);
+ for (i = 0; i < wait_list__nelements; i++) {
+ SpiceWaitForChannel *out2;
+ out2 = (SpiceWaitForChannel *)end;
+ end += sizeof(SpiceWaitForChannel);
+
+ out2->channel_type = consume_uint8(&in);
+ out2->channel_id = consume_uint8(&in);
+ out2->message_serial = consume_uint64(&in);
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_inval_palette(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisplayInvalOne *out;
+
+ nw_size = 8;
+ mem_size = sizeof(SpiceMsgDisplayInvalOne);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayInvalOne);
+ in = start;
+
+ out = (SpiceMsgDisplayInvalOne *)data;
+
+ out->id = consume_uint64(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_stream_create(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[1];
+ size_t clip__nw_size, clip__extra_size;
+ uint32_t rects__saved_size = 0;
+ SpiceMsgDisplayStreamCreate *out;
+ uint32_t i;
+
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 50);
+ size_t clip_u__nw_size, clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t clip_u__mem_size;
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 1);
+ size_t clip_u_rects__nw_size, clip_u_rects__mem_size;
+ uint32_t clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ clip_u_rects__nelements = num_rects__value;
+
+ clip_u_rects__nw_size = (16) * clip_u_rects__nelements;
+ clip_u_rects__mem_size = sizeof(SpiceRect) * clip_u_rects__nelements;
+ }
+
+ clip_u__nw_size = 4 + clip_u_rects__nw_size;
+ clip_u__mem_size = sizeof(SpiceClipRects) + clip_u_rects__mem_size;
+ rects__saved_size = clip_u__nw_size;
+ clip_u__extra_size = clip_u__mem_size;
+ } else {
+ clip_u__nw_size = 0;
+ clip_u__extra_size = 0;
+ }
+
+ }
+
+ clip__nw_size = 1 + clip_u__nw_size;
+ clip__extra_size = clip_u__extra_size;
+ }
+
+ nw_size = 50 + clip__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayStreamCreate) + clip__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayStreamCreate);
+ in = start;
+
+ out = (SpiceMsgDisplayStreamCreate *)data;
+
+ out->surface_id = consume_uint32(&in);
+ out->id = consume_uint32(&in);
+ out->flags = consume_uint8(&in);
+ out->codec_type = consume_uint8(&in);
+ out->stamp = consume_uint64(&in);
+ out->stream_width = consume_uint32(&in);
+ out->stream_height = consume_uint32(&in);
+ out->src_width = consume_uint32(&in);
+ out->src_height = consume_uint32(&in);
+ /* dest */ {
+ out->dest.top = consume_int32(&in);
+ out->dest.left = consume_int32(&in);
+ out->dest.bottom = consume_int32(&in);
+ out->dest.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->clip.type = consume_uint8(&in);
+ if (out->clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_stream_data(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size, data__mem_size;
+ uint32_t data__nelements;
+ SpiceMsgDisplayStreamData *out;
+
+ { /* data */
+ uint32_t data_size__value;
+ pos = start + 8;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ data__nelements = data_size__value;
+
+ data__nw_size = data__nelements;
+ data__mem_size = sizeof(uint8_t) * data__nelements;
+ }
+
+ nw_size = 12 + data__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayStreamData) + data__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayStreamData);
+ in = start;
+
+ out = (SpiceMsgDisplayStreamData *)data;
+
+ /* base */ {
+ out->base.id = consume_uint32(&in);
+ out->base.multi_media_time = consume_uint32(&in);
+ }
+ out->data_size = consume_uint32(&in);
+ memcpy(out->data, in, data__nelements);
+ in += data__nelements;
+ end += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_stream_clip(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[1];
+ size_t clip__nw_size, clip__extra_size;
+ uint32_t rects__saved_size = 0;
+ SpiceMsgDisplayStreamClip *out;
+ uint32_t i;
+
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 4);
+ size_t clip_u__nw_size, clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t clip_u__mem_size;
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 1);
+ size_t clip_u_rects__nw_size, clip_u_rects__mem_size;
+ uint32_t clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ clip_u_rects__nelements = num_rects__value;
+
+ clip_u_rects__nw_size = (16) * clip_u_rects__nelements;
+ clip_u_rects__mem_size = sizeof(SpiceRect) * clip_u_rects__nelements;
+ }
+
+ clip_u__nw_size = 4 + clip_u_rects__nw_size;
+ clip_u__mem_size = sizeof(SpiceClipRects) + clip_u_rects__mem_size;
+ rects__saved_size = clip_u__nw_size;
+ clip_u__extra_size = clip_u__mem_size;
+ } else {
+ clip_u__nw_size = 0;
+ clip_u__extra_size = 0;
+ }
+
+ }
+
+ clip__nw_size = 1 + clip_u__nw_size;
+ clip__extra_size = clip_u__extra_size;
+ }
+
+ nw_size = 4 + clip__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayStreamClip) + clip__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayStreamClip);
+ in = start;
+
+ out = (SpiceMsgDisplayStreamClip *)data;
+
+ out->id = consume_uint32(&in);
+ /* clip */ {
+ out->clip.type = consume_uint8(&in);
+ if (out->clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_stream_destroy(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisplayStreamDestroy *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgDisplayStreamDestroy);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayStreamDestroy);
+ in = start;
+
+ out = (SpiceMsgDisplayStreamDestroy *)data;
+
+ out->id = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static intptr_t validate_SpicePalette(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *start = message_start + offset;
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ size_t mem_size, nw_size;
+ size_t ents__nw_size, ents__mem_size;
+ uint32_t ents__nelements;
+
+ if (offset == 0) {
+ return 0;
+ }
+
+ if (SPICE_UNLIKELY(start >= message_end)) {
+ goto error;
+ }
+
+ { /* ents */
+ uint16_t num_ents__value;
+ pos = start + 8;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ num_ents__value = read_uint16(pos);
+ ents__nelements = num_ents__value;
+
+ ents__nw_size = (4) * ents__nelements;
+ ents__mem_size = sizeof(uint32_t) * ents__nelements;
+ }
+
+ nw_size = 10 + ents__nw_size;
+ mem_size = sizeof(SpicePalette) + ents__mem_size;
+
+ /* Check if struct fits in reported side */
+ if (SPICE_UNLIKELY(start + nw_size > message_end)) {
+ goto error;
+ }
+ return mem_size;
+
+ error:
+ return -1;
+}
+
+static intptr_t validate_SpiceImage(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *start = message_start + offset;
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ size_t mem_size, nw_size;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ size_t u__nw_size, u__extra_size;
+ uint8_t descriptor_type__value;
+
+ if (offset == 0) {
+ return 0;
+ }
+
+ if (SPICE_UNLIKELY(start >= message_end)) {
+ goto error;
+ }
+
+ { /* u */
+ pos = start + 8;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ descriptor_type__value = read_uint8(pos);
+ if (descriptor_type__value == SPICE_IMAGE_TYPE_BITMAP) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ size_t u_pal__nw_size, u_pal__extra_size;
+ uint8_t flags__value;
+ size_t u_data__nw_size, u_data__extra_size;
+ uint32_t u_data__nelements;
+ { /* pal */
+ pos = start2 + 1;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint8(pos);
+ if ((flags__value & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
+ u_pal__nw_size = 8;
+ u_pal__extra_size = 0;
+ } else if (1) {
+ uint32_t u_pal_palette__value;
+ u_pal__nw_size = 4;
+ pos = (start2 + 14);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ u_pal_palette__value = read_uint32(pos);
+ ptr_size = validate_SpicePalette(message_start, message_end, u_pal_palette__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ u_pal__extra_size = ptr_size + /* for alignment */ 3;
+ } else {
+ u_pal__nw_size = 0;
+ u_pal__extra_size = 0;
+ }
+
+ }
+
+ { /* data */
+ uint32_t stride__value;
+ uint32_t y__value;
+ pos = start2 + 10;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ stride__value = read_uint32(pos);
+ pos = start2 + 6;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ y__value = read_uint32(pos);
+ u_data__nelements = stride__value * y__value;
+
+ u_data__nw_size = u_data__nelements;
+ u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ }
+
+ u__nw_size = 14 + u_pal__nw_size + u_data__nw_size;
+ u__extra_size = u_pal__extra_size + u_data__extra_size;
+ } else if (descriptor_type__value == SPICE_IMAGE_TYPE_QUIC) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ size_t u_data__nw_size, u_data__extra_size;
+ uint32_t u_data__nelements;
+ { /* data */
+ uint32_t data_size__value;
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ u_data__nelements = data_size__value;
+
+ u_data__nw_size = u_data__nelements;
+ u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ }
+
+ u__nw_size = 4 + u_data__nw_size;
+ u__extra_size = u_data__extra_size;
+ } else if (descriptor_type__value == SPICE_IMAGE_TYPE_LZ_RGB || descriptor_type__value == SPICE_IMAGE_TYPE_GLZ_RGB) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ size_t u_data__nw_size, u_data__extra_size;
+ uint32_t u_data__nelements;
+ { /* data */
+ uint32_t data_size__value;
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ u_data__nelements = data_size__value;
+
+ u_data__nw_size = u_data__nelements;
+ u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ }
+
+ u__nw_size = 4 + u_data__nw_size;
+ u__extra_size = u_data__extra_size;
+ } else if (descriptor_type__value == SPICE_IMAGE_TYPE_JPEG) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ size_t u_data__nw_size, u_data__extra_size;
+ uint32_t u_data__nelements;
+ { /* data */
+ uint32_t data_size__value;
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ u_data__nelements = data_size__value;
+
+ u_data__nw_size = u_data__nelements;
+ u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ }
+
+ u__nw_size = 4 + u_data__nw_size;
+ u__extra_size = u_data__extra_size;
+ } else if (descriptor_type__value == SPICE_IMAGE_TYPE_LZ4) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ size_t u_data__nw_size, u_data__extra_size;
+ uint32_t u_data__nelements;
+ { /* data */
+ uint32_t data_size__value;
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ u_data__nelements = data_size__value;
+
+ u_data__nw_size = u_data__nelements;
+ u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ }
+
+ u__nw_size = 4 + u_data__nw_size;
+ u__extra_size = u_data__extra_size;
+ } else if (descriptor_type__value == SPICE_IMAGE_TYPE_LZ_PLT) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ size_t u_pal__nw_size, u_pal__extra_size;
+ uint8_t flags__value;
+ size_t u_data__nw_size, u_data__extra_size;
+ uint32_t u_data__nelements;
+ { /* pal */
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint8(pos);
+ if ((flags__value & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
+ u_pal__nw_size = 8;
+ u_pal__extra_size = 0;
+ } else if (1) {
+ uint32_t u_pal_palette__value;
+ u_pal__nw_size = 4;
+ pos = (start2 + 5);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ u_pal_palette__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(u_pal_palette__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpicePalette(message_start, message_end, u_pal_palette__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ u_pal__extra_size = ptr_size + /* for alignment */ 3;
+ } else {
+ u_pal__nw_size = 0;
+ u_pal__extra_size = 0;
+ }
+
+ }
+
+ { /* data */
+ uint32_t data_size__value;
+ pos = start2 + 1;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ u_data__nelements = data_size__value;
+
+ u_data__nw_size = u_data__nelements;
+ u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ }
+
+ u__nw_size = 5 + u_pal__nw_size + u_data__nw_size;
+ u__extra_size = u_pal__extra_size + u_data__extra_size;
+ } else if (descriptor_type__value == SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ size_t u_data__nw_size, u_data__extra_size;
+ uint32_t u_data__nelements;
+ { /* data */
+ uint32_t data_size__value;
+ pos = start2 + 4;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ u_data__nelements = data_size__value;
+
+ u_data__nw_size = u_data__nelements;
+ u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ }
+
+ u__nw_size = 8 + u_data__nw_size;
+ u__extra_size = u_data__extra_size;
+ } else if (descriptor_type__value == SPICE_IMAGE_TYPE_JPEG_ALPHA) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ size_t u_data__nw_size, u_data__extra_size;
+ uint32_t u_data__nelements;
+ { /* data */
+ uint32_t data_size__value;
+ pos = start2 + 5;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ u_data__nelements = data_size__value;
+
+ u_data__nw_size = u_data__nelements;
+ u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ }
+
+ u__nw_size = 9 + u_data__nw_size;
+ u__extra_size = u_data__extra_size;
+ } else if (descriptor_type__value == SPICE_IMAGE_TYPE_SURFACE) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ u__nw_size = 4;
+ u__extra_size = 0;
+ } else {
+ u__nw_size = 0;
+ u__extra_size = 0;
+ }
+
+ }
+
+ nw_size = 18 + u__nw_size;
+ mem_size = sizeof(SpiceImage) + u__extra_size;
+
+ /* Check if struct fits in reported side */
+ if (SPICE_UNLIKELY(start + nw_size > message_end)) {
+ goto error;
+ }
+ return mem_size;
+
+ error:
+ return -1;
+}
+
+static uint8_t * parse_struct_SpicePalette(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+ SpicePalette *out;
+ uint32_t ents__nelements;
+ uint32_t i;
+
+ end = struct_data + sizeof(SpicePalette);
+ out = (SpicePalette *)struct_data;
+
+ out->unique = consume_uint64(&in);
+ out->num_ents = consume_uint16(&in);
+ ents__nelements = out->num_ents;
+ for (i = 0; i < ents__nelements; i++) {
+ out->ents[i] = consume_uint32(&in);
+ end += sizeof(uint32_t);
+ }
+ return end;
+}
+
+static uint8_t * parse_struct_SpiceImage(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[1];
+ SpiceImage *out;
+ uint32_t i;
+
+ end = struct_data + sizeof(SpiceImage);
+ out = (SpiceImage *)struct_data;
+
+ /* descriptor */ {
+ out->descriptor.id = consume_uint64(&in);
+ out->descriptor.type = consume_uint8(&in);
+ out->descriptor.flags = consume_uint8(&in);
+ out->descriptor.width = consume_uint32(&in);
+ out->descriptor.height = consume_uint32(&in);
+ }
+ if (out->descriptor.type == SPICE_IMAGE_TYPE_BITMAP) {
+ uint32_t data__nelements;
+ SpiceChunks *chunks;
+ out->u.bitmap.format = consume_uint8(&in);
+ out->u.bitmap.flags = consume_uint8(&in);
+ out->u.bitmap.x = consume_uint32(&in);
+ out->u.bitmap.y = consume_uint32(&in);
+ out->u.bitmap.stride = consume_uint32(&in);
+ if ((out->u.bitmap.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
+ out->u.bitmap.palette_id = consume_uint64(&in);
+ } else if (1) {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpicePalette;
+ ptr_info[n_ptr].dest = (void **)&out->u.bitmap.palette;
+ n_ptr++;
+ }
+ data__nelements = out->u.bitmap.stride * out->u.bitmap.y;
+ /* use array as chunk */
+ chunks = (SpiceChunks *)end;
+ end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ out->u.bitmap.data = chunks;
+ chunks->data_size = data__nelements;
+ chunks->flags = 0;
+ chunks->num_chunks = 1;
+ chunks->chunk[0].len = data__nelements;
+ chunks->chunk[0].data = in;
+ in += data__nelements;
+ } else if (out->descriptor.type == SPICE_IMAGE_TYPE_QUIC) {
+ uint32_t data__nelements;
+ SpiceChunks *chunks;
+ out->u.quic.data_size = consume_uint32(&in);
+ data__nelements = out->u.quic.data_size;
+ /* use array as chunk */
+ chunks = (SpiceChunks *)end;
+ end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ out->u.quic.data = chunks;
+ chunks->data_size = data__nelements;
+ chunks->flags = 0;
+ chunks->num_chunks = 1;
+ chunks->chunk[0].len = data__nelements;
+ chunks->chunk[0].data = in;
+ in += data__nelements;
+ } else if (out->descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB || out->descriptor.type == SPICE_IMAGE_TYPE_GLZ_RGB) {
+ uint32_t data__nelements;
+ SpiceChunks *chunks;
+ out->u.lz_rgb.data_size = consume_uint32(&in);
+ data__nelements = out->u.lz_rgb.data_size;
+ /* use array as chunk */
+ chunks = (SpiceChunks *)end;
+ end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ out->u.lz_rgb.data = chunks;
+ chunks->data_size = data__nelements;
+ chunks->flags = 0;
+ chunks->num_chunks = 1;
+ chunks->chunk[0].len = data__nelements;
+ chunks->chunk[0].data = in;
+ in += data__nelements;
+ } else if (out->descriptor.type == SPICE_IMAGE_TYPE_JPEG) {
+ uint32_t data__nelements;
+ SpiceChunks *chunks;
+ out->u.jpeg.data_size = consume_uint32(&in);
+ data__nelements = out->u.jpeg.data_size;
+ /* use array as chunk */
+ chunks = (SpiceChunks *)end;
+ end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ out->u.jpeg.data = chunks;
+ chunks->data_size = data__nelements;
+ chunks->flags = 0;
+ chunks->num_chunks = 1;
+ chunks->chunk[0].len = data__nelements;
+ chunks->chunk[0].data = in;
+ in += data__nelements;
+ } else if (out->descriptor.type == SPICE_IMAGE_TYPE_LZ4) {
+ uint32_t data__nelements;
+ SpiceChunks *chunks;
+ out->u.lz4.data_size = consume_uint32(&in);
+ data__nelements = out->u.lz4.data_size;
+ /* use array as chunk */
+ chunks = (SpiceChunks *)end;
+ end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ out->u.lz4.data = chunks;
+ chunks->data_size = data__nelements;
+ chunks->flags = 0;
+ chunks->num_chunks = 1;
+ chunks->chunk[0].len = data__nelements;
+ chunks->chunk[0].data = in;
+ in += data__nelements;
+ } else if (out->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) {
+ uint32_t data__nelements;
+ SpiceChunks *chunks;
+ out->u.lz_plt.flags = consume_uint8(&in);
+ out->u.lz_plt.data_size = consume_uint32(&in);
+ if ((out->u.lz_plt.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
+ out->u.lz_plt.palette_id = consume_uint64(&in);
+ } else if (1) {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpicePalette;
+ ptr_info[n_ptr].dest = (void **)&out->u.lz_plt.palette;
+ n_ptr++;
+ }
+ data__nelements = out->u.lz_plt.data_size;
+ /* use array as chunk */
+ chunks = (SpiceChunks *)end;
+ end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ out->u.lz_plt.data = chunks;
+ chunks->data_size = data__nelements;
+ chunks->flags = 0;
+ chunks->num_chunks = 1;
+ chunks->chunk[0].len = data__nelements;
+ chunks->chunk[0].data = in;
+ in += data__nelements;
+ } else if (out->descriptor.type == SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB) {
+ uint32_t data__nelements;
+ SpiceChunks *chunks;
+ out->u.zlib_glz.glz_data_size = consume_uint32(&in);
+ out->u.zlib_glz.data_size = consume_uint32(&in);
+ data__nelements = out->u.zlib_glz.data_size;
+ /* use array as chunk */
+ chunks = (SpiceChunks *)end;
+ end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ out->u.zlib_glz.data = chunks;
+ chunks->data_size = data__nelements;
+ chunks->flags = 0;
+ chunks->num_chunks = 1;
+ chunks->chunk[0].len = data__nelements;
+ chunks->chunk[0].data = in;
+ in += data__nelements;
+ } else if (out->descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA) {
+ uint32_t data__nelements;
+ SpiceChunks *chunks;
+ out->u.jpeg_alpha.flags = consume_uint8(&in);
+ out->u.jpeg_alpha.jpeg_size = consume_uint32(&in);
+ out->u.jpeg_alpha.data_size = consume_uint32(&in);
+ data__nelements = out->u.jpeg_alpha.data_size;
+ /* use array as chunk */
+ chunks = (SpiceChunks *)end;
+ end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ out->u.jpeg_alpha.data = chunks;
+ chunks->data_size = data__nelements;
+ chunks->flags = 0;
+ chunks->num_chunks = 1;
+ chunks->chunk[0].len = data__nelements;
+ chunks->chunk[0].data = in;
+ in += data__nelements;
+ } else if (out->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) {
+ out->u.surface.surface_id = consume_uint32(&in);
+ }
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ return end;
+
+ error:
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_fill(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[3];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__nw_size, data__extra_size;
+ SpiceMsgDisplayDrawFill *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_brush__nw_size, data_brush__extra_size;
+ size_t data_mask__extra_size;
+ { /* brush */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
+ size_t data_brush_u__nw_size, data_brush_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_BRUSH_TYPE_SOLID) {
+ data_brush_u__nw_size = 4;
+ data_brush_u__extra_size = 0;
+ } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t data_brush_u_pat__extra_size;
+ { /* pat */
+ uint32_t pat__value;
+ pos = (start4 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ pat__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(pat__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_brush_u__nw_size = 12;
+ data_brush_u__extra_size = data_brush_u_pat__extra_size;
+ } else {
+ data_brush_u__nw_size = 0;
+ data_brush_u__extra_size = 0;
+ }
+
+ }
+
+ data_brush__nw_size = 1 + data_brush_u__nw_size;
+ data_brush__extra_size = data_brush_u__extra_size;
+ }
+
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 2 + data_brush__nw_size);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint32_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__nw_size = 15 + data_brush__nw_size;
+ data__extra_size = data_brush__extra_size + data_mask__extra_size;
+ }
+
+ nw_size = 0 + base__nw_size + data__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawFill) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawFill);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawFill *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ /* brush */ {
+ out->data.brush.type = consume_uint8(&in);
+ if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ out->data.brush.u.color = consume_uint32(&in);
+ } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
+ n_ptr++;
+ /* pos */ {
+ out->data.brush.u.pattern.pos.x = consume_int32(&in);
+ out->data.brush.u.pattern.pos.y = consume_int32(&in);
+ }
+ }
+ }
+ out->data.rop_descriptor = consume_uint16(&in);
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_opaque(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[4];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__nw_size, data__extra_size;
+ SpiceMsgDisplayDrawOpaque *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_src_bitmap__extra_size;
+ size_t data_brush__nw_size, data_brush__extra_size;
+ size_t data_mask__extra_size;
+ { /* src_bitmap */
+ uint32_t src_bitmap__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* brush */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t data_brush_u__nw_size, data_brush_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_BRUSH_TYPE_SOLID) {
+ data_brush_u__nw_size = 4;
+ data_brush_u__extra_size = 0;
+ } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t data_brush_u_pat__extra_size;
+ { /* pat */
+ uint32_t pat__value;
+ pos = (start4 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ pat__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(pat__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_brush_u__nw_size = 12;
+ data_brush_u__extra_size = data_brush_u_pat__extra_size;
+ } else {
+ data_brush_u__nw_size = 0;
+ data_brush_u__extra_size = 0;
+ }
+
+ }
+
+ data_brush__nw_size = 1 + data_brush_u__nw_size;
+ data_brush__extra_size = data_brush_u__extra_size;
+ }
+
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 23 + data_brush__nw_size);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint32_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__nw_size = 36 + data_brush__nw_size;
+ data__extra_size = data_src_bitmap__extra_size + data_brush__extra_size + data_mask__extra_size;
+ }
+
+ nw_size = 0 + base__nw_size + data__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawOpaque) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawOpaque);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawOpaque *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ /* src_area */ {
+ out->data.src_area.top = consume_int32(&in);
+ out->data.src_area.left = consume_int32(&in);
+ out->data.src_area.bottom = consume_int32(&in);
+ out->data.src_area.right = consume_int32(&in);
+ }
+ /* brush */ {
+ out->data.brush.type = consume_uint8(&in);
+ if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ out->data.brush.u.color = consume_uint32(&in);
+ } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
+ n_ptr++;
+ /* pos */ {
+ out->data.brush.u.pattern.pos.x = consume_int32(&in);
+ out->data.brush.u.pattern.pos.y = consume_int32(&in);
+ }
+ }
+ }
+ out->data.rop_descriptor = consume_uint16(&in);
+ out->data.scale_mode = consume_uint8(&in);
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_copy(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[3];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawCopy *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_src_bitmap__extra_size;
+ size_t data_mask__extra_size;
+ { /* src_bitmap */
+ uint32_t src_bitmap__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 23);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint32_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_src_bitmap__extra_size + data_mask__extra_size;
+ }
+
+ nw_size = 36 + base__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawCopy) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawCopy);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawCopy *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ /* src_area */ {
+ out->data.src_area.top = consume_int32(&in);
+ out->data.src_area.left = consume_int32(&in);
+ out->data.src_area.bottom = consume_int32(&in);
+ out->data.src_area.right = consume_int32(&in);
+ }
+ out->data.rop_descriptor = consume_uint16(&in);
+ out->data.scale_mode = consume_uint8(&in);
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_blend(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[3];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawBlend *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_src_bitmap__extra_size;
+ size_t data_mask__extra_size;
+ { /* src_bitmap */
+ uint32_t src_bitmap__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 23);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint32_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_src_bitmap__extra_size + data_mask__extra_size;
+ }
+
+ nw_size = 36 + base__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawBlend) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawBlend);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawBlend *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ /* src_area */ {
+ out->data.src_area.top = consume_int32(&in);
+ out->data.src_area.left = consume_int32(&in);
+ out->data.src_area.bottom = consume_int32(&in);
+ out->data.src_area.right = consume_int32(&in);
+ }
+ out->data.rop_descriptor = consume_uint16(&in);
+ out->data.scale_mode = consume_uint8(&in);
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_blackness(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawBlackness *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_mask__extra_size;
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint32_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_mask__extra_size;
+ }
+
+ nw_size = 13 + base__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawBlackness) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawBlackness);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawBlackness *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_whiteness(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawWhiteness *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_mask__extra_size;
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint32_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_mask__extra_size;
+ }
+
+ nw_size = 13 + base__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawWhiteness) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawWhiteness);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawWhiteness *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_invers(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawInvers *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_mask__extra_size;
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint32_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_mask__extra_size;
+ }
+
+ nw_size = 13 + base__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawInvers) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawInvers);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawInvers *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_rop3(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[4];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__nw_size, data__extra_size;
+ SpiceMsgDisplayDrawRop3 *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_src_bitmap__extra_size;
+ size_t data_brush__nw_size, data_brush__extra_size;
+ size_t data_mask__extra_size;
+ { /* src_bitmap */
+ uint32_t src_bitmap__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* brush */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t data_brush_u__nw_size, data_brush_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_BRUSH_TYPE_SOLID) {
+ data_brush_u__nw_size = 4;
+ data_brush_u__extra_size = 0;
+ } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t data_brush_u_pat__extra_size;
+ { /* pat */
+ uint32_t pat__value;
+ pos = (start4 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ pat__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(pat__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_brush_u__nw_size = 12;
+ data_brush_u__extra_size = data_brush_u_pat__extra_size;
+ } else {
+ data_brush_u__nw_size = 0;
+ data_brush_u__extra_size = 0;
+ }
+
+ }
+
+ data_brush__nw_size = 1 + data_brush_u__nw_size;
+ data_brush__extra_size = data_brush_u__extra_size;
+ }
+
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 22 + data_brush__nw_size);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint32_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__nw_size = 35 + data_brush__nw_size;
+ data__extra_size = data_src_bitmap__extra_size + data_brush__extra_size + data_mask__extra_size;
+ }
+
+ nw_size = 0 + base__nw_size + data__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawRop3) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawRop3);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawRop3 *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ /* src_area */ {
+ out->data.src_area.top = consume_int32(&in);
+ out->data.src_area.left = consume_int32(&in);
+ out->data.src_area.bottom = consume_int32(&in);
+ out->data.src_area.right = consume_int32(&in);
+ }
+ /* brush */ {
+ out->data.brush.type = consume_uint8(&in);
+ if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ out->data.brush.u.color = consume_uint32(&in);
+ } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
+ n_ptr++;
+ /* pos */ {
+ out->data.brush.u.pattern.pos.x = consume_int32(&in);
+ out->data.brush.u.pattern.pos.y = consume_int32(&in);
+ }
+ }
+ }
+ out->data.rop3 = consume_uint8(&in);
+ out->data.scale_mode = consume_uint8(&in);
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static intptr_t validate_SpicePath(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *start = message_start + offset;
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ size_t mem_size, nw_size;
+ size_t segments__nw_size, segments__mem_size;
+ uint32_t segments__nelements;
+ uint32_t i;
+
+ if (offset == 0) {
+ return 0;
+ }
+
+ if (SPICE_UNLIKELY(start >= message_end)) {
+ goto error;
+ }
+
+ { /* segments */
+ uint32_t num_segments__value;
+ uint8_t *start2 = (start + 4);
+ uint32_t segments__element__nw_size;
+ uint32_t segments__element__mem_size;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_segments__value = read_uint32(pos);
+ segments__nelements = num_segments__value;
+
+ segments__nw_size = 0;
+ segments__mem_size = 0;
+ for (i = 0; i < segments__nelements; i++) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = start2;
+ size_t segments__element_points__nw_size, segments__element_points__mem_size;
+ uint32_t segments__element_points__nelements;
+ { /* points */
+ uint32_t count__value;
+ pos = start3 + 1;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ count__value = read_uint32(pos);
+ segments__element_points__nelements = count__value;
+
+ segments__element_points__nw_size = (8) * segments__element_points__nelements;
+ segments__element_points__mem_size = sizeof(SpicePointFix) * segments__element_points__nelements;
+ }
+
+ segments__element__nw_size = 5 + segments__element_points__nw_size;
+ segments__element__mem_size = sizeof(SpicePathSeg) + segments__element_points__mem_size;
+ segments__nw_size += segments__element__nw_size;
+ segments__mem_size += sizeof(void *) + SPICE_ALIGN(segments__element__mem_size, 4);
+ start2 += segments__element__nw_size;
+ }
+ }
+
+ nw_size = 4 + segments__nw_size;
+ mem_size = sizeof(SpicePath) + segments__mem_size;
+
+ /* Check if struct fits in reported side */
+ if (SPICE_UNLIKELY(start + nw_size > message_end)) {
+ goto error;
+ }
+ return mem_size;
+
+ error:
+ return -1;
+}
+
+static uint8_t * parse_struct_SpicePath(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+ SpicePath *out;
+ uint32_t segments__nelements;
+ uint32_t i;
+ void * *ptr_array;
+ int ptr_array_index;
+ uint32_t j;
+
+ end = struct_data + sizeof(SpicePath);
+ out = (SpicePath *)struct_data;
+
+ out->num_segments = consume_uint32(&in);
+ segments__nelements = out->num_segments;
+ ptr_array_index = 0;
+ ptr_array = (void **)out->segments;
+ end += sizeof(void *) * segments__nelements;
+ for (i = 0; i < segments__nelements; i++) {
+ SpicePathSeg *out2;
+ uint32_t points__nelements;
+ ptr_array[ptr_array_index++] = end;
+ out2 = (SpicePathSeg *)end;
+ end += sizeof(SpicePathSeg);
+
+ out2->flags = consume_uint8(&in);
+ out2->count = consume_uint32(&in);
+ points__nelements = out2->count;
+ for (j = 0; j < points__nelements; j++) {
+ SpicePointFix *out3;
+ out3 = (SpicePointFix *)end;
+ end += sizeof(SpicePointFix);
+
+ out3->x = consume_int32(&in);
+ out3->y = consume_int32(&in);
+ }
+ /* Align ptr_array element to 4 bytes */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ }
+ return end;
+}
+
+static uint8_t * parse_array_int32(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+ uint32_t i;
+
+ end = struct_data;
+ for (i = 0; i < this_ptr_info->nelements; i++) {
+ *(SPICE_FIXED28_4 *)end = consume_int32(&in);
+ end += sizeof(SPICE_FIXED28_4);
+ }
+ return end;
+}
+
+static uint8_t * parse_msg_display_draw_stroke(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[4];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__nw_size, data__extra_size;
+ SpiceMsgDisplayDrawStroke *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_path__extra_size;
+ size_t data_attr__nw_size, data_attr__extra_size;
+ size_t data_brush__nw_size, data_brush__extra_size;
+ { /* path */
+ uint32_t path__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ path__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(path__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpicePath(message_start, message_end, path__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_path__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* attr */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 4);
+ size_t data_attr_u1__nw_size;
+ uint8_t flags__value;
+ size_t data_attr_u2__nw_size, data_attr_u2__extra_size;
+ { /* u1 */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint8(pos);
+ if ((flags__value & SPICE_LINE_FLAGS_STYLED)) {
+ data_attr_u1__nw_size = 1;
+ } else {
+ data_attr_u1__nw_size = 0;
+ }
+
+ }
+
+ { /* u2 */
+ uint32_t data_attr_u2__array__nelements;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint8(pos);
+ if ((flags__value & SPICE_LINE_FLAGS_STYLED)) {
+ uint32_t data_attr_u2_style__value;
+ uint32_t data_attr_u2__array__nw_size;
+ uint32_t data_attr_u2__array__mem_size;
+ uint8_t style_nseg__value;
+ data_attr_u2__nw_size = 4;
+ pos = (start3 + 1 + data_attr_u1__nw_size);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_attr_u2_style__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(message_start + data_attr_u2_style__value >= message_end)) {
+ goto error;
+ }
+ pos = start3 + 1;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ style_nseg__value = read_uint8(pos);
+ data_attr_u2__array__nelements = style_nseg__value;
+
+ data_attr_u2__array__nw_size = (4) * data_attr_u2__array__nelements;
+ data_attr_u2__array__mem_size = sizeof(SPICE_FIXED28_4) * data_attr_u2__array__nelements;
+ if (SPICE_UNLIKELY(message_start + data_attr_u2_style__value + data_attr_u2__array__nw_size > message_end)) {
+ goto error;
+ }
+ data_attr_u2__extra_size = data_attr_u2__array__mem_size + /* for alignment */ 3;
+ } else {
+ data_attr_u2__nw_size = 0;
+ data_attr_u2__extra_size = 0;
+ }
+
+ }
+
+ data_attr__nw_size = 1 + data_attr_u1__nw_size + data_attr_u2__nw_size;
+ data_attr__extra_size = data_attr_u2__extra_size;
+ }
+
+ { /* brush */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 4 + data_attr__nw_size);
+ size_t data_brush_u__nw_size, data_brush_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_BRUSH_TYPE_SOLID) {
+ data_brush_u__nw_size = 4;
+ data_brush_u__extra_size = 0;
+ } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t data_brush_u_pat__extra_size;
+ { /* pat */
+ uint32_t pat__value;
+ pos = (start4 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ pat__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(pat__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_brush_u__nw_size = 12;
+ data_brush_u__extra_size = data_brush_u_pat__extra_size;
+ } else {
+ data_brush_u__nw_size = 0;
+ data_brush_u__extra_size = 0;
+ }
+
+ }
+
+ data_brush__nw_size = 1 + data_brush_u__nw_size;
+ data_brush__extra_size = data_brush_u__extra_size;
+ }
+
+ data__nw_size = 8 + data_attr__nw_size + data_brush__nw_size;
+ data__extra_size = data_path__extra_size + data_attr__extra_size + data_brush__extra_size;
+ }
+
+ nw_size = 0 + base__nw_size + data__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawStroke) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawStroke);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawStroke *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpicePath;
+ ptr_info[n_ptr].dest = (void **)&out->data.path;
+ n_ptr++;
+ /* attr */ {
+ out->data.attr.flags = consume_uint8(&in);
+ if ((out->data.attr.flags & SPICE_LINE_FLAGS_STYLED)) {
+ out->data.attr.style_nseg = consume_uint8(&in);
+ }
+ if ((out->data.attr.flags & SPICE_LINE_FLAGS_STYLED)) {
+ uint32_t style__array__nelements;
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_array_int32;
+ ptr_info[n_ptr].dest = (void **)&out->data.attr.style;
+ style__array__nelements = out->data.attr.style_nseg;
+ ptr_info[n_ptr].nelements = style__array__nelements;
+ n_ptr++;
+ }
+ }
+ /* brush */ {
+ out->data.brush.type = consume_uint8(&in);
+ if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ out->data.brush.u.color = consume_uint32(&in);
+ } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
+ n_ptr++;
+ /* pos */ {
+ out->data.brush.u.pattern.pos.x = consume_int32(&in);
+ out->data.brush.u.pattern.pos.y = consume_int32(&in);
+ }
+ }
+ }
+ out->data.fore_mode = consume_uint16(&in);
+ out->data.back_mode = consume_uint16(&in);
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static intptr_t validate_SpiceString(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *start = message_start + offset;
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ size_t mem_size, nw_size;
+ size_t u__nw_size, u__extra_size;
+ uint8_t flags__value;
+ uint32_t i;
+
+ if (offset == 0) {
+ return 0;
+ }
+
+ if (SPICE_UNLIKELY(start >= message_end)) {
+ goto error;
+ }
+
+ { /* u */
+ uint32_t u__mem_size;
+ uint32_t u__nelements;
+ pos = start + 2;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint8(pos);
+ if ((flags__value & SPICE_STRING_FLAGS_RASTER_A1)) {
+ uint16_t length__value;
+ uint8_t *start2 = (start + 3);
+ uint32_t u__element__nw_size;
+ uint32_t u__element__mem_size;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ length__value = read_uint16(pos);
+ u__nelements = length__value;
+
+ u__nw_size = 0;
+ u__mem_size = 0;
+ for (i = 0; i < u__nelements; i++) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = start2;
+ size_t u__element_data__nw_size, u__element_data__mem_size;
+ uint32_t u__element_data__nelements;
+ { /* data */
+ uint16_t width__value;
+ uint16_t height__value;
+ pos = start3 + 16;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ width__value = read_uint16(pos);
+ pos = start3 + 18;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ height__value = read_uint16(pos);
+ u__element_data__nelements = ((width__value + 7) / 8 ) * height__value;
+
+ u__element_data__nw_size = u__element_data__nelements;
+ u__element_data__mem_size = sizeof(uint8_t) * u__element_data__nelements;
+ }
+
+ u__element__nw_size = 20 + u__element_data__nw_size;
+ u__element__mem_size = sizeof(SpiceRasterGlyph) + u__element_data__mem_size;
+ u__nw_size += u__element__nw_size;
+ u__mem_size += sizeof(void *) + SPICE_ALIGN(u__element__mem_size, 4);
+ start2 += u__element__nw_size;
+ }
+ u__extra_size = u__mem_size;
+ } else if ((flags__value & SPICE_STRING_FLAGS_RASTER_A4)) {
+ uint16_t length__value;
+ uint8_t *start2 = (start + 3);
+ uint32_t u__element__nw_size;
+ uint32_t u__element__mem_size;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ length__value = read_uint16(pos);
+ u__nelements = length__value;
+
+ u__nw_size = 0;
+ u__mem_size = 0;
+ for (i = 0; i < u__nelements; i++) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = start2;
+ size_t u__element_data__nw_size, u__element_data__mem_size;
+ uint32_t u__element_data__nelements;
+ { /* data */
+ uint16_t width__value;
+ uint16_t height__value;
+ pos = start3 + 16;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ width__value = read_uint16(pos);
+ pos = start3 + 18;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ height__value = read_uint16(pos);
+ u__element_data__nelements = ((4 * width__value + 7) / 8 ) * height__value;
+
+ u__element_data__nw_size = u__element_data__nelements;
+ u__element_data__mem_size = sizeof(uint8_t) * u__element_data__nelements;
+ }
+
+ u__element__nw_size = 20 + u__element_data__nw_size;
+ u__element__mem_size = sizeof(SpiceRasterGlyph) + u__element_data__mem_size;
+ u__nw_size += u__element__nw_size;
+ u__mem_size += sizeof(void *) + SPICE_ALIGN(u__element__mem_size, 4);
+ start2 += u__element__nw_size;
+ }
+ u__extra_size = u__mem_size;
+ } else if ((flags__value & SPICE_STRING_FLAGS_RASTER_A8)) {
+ uint16_t length__value;
+ uint8_t *start2 = (start + 3);
+ uint32_t u__element__nw_size;
+ uint32_t u__element__mem_size;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ length__value = read_uint16(pos);
+ u__nelements = length__value;
+
+ u__nw_size = 0;
+ u__mem_size = 0;
+ for (i = 0; i < u__nelements; i++) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = start2;
+ size_t u__element_data__nw_size, u__element_data__mem_size;
+ uint32_t u__element_data__nelements;
+ { /* data */
+ uint16_t width__value;
+ uint16_t height__value;
+ pos = start3 + 16;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ width__value = read_uint16(pos);
+ pos = start3 + 18;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ height__value = read_uint16(pos);
+ u__element_data__nelements = width__value * height__value;
+
+ u__element_data__nw_size = u__element_data__nelements;
+ u__element_data__mem_size = sizeof(uint8_t) * u__element_data__nelements;
+ }
+
+ u__element__nw_size = 20 + u__element_data__nw_size;
+ u__element__mem_size = sizeof(SpiceRasterGlyph) + u__element_data__mem_size;
+ u__nw_size += u__element__nw_size;
+ u__mem_size += sizeof(void *) + SPICE_ALIGN(u__element__mem_size, 4);
+ start2 += u__element__nw_size;
+ }
+ u__extra_size = u__mem_size;
+ } else {
+ u__nw_size = 0;
+ u__extra_size = 0;
+ }
+
+ }
+
+ nw_size = 3 + u__nw_size;
+ mem_size = sizeof(SpiceString) + u__extra_size;
+
+ /* Check if struct fits in reported side */
+ if (SPICE_UNLIKELY(start + nw_size > message_end)) {
+ goto error;
+ }
+ return mem_size;
+
+ error:
+ return -1;
+}
+
+static uint8_t * parse_struct_SpiceString(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+ SpiceString *out;
+ uint32_t i;
+
+ end = struct_data + sizeof(SpiceString);
+ out = (SpiceString *)struct_data;
+
+ out->length = consume_uint16(&in);
+ out->flags = consume_uint8(&in);
+ if ((out->flags & SPICE_STRING_FLAGS_RASTER_A1)) {
+ uint32_t glyphs__nelements;
+ void * *ptr_array;
+ int ptr_array_index;
+ glyphs__nelements = out->length;
+ ptr_array_index = 0;
+ ptr_array = (void **)out->glyphs;
+ end += sizeof(void *) * glyphs__nelements;
+ for (i = 0; i < glyphs__nelements; i++) {
+ SpiceRasterGlyph *out2;
+ uint32_t data__nelements;
+ ptr_array[ptr_array_index++] = end;
+ out2 = (SpiceRasterGlyph *)end;
+ end += sizeof(SpiceRasterGlyph);
+
+ /* render_pos */ {
+ out2->render_pos.x = consume_int32(&in);
+ out2->render_pos.y = consume_int32(&in);
+ }
+ /* glyph_origin */ {
+ out2->glyph_origin.x = consume_int32(&in);
+ out2->glyph_origin.y = consume_int32(&in);
+ }
+ out2->width = consume_uint16(&in);
+ out2->height = consume_uint16(&in);
+ data__nelements = ((out2->width + 7) / 8 ) * out2->height;
+ memcpy(out2->data, in, data__nelements);
+ in += data__nelements;
+ end += data__nelements;
+ /* Align ptr_array element to 4 bytes */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ }
+ } else if ((out->flags & SPICE_STRING_FLAGS_RASTER_A4)) {
+ uint32_t glyphs__nelements;
+ void * *ptr_array;
+ int ptr_array_index;
+ glyphs__nelements = out->length;
+ ptr_array_index = 0;
+ ptr_array = (void **)out->glyphs;
+ end += sizeof(void *) * glyphs__nelements;
+ for (i = 0; i < glyphs__nelements; i++) {
+ SpiceRasterGlyph *out2;
+ uint32_t data__nelements;
+ ptr_array[ptr_array_index++] = end;
+ out2 = (SpiceRasterGlyph *)end;
+ end += sizeof(SpiceRasterGlyph);
+
+ /* render_pos */ {
+ out2->render_pos.x = consume_int32(&in);
+ out2->render_pos.y = consume_int32(&in);
+ }
+ /* glyph_origin */ {
+ out2->glyph_origin.x = consume_int32(&in);
+ out2->glyph_origin.y = consume_int32(&in);
+ }
+ out2->width = consume_uint16(&in);
+ out2->height = consume_uint16(&in);
+ data__nelements = ((4 * out2->width + 7) / 8 ) * out2->height;
+ memcpy(out2->data, in, data__nelements);
+ in += data__nelements;
+ end += data__nelements;
+ /* Align ptr_array element to 4 bytes */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ }
+ } else if ((out->flags & SPICE_STRING_FLAGS_RASTER_A8)) {
+ uint32_t glyphs__nelements;
+ void * *ptr_array;
+ int ptr_array_index;
+ glyphs__nelements = out->length;
+ ptr_array_index = 0;
+ ptr_array = (void **)out->glyphs;
+ end += sizeof(void *) * glyphs__nelements;
+ for (i = 0; i < glyphs__nelements; i++) {
+ SpiceRasterGlyph *out2;
+ uint32_t data__nelements;
+ ptr_array[ptr_array_index++] = end;
+ out2 = (SpiceRasterGlyph *)end;
+ end += sizeof(SpiceRasterGlyph);
+
+ /* render_pos */ {
+ out2->render_pos.x = consume_int32(&in);
+ out2->render_pos.y = consume_int32(&in);
+ }
+ /* glyph_origin */ {
+ out2->glyph_origin.x = consume_int32(&in);
+ out2->glyph_origin.y = consume_int32(&in);
+ }
+ out2->width = consume_uint16(&in);
+ out2->height = consume_uint16(&in);
+ data__nelements = out2->width * out2->height;
+ memcpy(out2->data, in, data__nelements);
+ in += data__nelements;
+ end += data__nelements;
+ /* Align ptr_array element to 4 bytes */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ }
+ }
+ return end;
+}
+
+static uint8_t * parse_msg_display_draw_text(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[4];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__nw_size, data__extra_size;
+ SpiceMsgDisplayDrawText *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_str__extra_size;
+ size_t data_fore_brush__nw_size, data_fore_brush__extra_size;
+ size_t data_back_brush__nw_size, data_back_brush__extra_size;
+ { /* str */
+ uint32_t str__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ str__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(str__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceString(message_start, message_end, str__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_str__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* fore_brush */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t data_fore_brush_u__nw_size, data_fore_brush_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_BRUSH_TYPE_SOLID) {
+ data_fore_brush_u__nw_size = 4;
+ data_fore_brush_u__extra_size = 0;
+ } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t data_fore_brush_u_pat__extra_size;
+ { /* pat */
+ uint32_t pat__value;
+ pos = (start4 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ pat__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(pat__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_fore_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_fore_brush_u__nw_size = 12;
+ data_fore_brush_u__extra_size = data_fore_brush_u_pat__extra_size;
+ } else {
+ data_fore_brush_u__nw_size = 0;
+ data_fore_brush_u__extra_size = 0;
+ }
+
+ }
+
+ data_fore_brush__nw_size = 1 + data_fore_brush_u__nw_size;
+ data_fore_brush__extra_size = data_fore_brush_u__extra_size;
+ }
+
+ { /* back_brush */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20 + data_fore_brush__nw_size);
+ size_t data_back_brush_u__nw_size, data_back_brush_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_BRUSH_TYPE_SOLID) {
+ data_back_brush_u__nw_size = 4;
+ data_back_brush_u__extra_size = 0;
+ } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t data_back_brush_u_pat__extra_size;
+ { /* pat */
+ uint32_t pat__value;
+ pos = (start4 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ pat__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(pat__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_back_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_back_brush_u__nw_size = 12;
+ data_back_brush_u__extra_size = data_back_brush_u_pat__extra_size;
+ } else {
+ data_back_brush_u__nw_size = 0;
+ data_back_brush_u__extra_size = 0;
+ }
+
+ }
+
+ data_back_brush__nw_size = 1 + data_back_brush_u__nw_size;
+ data_back_brush__extra_size = data_back_brush_u__extra_size;
+ }
+
+ data__nw_size = 24 + data_fore_brush__nw_size + data_back_brush__nw_size;
+ data__extra_size = data_str__extra_size + data_fore_brush__extra_size + data_back_brush__extra_size;
+ }
+
+ nw_size = 0 + base__nw_size + data__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawText) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawText);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawText *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceString;
+ ptr_info[n_ptr].dest = (void **)&out->data.str;
+ n_ptr++;
+ /* back_area */ {
+ out->data.back_area.top = consume_int32(&in);
+ out->data.back_area.left = consume_int32(&in);
+ out->data.back_area.bottom = consume_int32(&in);
+ out->data.back_area.right = consume_int32(&in);
+ }
+ /* fore_brush */ {
+ out->data.fore_brush.type = consume_uint8(&in);
+ if (out->data.fore_brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ out->data.fore_brush.u.color = consume_uint32(&in);
+ } else if (out->data.fore_brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.fore_brush.u.pattern.pat;
+ n_ptr++;
+ /* pos */ {
+ out->data.fore_brush.u.pattern.pos.x = consume_int32(&in);
+ out->data.fore_brush.u.pattern.pos.y = consume_int32(&in);
+ }
+ }
+ }
+ /* back_brush */ {
+ out->data.back_brush.type = consume_uint8(&in);
+ if (out->data.back_brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ out->data.back_brush.u.color = consume_uint32(&in);
+ } else if (out->data.back_brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.back_brush.u.pattern.pat;
+ n_ptr++;
+ /* pos */ {
+ out->data.back_brush.u.pattern.pos.x = consume_int32(&in);
+ out->data.back_brush.u.pattern.pos.y = consume_int32(&in);
+ }
+ }
+ }
+ out->data.fore_mode = consume_uint16(&in);
+ out->data.back_mode = consume_uint16(&in);
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_transparent(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawTransparent *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_src_bitmap__extra_size;
+ { /* src_bitmap */
+ uint32_t src_bitmap__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data__extra_size = data_src_bitmap__extra_size;
+ }
+
+ nw_size = 28 + base__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawTransparent) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawTransparent);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawTransparent *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ /* src_area */ {
+ out->data.src_area.top = consume_int32(&in);
+ out->data.src_area.left = consume_int32(&in);
+ out->data.src_area.bottom = consume_int32(&in);
+ out->data.src_area.right = consume_int32(&in);
+ }
+ out->data.src_color = consume_uint32(&in);
+ out->data.true_color = consume_uint32(&in);
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_alpha_blend(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawAlphaBlend *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_src_bitmap__extra_size;
+ { /* src_bitmap */
+ uint32_t src_bitmap__value;
+ pos = (start2 + 2);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data__extra_size = data_src_bitmap__extra_size;
+ }
+
+ nw_size = 22 + base__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawAlphaBlend) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawAlphaBlend);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawAlphaBlend *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ out->data.alpha_flags = consume_uint8(&in);
+ out->data.alpha = consume_uint8(&in);
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ /* src_area */ {
+ out->data.src_area.top = consume_int32(&in);
+ out->data.src_area.left = consume_int32(&in);
+ out->data.src_area.bottom = consume_int32(&in);
+ out->data.src_area.right = consume_int32(&in);
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_surface_create(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgSurfaceCreate *out;
+
+ nw_size = 20;
+ mem_size = sizeof(SpiceMsgSurfaceCreate);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgSurfaceCreate);
+ in = start;
+
+ out = (SpiceMsgSurfaceCreate *)data;
+
+ out->surface_id = consume_uint32(&in);
+ out->width = consume_uint32(&in);
+ out->height = consume_uint32(&in);
+ out->format = consume_uint32(&in);
+ out->flags = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_surface_destroy(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgSurfaceDestroy *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgSurfaceDestroy);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgSurfaceDestroy);
+ in = start;
+
+ out = (SpiceMsgSurfaceDestroy *)data;
+
+ out->surface_id = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_stream_data_sized(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size, data__mem_size;
+ uint32_t data__nelements;
+ SpiceMsgDisplayStreamDataSized *out;
+
+ { /* data */
+ uint32_t data_size__value;
+ pos = start + 32;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ data__nelements = data_size__value;
+
+ data__nw_size = data__nelements;
+ data__mem_size = sizeof(uint8_t) * data__nelements;
+ }
+
+ nw_size = 36 + data__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayStreamDataSized) + data__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayStreamDataSized);
+ in = start;
+
+ out = (SpiceMsgDisplayStreamDataSized *)data;
+
+ /* base */ {
+ out->base.id = consume_uint32(&in);
+ out->base.multi_media_time = consume_uint32(&in);
+ }
+ out->width = consume_uint32(&in);
+ out->height = consume_uint32(&in);
+ /* dest */ {
+ out->dest.top = consume_int32(&in);
+ out->dest.left = consume_int32(&in);
+ out->dest.bottom = consume_int32(&in);
+ out->dest.right = consume_int32(&in);
+ }
+ out->data_size = consume_uint32(&in);
+ memcpy(out->data, in, data__nelements);
+ in += data__nelements;
+ end += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_monitors_config(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t heads__nw_size, heads__mem_size;
+ uint32_t heads__nelements;
+ SpiceMsgDisplayMonitorsConfig *out;
+ uint32_t i;
+
+ { /* heads */
+ uint16_t count__value;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ count__value = read_uint16(pos);
+ heads__nelements = count__value;
+
+ heads__nw_size = (28) * heads__nelements;
+ heads__mem_size = sizeof(SpiceHead) * heads__nelements;
+ }
+
+ nw_size = 4 + heads__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayMonitorsConfig) + heads__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayMonitorsConfig);
+ in = start;
+
+ out = (SpiceMsgDisplayMonitorsConfig *)data;
+
+ out->count = consume_uint16(&in);
+ out->max_allowed = consume_uint16(&in);
+ for (i = 0; i < heads__nelements; i++) {
+ SpiceHead *out2;
+ out2 = (SpiceHead *)end;
+ end += sizeof(SpiceHead);
+
+ out2->id = consume_uint32(&in);
+ out2->surface_id = consume_uint32(&in);
+ out2->width = consume_uint32(&in);
+ out2->height = consume_uint32(&in);
+ out2->x = consume_uint32(&in);
+ out2->y = consume_uint32(&in);
+ out2->flags = consume_uint32(&in);
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_composite(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[3];
+ size_t base__nw_size, base__extra_size;
+ uint32_t rects__saved_size = 0;
+ size_t data__nw_size, data__extra_size;
+ SpiceMsgDisplayDrawComposite *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__nw_size, base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 20);
+ size_t base_clip_u__nw_size, base_clip_u__extra_size;
+ uint8_t type__value;
+ { /* u */
+ uint32_t base_clip_u__mem_size;
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 1);
+ size_t base_clip_u_rects__nw_size, base_clip_u_rects__mem_size;
+ uint32_t base_clip_u_rects__nelements;
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start4 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ base_clip_u_rects__nelements = num_rects__value;
+
+ base_clip_u_rects__nw_size = (16) * base_clip_u_rects__nelements;
+ base_clip_u_rects__mem_size = sizeof(SpiceRect) * base_clip_u_rects__nelements;
+ }
+
+ base_clip_u__nw_size = 4 + base_clip_u_rects__nw_size;
+ base_clip_u__mem_size = sizeof(SpiceClipRects) + base_clip_u_rects__mem_size;
+ rects__saved_size = base_clip_u__nw_size;
+ base_clip_u__extra_size = base_clip_u__mem_size;
+ } else {
+ base_clip_u__nw_size = 0;
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__nw_size = 1 + base_clip_u__nw_size;
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__nw_size = 20 + base_clip__nw_size;
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0 + base__nw_size);
+ size_t data_src_bitmap__extra_size;
+ size_t data_a__nw_size, data_a__extra_size;
+ uint32_t flags__value;
+ size_t data_b__nw_size;
+ size_t data_c__nw_size;
+ { /* src_bitmap */
+ uint32_t src_bitmap__value;
+ pos = (start2 + 4);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* a */
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint32(pos);
+ if ((flags__value & SPICE_COMPOSITE_HAS_MASK)) {
+ uint32_t data_a_mask_bitmap__value;
+ data_a__nw_size = 4;
+ pos = (start2 + 8);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_a_mask_bitmap__value = read_uint32(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, data_a_mask_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_a__extra_size = ptr_size + /* for alignment */ 3;
+ } else {
+ data_a__nw_size = 0;
+ data_a__extra_size = 0;
+ }
+
+ }
+
+ { /* b */
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint32(pos);
+ if ((flags__value & SPICE_COMPOSITE_HAS_SRC_TRANSFORM)) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 8 + data_a__nw_size);
+ data_b__nw_size = 24;
+ } else {
+ data_b__nw_size = 0;
+ }
+
+ }
+
+ { /* c */
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint32(pos);
+ if ((flags__value & SPICE_COMPOSITE_HAS_MASK_TRANSFORM)) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 8 + data_a__nw_size + data_b__nw_size);
+ data_c__nw_size = 24;
+ } else {
+ data_c__nw_size = 0;
+ }
+
+ }
+
+ data__nw_size = 16 + data_a__nw_size + data_b__nw_size + data_c__nw_size;
+ data__extra_size = data_src_bitmap__extra_size + data_a__extra_size;
+ }
+
+ nw_size = 0 + base__nw_size + data__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayDrawComposite) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawComposite);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawComposite *)data;
+
+ /* base */ {
+ out->base.surface_id = consume_uint32(&in);
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint8(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = in - start;
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ in += rects__saved_size;
+ }
+ }
+ }
+ /* data */ {
+ out->data.flags = consume_uint32(&in);
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ if ((out->data.flags & SPICE_COMPOSITE_HAS_MASK)) {
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask_bitmap;
+ n_ptr++;
+ }
+ if ((out->data.flags & SPICE_COMPOSITE_HAS_SRC_TRANSFORM)) {
+ out->data.src_transform.t00 = consume_uint32(&in);
+ out->data.src_transform.t01 = consume_uint32(&in);
+ out->data.src_transform.t02 = consume_uint32(&in);
+ out->data.src_transform.t10 = consume_uint32(&in);
+ out->data.src_transform.t11 = consume_uint32(&in);
+ out->data.src_transform.t12 = consume_uint32(&in);
+ }
+ if ((out->data.flags & SPICE_COMPOSITE_HAS_MASK_TRANSFORM)) {
+ out->data.mask_transform.t00 = consume_uint32(&in);
+ out->data.mask_transform.t01 = consume_uint32(&in);
+ out->data.mask_transform.t02 = consume_uint32(&in);
+ out->data.mask_transform.t10 = consume_uint32(&in);
+ out->data.mask_transform.t11 = consume_uint32(&in);
+ out->data.mask_transform.t12 = consume_uint32(&in);
+ }
+ /* src_origin */ {
+ out->data.src_origin.x = consume_int16(&in);
+ out->data.src_origin.y = consume_int16(&in);
+ }
+ /* mask_origin */ {
+ out->data.mask_origin.x = consume_int16(&in);
+ out->data.mask_origin.y = consume_int16(&in);
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_stream_activate_report(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisplayStreamActivateReport *out;
+
+ nw_size = 16;
+ mem_size = sizeof(SpiceMsgDisplayStreamActivateReport);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayStreamActivateReport);
+ in = start;
+
+ out = (SpiceMsgDisplayStreamActivateReport *)data;
+
+ out->stream_id = consume_uint32(&in);
+ out->unique_id = consume_uint32(&in);
+ out->max_window_size = consume_uint32(&in);
+ out->timeout_ms = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_gl_scanout_unix(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisplayGlScanoutUnix *out;
+
+ nw_size = 20;
+ mem_size = sizeof(SpiceMsgDisplayGlScanoutUnix);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayGlScanoutUnix);
+ in = start;
+
+ out = (SpiceMsgDisplayGlScanoutUnix *)data;
+
+ out->drm_dma_buf_fd = consume_fd(&in);
+ out->width = consume_uint32(&in);
+ out->height = consume_uint32(&in);
+ out->stride = consume_uint32(&in);
+ out->drm_fourcc_format = consume_uint32(&in);
+ out->flags = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_gl_draw(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisplayGlDraw *out;
+
+ nw_size = 16;
+ mem_size = sizeof(SpiceMsgDisplayGlDraw);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayGlDraw);
+ in = start;
+
+ out = (SpiceMsgDisplayGlDraw *)data;
+
+ out->x = consume_uint32(&in);
+ out->y = consume_uint32(&in);
+ out->w = consume_uint32(&in);
+ out->h = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_DisplayChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[8] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify,
+ parse_SpiceMsgData
+ };
+ static parse_msg_func_t funcs2[9] = {
+ parse_SpiceMsgEmpty,
+ parse_msg_display_mode,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgEmpty,
+ parse_msg_display_copy_bits,
+ parse_msg_display_inval_list,
+ parse_msg_display_inval_all_pixmaps,
+ parse_msg_display_inval_palette,
+ parse_SpiceMsgEmpty
+ };
+ static parse_msg_func_t funcs3[5] = {
+ parse_msg_display_stream_create,
+ parse_msg_display_stream_data,
+ parse_msg_display_stream_clip,
+ parse_msg_display_stream_destroy,
+ parse_SpiceMsgEmpty
+ };
+ static parse_msg_func_t funcs4[20] = {
+ parse_msg_display_draw_fill,
+ parse_msg_display_draw_opaque,
+ parse_msg_display_draw_copy,
+ parse_msg_display_draw_blend,
+ parse_msg_display_draw_blackness,
+ parse_msg_display_draw_whiteness,
+ parse_msg_display_draw_invers,
+ parse_msg_display_draw_rop3,
+ parse_msg_display_draw_stroke,
+ parse_msg_display_draw_text,
+ parse_msg_display_draw_transparent,
+ parse_msg_display_draw_alpha_blend,
+ parse_msg_display_surface_create,
+ parse_msg_display_surface_destroy,
+ parse_msg_display_stream_data_sized,
+ parse_msg_display_monitors_config,
+ parse_msg_display_draw_composite,
+ parse_msg_display_stream_activate_report,
+ parse_msg_display_gl_scanout_unix,
+ parse_msg_display_gl_draw
+ };
+ if (message_type >= 1 && message_type < 9) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 100 && message_type < 109) {
+ return funcs2[message_type-100](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 122 && message_type < 127) {
+ return funcs3[message_type-122](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 302 && message_type < 322) {
+ return funcs4[message_type-302](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msg_inputs_init(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgInputsInit *out;
+
+ nw_size = 2;
+ mem_size = sizeof(SpiceMsgInputsInit);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgInputsInit);
+ in = start;
+
+ out = (SpiceMsgInputsInit *)data;
+
+ out->keyboard_modifiers = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_inputs_key_modifiers(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgInputsKeyModifiers *out;
+
+ nw_size = 2;
+ mem_size = sizeof(SpiceMsgInputsKeyModifiers);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgInputsKeyModifiers);
+ in = start;
+
+ out = (SpiceMsgInputsKeyModifiers *)data;
+
+ out->modifiers = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_InputsChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[8] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify,
+ parse_SpiceMsgData
+ };
+ static parse_msg_func_t funcs2[3] = {
+ parse_SpiceMsgEmpty,
+ parse_msg_inputs_init,
+ parse_msg_inputs_key_modifiers
+ };
+ static parse_msg_func_t funcs3[1] = {
+ parse_SpiceMsgEmpty
+ };
+ if (message_type >= 1 && message_type < 9) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 100 && message_type < 103) {
+ return funcs2[message_type-100](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 111 && message_type < 112) {
+ return funcs3[message_type-111](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msg_cursor_init(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t cursor__nw_size;
+ SpiceMsgCursorInit *out;
+
+ { /* cursor */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 9);
+ size_t cursor_u__nw_size;
+ uint16_t flags__value;
+ size_t cursor_data__nw_size;
+ uint32_t cursor_data__nelements;
+ { /* u */
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint16(pos);
+ if (!(flags__value & SPICE_CURSOR_FLAGS_NONE)) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 2);
+ cursor_u__nw_size = 17;
+ } else {
+ cursor_u__nw_size = 0;
+ }
+
+ }
+
+ { /* data */
+ cursor_data__nelements = message_end - (start2 + 2 + cursor_u__nw_size);
+
+ cursor_data__nw_size = cursor_data__nelements;
+ }
+
+ cursor__nw_size = 2 + cursor_u__nw_size + cursor_data__nw_size;
+ }
+
+ nw_size = 9 + cursor__nw_size;
+ mem_size = sizeof(SpiceMsgCursorInit);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgCursorInit);
+ in = start;
+
+ out = (SpiceMsgCursorInit *)data;
+
+ /* position */ {
+ out->position.x = consume_int16(&in);
+ out->position.y = consume_int16(&in);
+ }
+ out->trail_length = consume_uint16(&in);
+ out->trail_frequency = consume_uint16(&in);
+ out->visible = consume_uint8(&in);
+ /* cursor */ {
+ uint32_t data__nelements;
+ out->cursor.flags = consume_uint16(&in);
+ if (!(out->cursor.flags & SPICE_CURSOR_FLAGS_NONE)) {
+ out->cursor.header.unique = consume_uint64(&in);
+ out->cursor.header.type = consume_uint8(&in);
+ out->cursor.header.width = consume_uint16(&in);
+ out->cursor.header.height = consume_uint16(&in);
+ out->cursor.header.hot_spot_x = consume_uint16(&in);
+ out->cursor.header.hot_spot_y = consume_uint16(&in);
+ }
+ data__nelements = (message_end - in) / (1);
+ /* use array as pointer */
+ out->cursor.data = (uint8_t *)in;
+ out->cursor.data_size = data__nelements;
+ in += data__nelements;
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_cursor_set(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t cursor__nw_size;
+ SpiceMsgCursorSet *out;
+
+ { /* cursor */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 5);
+ size_t cursor_u__nw_size;
+ uint16_t flags__value;
+ size_t cursor_data__nw_size;
+ uint32_t cursor_data__nelements;
+ { /* u */
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint16(pos);
+ if (!(flags__value & SPICE_CURSOR_FLAGS_NONE)) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 2);
+ cursor_u__nw_size = 17;
+ } else {
+ cursor_u__nw_size = 0;
+ }
+
+ }
+
+ { /* data */
+ cursor_data__nelements = message_end - (start2 + 2 + cursor_u__nw_size);
+
+ cursor_data__nw_size = cursor_data__nelements;
+ }
+
+ cursor__nw_size = 2 + cursor_u__nw_size + cursor_data__nw_size;
+ }
+
+ nw_size = 5 + cursor__nw_size;
+ mem_size = sizeof(SpiceMsgCursorSet);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgCursorSet);
+ in = start;
+
+ out = (SpiceMsgCursorSet *)data;
+
+ /* position */ {
+ out->position.x = consume_int16(&in);
+ out->position.y = consume_int16(&in);
+ }
+ out->visible = consume_uint8(&in);
+ /* cursor */ {
+ uint32_t data__nelements;
+ out->cursor.flags = consume_uint16(&in);
+ if (!(out->cursor.flags & SPICE_CURSOR_FLAGS_NONE)) {
+ out->cursor.header.unique = consume_uint64(&in);
+ out->cursor.header.type = consume_uint8(&in);
+ out->cursor.header.width = consume_uint16(&in);
+ out->cursor.header.height = consume_uint16(&in);
+ out->cursor.header.hot_spot_x = consume_uint16(&in);
+ out->cursor.header.hot_spot_y = consume_uint16(&in);
+ }
+ data__nelements = (message_end - in) / (1);
+ /* use array as pointer */
+ out->cursor.data = (uint8_t *)in;
+ out->cursor.data_size = data__nelements;
+ in += data__nelements;
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_cursor_move(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgCursorMove *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgCursorMove);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgCursorMove);
+ in = start;
+
+ out = (SpiceMsgCursorMove *)data;
+
+ /* position */ {
+ out->position.x = consume_int16(&in);
+ out->position.y = consume_int16(&in);
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_cursor_trail(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgCursorTrail *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgCursorTrail);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgCursorTrail);
+ in = start;
+
+ out = (SpiceMsgCursorTrail *)data;
+
+ out->length = consume_uint16(&in);
+ out->frequency = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_cursor_inval_one(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisplayInvalOne *out;
+
+ nw_size = 8;
+ mem_size = sizeof(SpiceMsgDisplayInvalOne);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayInvalOne);
+ in = start;
+
+ out = (SpiceMsgDisplayInvalOne *)data;
+
+ out->id = consume_uint64(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_CursorChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[8] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify,
+ parse_SpiceMsgData
+ };
+ static parse_msg_func_t funcs2[9] = {
+ parse_SpiceMsgEmpty,
+ parse_msg_cursor_init,
+ parse_SpiceMsgEmpty,
+ parse_msg_cursor_set,
+ parse_msg_cursor_move,
+ parse_SpiceMsgEmpty,
+ parse_msg_cursor_trail,
+ parse_msg_cursor_inval_one,
+ parse_SpiceMsgEmpty
+ };
+ if (message_type >= 1 && message_type < 9) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 100 && message_type < 109) {
+ return funcs2[message_type-100](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msg_playback_data(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size;
+ uint32_t data__nelements;
+ SpiceMsgPlaybackPacket *out;
+
+ { /* data */
+ data__nelements = message_end - (start + 4);
+
+ data__nw_size = data__nelements;
+ }
+
+ nw_size = 4 + data__nw_size;
+ mem_size = sizeof(SpiceMsgPlaybackPacket);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgPlaybackPacket);
+ in = start;
+
+ out = (SpiceMsgPlaybackPacket *)data;
+
+ out->time = consume_uint32(&in);
+ /* use array as pointer */
+ out->data = (uint8_t *)in;
+ out->data_size = data__nelements;
+ in += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_playback_mode(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size;
+ uint32_t data__nelements;
+ SpiceMsgPlaybackMode *out;
+
+ { /* data */
+ data__nelements = message_end - (start + 6);
+
+ data__nw_size = data__nelements;
+ }
+
+ nw_size = 6 + data__nw_size;
+ mem_size = sizeof(SpiceMsgPlaybackMode);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgPlaybackMode);
+ in = start;
+
+ out = (SpiceMsgPlaybackMode *)data;
+
+ out->time = consume_uint32(&in);
+ out->mode = consume_uint16(&in);
+ /* use array as pointer */
+ out->data = (uint8_t *)in;
+ out->data_size = data__nelements;
+ in += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_playback_start(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgPlaybackStart *out;
+
+ nw_size = 14;
+ mem_size = sizeof(SpiceMsgPlaybackStart);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgPlaybackStart);
+ in = start;
+
+ out = (SpiceMsgPlaybackStart *)data;
+
+ out->channels = consume_uint32(&in);
+ out->format = consume_uint16(&in);
+ out->frequency = consume_uint32(&in);
+ out->time = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_SpiceMsgAudioVolume(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t volume__nw_size, volume__mem_size;
+ uint32_t volume__nelements;
+ SpiceMsgAudioVolume *out;
+ uint32_t i;
+
+ { /* volume */
+ uint8_t nchannels__value;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ nchannels__value = read_uint8(pos);
+ volume__nelements = nchannels__value;
+
+ volume__nw_size = (2) * volume__nelements;
+ volume__mem_size = sizeof(uint16_t) * volume__nelements;
+ }
+
+ nw_size = 1 + volume__nw_size;
+ mem_size = sizeof(SpiceMsgAudioVolume) + volume__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgAudioVolume);
+ in = start;
+
+ out = (SpiceMsgAudioVolume *)data;
+
+ out->nchannels = consume_uint8(&in);
+ for (i = 0; i < volume__nelements; i++) {
+ out->volume[i] = consume_uint16(&in);
+ end += sizeof(uint16_t);
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_SpiceMsgAudioMute(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgAudioMute *out;
+
+ nw_size = 1;
+ mem_size = sizeof(SpiceMsgAudioMute);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgAudioMute);
+ in = start;
+
+ out = (SpiceMsgAudioMute *)data;
+
+ out->mute = consume_uint8(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_playback_latency(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgPlaybackLatency *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgPlaybackLatency);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgPlaybackLatency);
+ in = start;
+
+ out = (SpiceMsgPlaybackLatency *)data;
+
+ out->latency_ms = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_PlaybackChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[8] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify,
+ parse_SpiceMsgData
+ };
+ static parse_msg_func_t funcs2[8] = {
+ parse_SpiceMsgEmpty,
+ parse_msg_playback_data,
+ parse_msg_playback_mode,
+ parse_msg_playback_start,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgAudioVolume,
+ parse_SpiceMsgAudioMute,
+ parse_msg_playback_latency
+ };
+ if (message_type >= 1 && message_type < 9) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 100 && message_type < 108) {
+ return funcs2[message_type-100](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msg_record_start(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgRecordStart *out;
+
+ nw_size = 10;
+ mem_size = sizeof(SpiceMsgRecordStart);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgRecordStart);
+ in = start;
+
+ out = (SpiceMsgRecordStart *)data;
+
+ out->channels = consume_uint32(&in);
+ out->format = consume_uint16(&in);
+ out->frequency = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_RecordChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[8] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify,
+ parse_SpiceMsgData
+ };
+ static parse_msg_func_t funcs2[5] = {
+ parse_SpiceMsgEmpty,
+ parse_msg_record_start,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgAudioVolume,
+ parse_SpiceMsgAudioMute
+ };
+ if (message_type >= 1 && message_type < 9) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 100 && message_type < 105) {
+ return funcs2[message_type-100](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msg_tunnel_init(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgTunnelInit *out;
+
+ nw_size = 6;
+ mem_size = sizeof(SpiceMsgTunnelInit);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgTunnelInit);
+ in = start;
+
+ out = (SpiceMsgTunnelInit *)data;
+
+ out->max_num_of_sockets = consume_uint16(&in);
+ out->max_socket_data_size = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_tunnel_service_ip_map(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t virtual_ip__nw_size;
+ SpiceMsgTunnelServiceIpMap *out;
+
+ { /* virtual_ip */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 4);
+ size_t virtual_ip_u__nw_size;
+ uint16_t type__value;
+ { /* u */
+ uint32_t virtual_ip_u__nelements;
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint16(pos);
+ if (type__value == SPICE_TUNNEL_IP_TYPE_IPv4) {
+ virtual_ip_u__nelements = 4;
+
+ virtual_ip_u__nw_size = virtual_ip_u__nelements;
+ } else {
+ virtual_ip_u__nw_size = 0;
+ }
+
+ }
+
+ virtual_ip__nw_size = 2 + virtual_ip_u__nw_size;
+ }
+
+ nw_size = 4 + virtual_ip__nw_size;
+ mem_size = sizeof(SpiceMsgTunnelServiceIpMap);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgTunnelServiceIpMap);
+ in = start;
+
+ out = (SpiceMsgTunnelServiceIpMap *)data;
+
+ out->service_id = consume_uint32(&in);
+ /* virtual_ip */ {
+ out->virtual_ip.type = consume_uint16(&in);
+ if (out->virtual_ip.type == SPICE_TUNNEL_IP_TYPE_IPv4) {
+ uint32_t ipv4__nelements;
+ ipv4__nelements = 4;
+ memcpy(out->virtual_ip.u.ipv4, in, ipv4__nelements);
+ in += ipv4__nelements;
+ }
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_tunnel_socket_open(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgTunnelSocketOpen *out;
+
+ nw_size = 10;
+ mem_size = sizeof(SpiceMsgTunnelSocketOpen);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgTunnelSocketOpen);
+ in = start;
+
+ out = (SpiceMsgTunnelSocketOpen *)data;
+
+ out->connection_id = consume_uint16(&in);
+ out->service_id = consume_uint32(&in);
+ out->tokens = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_tunnel_socket_fin(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgTunnelSocketFin *out;
+
+ nw_size = 2;
+ mem_size = sizeof(SpiceMsgTunnelSocketFin);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgTunnelSocketFin);
+ in = start;
+
+ out = (SpiceMsgTunnelSocketFin *)data;
+
+ out->connection_id = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_tunnel_socket_close(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgTunnelSocketClose *out;
+
+ nw_size = 2;
+ mem_size = sizeof(SpiceMsgTunnelSocketClose);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgTunnelSocketClose);
+ in = start;
+
+ out = (SpiceMsgTunnelSocketClose *)data;
+
+ out->connection_id = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_tunnel_socket_data(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size, data__mem_size;
+ uint32_t data__nelements;
+ SpiceMsgTunnelSocketData *out;
+
+ { /* data */
+ data__nelements = message_end - (start + 2);
+
+ data__nw_size = data__nelements;
+ data__mem_size = sizeof(uint8_t) * data__nelements;
+ }
+
+ nw_size = 2 + data__nw_size;
+ mem_size = sizeof(SpiceMsgTunnelSocketData) + data__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgTunnelSocketData);
+ in = start;
+
+ out = (SpiceMsgTunnelSocketData *)data;
+
+ out->connection_id = consume_uint16(&in);
+ memcpy(out->data, in, data__nelements);
+ in += data__nelements;
+ end += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_tunnel_socket_closed_ack(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgTunnelSocketClosedAck *out;
+
+ nw_size = 2;
+ mem_size = sizeof(SpiceMsgTunnelSocketClosedAck);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgTunnelSocketClosedAck);
+ in = start;
+
+ out = (SpiceMsgTunnelSocketClosedAck *)data;
+
+ out->connection_id = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_tunnel_socket_token(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgTunnelSocketTokens *out;
+
+ nw_size = 6;
+ mem_size = sizeof(SpiceMsgTunnelSocketTokens);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgTunnelSocketTokens);
+ in = start;
+
+ out = (SpiceMsgTunnelSocketTokens *)data;
+
+ out->connection_id = consume_uint16(&in);
+ out->num_tokens = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_TunnelChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[8] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify,
+ parse_SpiceMsgData
+ };
+ static parse_msg_func_t funcs2[9] = {
+ parse_SpiceMsgEmpty,
+ parse_msg_tunnel_init,
+ parse_msg_tunnel_service_ip_map,
+ parse_msg_tunnel_socket_open,
+ parse_msg_tunnel_socket_fin,
+ parse_msg_tunnel_socket_close,
+ parse_msg_tunnel_socket_data,
+ parse_msg_tunnel_socket_closed_ack,
+ parse_msg_tunnel_socket_token
+ };
+ if (message_type >= 1 && message_type < 9) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 100 && message_type < 109) {
+ return funcs2[message_type-100](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+#ifdef USE_SMARTCARD
+
+static uint8_t * parse_msg_smartcard_data(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size, data__mem_size;
+ uint32_t data__nelements;
+ SpiceMsgSmartcard *out;
+
+ { /* data */
+ uint32_t length__value;
+ pos = start + 8;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ length__value = read_uint32(pos);
+ data__nelements = length__value;
+
+ data__nw_size = data__nelements;
+ data__mem_size = sizeof(uint8_t) * data__nelements;
+ }
+
+ nw_size = 12 + data__nw_size;
+ mem_size = sizeof(SpiceMsgSmartcard) + data__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgSmartcard);
+ in = start;
+
+ out = (SpiceMsgSmartcard *)data;
+
+ out->type = consume_uint32(&in);
+ out->reader_id = consume_uint32(&in);
+ out->length = consume_uint32(&in);
+ memcpy(out->data, in, data__nelements);
+ in += data__nelements;
+ end += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_SmartcardChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[8] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify,
+ parse_SpiceMsgData
+ };
+ static parse_msg_func_t funcs2[2] = {
+ parse_SpiceMsgEmpty,
+ parse_msg_smartcard_data
+ };
+ if (message_type >= 1 && message_type < 9) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 100 && message_type < 102) {
+ return funcs2[message_type-100](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+#endif /* USE_SMARTCARD */
+
+
+
+static uint8_t * parse_SpiceMsgCompressedData(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t u__nw_size;
+ uint8_t type__value;
+ size_t compressed_data__nw_size;
+ uint32_t compressed_data__nelements;
+ SpiceMsgCompressedData *out;
+
+ { /* u */
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_DATA_COMPRESSION_TYPE_NONE) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 1);
+ u__nw_size = 0;
+ } else if (1) {
+ u__nw_size = 4;
+ } else {
+ u__nw_size = 0;
+ }
+
+ }
+
+ { /* compressed_data */
+ compressed_data__nelements = message_end - (start + 1 + u__nw_size);
+
+ compressed_data__nw_size = compressed_data__nelements;
+ }
+
+ nw_size = 1 + u__nw_size + compressed_data__nw_size;
+ mem_size = sizeof(SpiceMsgCompressedData);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgCompressedData);
+ in = start;
+
+ out = (SpiceMsgCompressedData *)data;
+
+ out->type = consume_uint8(&in);
+ if (out->type == SPICE_DATA_COMPRESSION_TYPE_NONE) {
+ } else if (1) {
+ out->uncompressed_size = consume_uint32(&in);
+ }
+ /* use array as pointer */
+ out->compressed_data = (uint8_t *)in;
+ out->compressed_size = compressed_data__nelements;
+ in += compressed_data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_UsbredirChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[8] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify,
+ parse_SpiceMsgData
+ };
+ static parse_msg_func_t funcs2[3] = {
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_SpiceMsgCompressedData
+ };
+ if (message_type >= 1 && message_type < 9) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 100 && message_type < 103) {
+ return funcs2[message_type-100](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msg_port_init(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[1];
+ size_t name__extra_size;
+ uint32_t name__array__nelements;
+ SpiceMsgPortInit *out;
+ uint32_t i;
+
+ { /* name */
+ uint32_t name__value;
+ uint32_t name__array__nw_size;
+ uint32_t name__array__mem_size;
+ uint32_t name_size__value;
+ pos = (start + 4);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ name__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(name__value == 0)) {
+ goto error;
+ }
+ if (SPICE_UNLIKELY(message_start + name__value >= message_end)) {
+ goto error;
+ }
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ name_size__value = read_uint32(pos);
+ name__array__nelements = name_size__value;
+
+ name__array__nw_size = name__array__nelements;
+ name__array__mem_size = sizeof(uint8_t) * name__array__nelements;
+ if (SPICE_UNLIKELY(message_start + name__value + name__array__nw_size > message_end)) {
+ goto error;
+ }
+ name__extra_size = name__array__mem_size + /* for alignment */ 3;
+ }
+
+ nw_size = 9;
+ mem_size = sizeof(SpiceMsgPortInit) + name__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgPortInit);
+ in = start;
+
+ out = (SpiceMsgPortInit *)data;
+
+ out->name_size = consume_uint32(&in);
+ ptr_info[n_ptr].offset = consume_uint32(&in);
+ ptr_info[n_ptr].parse = parse_array_uint8;
+ ptr_info[n_ptr].dest = (void **)&out->name;
+ ptr_info[n_ptr].nelements = name__array__nelements;
+ n_ptr++;
+ out->opened = consume_uint8(&in);
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_port_event(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgPortEvent *out;
+
+ nw_size = 1;
+ mem_size = sizeof(SpiceMsgPortEvent);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgPortEvent);
+ in = start;
+
+ out = (SpiceMsgPortEvent *)data;
+
+ out->event = consume_uint8(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_PortChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[8] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify,
+ parse_SpiceMsgData
+ };
+ static parse_msg_func_t funcs2[3] = {
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_SpiceMsgCompressedData
+ };
+ static parse_msg_func_t funcs3[2] = {
+ parse_msg_port_init,
+ parse_msg_port_event
+ };
+ if (message_type >= 1 && message_type < 9) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 100 && message_type < 103) {
+ return funcs2[message_type-100](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 201 && message_type < 203) {
+ return funcs3[message_type-201](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_WebDAVChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[8] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify,
+ parse_SpiceMsgData
+ };
+ static parse_msg_func_t funcs2[3] = {
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_SpiceMsgCompressedData
+ };
+ static parse_msg_func_t funcs3[2] = {
+ parse_msg_port_init,
+ parse_msg_port_event
+ };
+ if (message_type >= 1 && message_type < 9) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 100 && message_type < 103) {
+ return funcs2[message_type-100](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 201 && message_type < 203) {
+ return funcs3[message_type-201](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+spice_parse_channel_func_t spice_get_server_channel_parser(uint32_t channel, unsigned int *max_message_type)
+{
+ static struct {spice_parse_channel_func_t func; unsigned int max_messages; } channels[12] = {
+ { NULL, 0 },
+ { parse_MainChannel_msg, 118},
+ { parse_DisplayChannel_msg, 321},
+ { parse_InputsChannel_msg, 111},
+ { parse_CursorChannel_msg, 108},
+ { parse_PlaybackChannel_msg, 107},
+ { parse_RecordChannel_msg, 104},
+ { parse_TunnelChannel_msg, 108},
+#ifdef USE_SMARTCARD
+ { parse_SmartcardChannel_msg, 101},
+#else /* USE_SMARTCARD */
+ { NULL, 0 },
+#endif /* USE_SMARTCARD */
+ { parse_UsbredirChannel_msg, 102},
+ { parse_PortChannel_msg, 202},
+ { parse_WebDAVChannel_msg, 202}
+ };
+ if (channel < 12) {
+ if (max_message_type != NULL) {
+ *max_message_type = channels[channel].max_messages;
+ }
+ return channels[channel].func;
+ }
+ return NULL;
+}
+
+uint8_t * spice_parse_msg(uint8_t *message_start, uint8_t *message_end, uint32_t channel, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ spice_parse_channel_func_t func;
+ func = spice_get_server_channel_parser(channel, NULL);
+ if (func != NULL) {
+ return func(message_start, message_end, message_type, minor, size_out, free_message);
+ }
+ return NULL;
+}
--- /dev/null
+/* this is a file autogenerated by spice_codegen.py */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "common/messages.h"
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <spice/protocol.h>
+#include <spice/macros.h>
+#include <common/mem.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable:4101)
+#endif
+
+
+
+#ifdef WORDS_BIGENDIAN
+#define read_int8(ptr) (*((int8_t *)(ptr)))
+#define write_int8(ptr, val) *(int8_t *)(ptr) = val
+#define read_uint8(ptr) (*((uint8_t *)(ptr)))
+#define write_uint8(ptr, val) *(uint8_t *)(ptr) = val
+#define read_int16(ptr) ((int16_t)SPICE_BYTESWAP16(*((uint16_t *)(ptr))))
+#define write_int16(ptr, val) *(uint16_t *)(ptr) = SPICE_BYTESWAP16((uint16_t)val)
+#define read_uint16(ptr) ((uint16_t)SPICE_BYTESWAP16(*((uint16_t *)(ptr))))
+#define write_uint16(ptr, val) *(uint16_t *)(ptr) = SPICE_BYTESWAP16((uint16_t)val)
+#define read_int32(ptr) ((int32_t)SPICE_BYTESWAP32(*((uint32_t *)(ptr))))
+#define write_int32(ptr, val) *(uint32_t *)(ptr) = SPICE_BYTESWAP32((uint32_t)val)
+#define read_uint32(ptr) ((uint32_t)SPICE_BYTESWAP32(*((uint32_t *)(ptr))))
+#define write_uint32(ptr, val) *(uint32_t *)(ptr) = SPICE_BYTESWAP32((uint32_t)val)
+#define read_int64(ptr) ((int64_t)SPICE_BYTESWAP64(*((uint64_t *)(ptr))))
+#define write_int64(ptr, val) *(uint64_t *)(ptr) = SPICE_BYTESWAP64((uint64_t)val)
+#define read_uint64(ptr) ((uint64_t)SPICE_BYTESWAP64(*((uint64_t *)(ptr))))
+#define write_uint64(ptr, val) *(uint64_t *)(ptr) = SPICE_BYTESWAP64((uint64_t)val)
+#else
+#define read_int8(ptr) (*((int8_t *)(ptr)))
+#define write_int8(ptr, val) (*((int8_t *)(ptr))) = val
+#define read_uint8(ptr) (*((uint8_t *)(ptr)))
+#define write_uint8(ptr, val) (*((uint8_t *)(ptr))) = val
+#define read_int16(ptr) (*((int16_t *)(ptr)))
+#define write_int16(ptr, val) (*((int16_t *)(ptr))) = val
+#define read_uint16(ptr) (*((uint16_t *)(ptr)))
+#define write_uint16(ptr, val) (*((uint16_t *)(ptr))) = val
+#define read_int32(ptr) (*((int32_t *)(ptr)))
+#define write_int32(ptr, val) (*((int32_t *)(ptr))) = val
+#define read_uint32(ptr) (*((uint32_t *)(ptr)))
+#define write_uint32(ptr, val) (*((uint32_t *)(ptr))) = val
+#define read_int64(ptr) (*((int64_t *)(ptr)))
+#define write_int64(ptr, val) (*((int64_t *)(ptr))) = val
+#define read_uint64(ptr) (*((uint64_t *)(ptr)))
+#define write_uint64(ptr, val) (*((uint64_t *)(ptr))) = val
+#endif
+
+static int8_t SPICE_GNUC_UNUSED consume_int8(uint8_t **ptr)
+{
+ int8_t val;
+ val = read_int8(*ptr);
+ *ptr += 1;
+ return val;
+}
+
+static uint8_t SPICE_GNUC_UNUSED consume_uint8(uint8_t **ptr)
+{
+ uint8_t val;
+ val = read_uint8(*ptr);
+ *ptr += 1;
+ return val;
+}
+
+static int16_t SPICE_GNUC_UNUSED consume_int16(uint8_t **ptr)
+{
+ int16_t val;
+ val = read_int16(*ptr);
+ *ptr += 2;
+ return val;
+}
+
+static uint16_t SPICE_GNUC_UNUSED consume_uint16(uint8_t **ptr)
+{
+ uint16_t val;
+ val = read_uint16(*ptr);
+ *ptr += 2;
+ return val;
+}
+
+static int32_t SPICE_GNUC_UNUSED consume_int32(uint8_t **ptr)
+{
+ int32_t val;
+ val = read_int32(*ptr);
+ *ptr += 4;
+ return val;
+}
+
+static uint32_t SPICE_GNUC_UNUSED consume_uint32(uint8_t **ptr)
+{
+ uint32_t val;
+ val = read_uint32(*ptr);
+ *ptr += 4;
+ return val;
+}
+
+static int64_t SPICE_GNUC_UNUSED consume_int64(uint8_t **ptr)
+{
+ int64_t val;
+ val = read_int64(*ptr);
+ *ptr += 8;
+ return val;
+}
+
+static uint64_t SPICE_GNUC_UNUSED consume_uint64(uint8_t **ptr)
+{
+ uint64_t val;
+ val = read_uint64(*ptr);
+ *ptr += 8;
+ return val;
+}
+static int SPICE_GNUC_UNUSED consume_fd(uint8_t **ptr)
+{
+ return -1;
+}
+
+typedef struct PointerInfo PointerInfo;
+typedef void (*message_destructor_t)(uint8_t *message);
+typedef uint8_t * (*parse_func_t)(uint8_t *message_start, uint8_t *message_end, uint8_t *struct_data, PointerInfo *ptr_info, int minor);
+typedef uint8_t * (*parse_msg_func_t)(uint8_t *message_start, uint8_t *message_end, int minor, size_t *size_out, message_destructor_t *free_message);
+typedef uint8_t * (*spice_parse_channel_func_t)(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, int minor, size_t *size_out, message_destructor_t *free_message);
+
+struct PointerInfo {
+ uint64_t offset;
+ parse_func_t parse;
+ void * *dest;
+ uint32_t nelements;
+};
+
+static uint8_t * parse_msg_migrate(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMigrate *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgMigrate);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMigrate);
+ in = start;
+
+ out = (SpiceMsgMigrate *)data;
+
+ out->flags = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static void nofree(SPICE_GNUC_UNUSED uint8_t *data)
+{
+}
+
+static uint8_t * parse_SpiceMsgData(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t data__nw_size;
+ uint32_t data__nelements;
+
+ { /* data */
+ data__nelements = message_end - (start + 0);
+
+ data__nw_size = data__nelements;
+ }
+
+ nw_size = 0 + data__nw_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = message_start;
+ *size = message_end - message_start;
+ *free_message = nofree;
+ return data;
+
+}
+
+static uint8_t * parse_msg_set_ack(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgSetAck *out;
+
+ nw_size = 8;
+ mem_size = sizeof(SpiceMsgSetAck);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgSetAck);
+ in = start;
+
+ out = (SpiceMsgSetAck *)data;
+
+ out->generation = consume_uint32(&in);
+ out->window = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_ping(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size;
+ uint32_t data__nelements;
+ SpiceMsgPing *out;
+
+ { /* data */
+ data__nelements = message_end - (start + 12);
+
+ data__nw_size = data__nelements;
+ }
+
+ nw_size = 12 + data__nw_size;
+ mem_size = sizeof(SpiceMsgPing);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgPing);
+ in = start;
+
+ out = (SpiceMsgPing *)data;
+
+ out->id = consume_uint32(&in);
+ out->timestamp = consume_uint64(&in);
+ /* use array as pointer */
+ out->data = (uint8_t *)in;
+ out->data_len = data__nelements;
+ in += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_wait_for_channels(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t wait_list__nw_size, wait_list__mem_size;
+ uint32_t wait_list__nelements;
+ SpiceMsgWaitForChannels *out;
+ uint32_t i;
+
+ { /* wait_list */
+ uint8_t wait_count__value;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ wait_count__value = read_uint8(pos);
+ wait_list__nelements = wait_count__value;
+
+ wait_list__nw_size = (10) * wait_list__nelements;
+ wait_list__mem_size = sizeof(SpiceWaitForChannel) * wait_list__nelements;
+ }
+
+ nw_size = 1 + wait_list__nw_size;
+ mem_size = sizeof(SpiceMsgWaitForChannels) + wait_list__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgWaitForChannels);
+ in = start;
+
+ out = (SpiceMsgWaitForChannels *)data;
+
+ out->wait_count = consume_uint8(&in);
+ for (i = 0; i < wait_list__nelements; i++) {
+ SpiceWaitForChannel *out2;
+ out2 = (SpiceWaitForChannel *)end;
+ end += sizeof(SpiceWaitForChannel);
+
+ out2->channel_type = consume_uint8(&in);
+ out2->channel_id = consume_uint8(&in);
+ out2->message_serial = consume_uint64(&in);
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_disconnecting(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisconnect *out;
+
+ nw_size = 12;
+ mem_size = sizeof(SpiceMsgDisconnect);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisconnect);
+ in = start;
+
+ out = (SpiceMsgDisconnect *)data;
+
+ out->time_stamp = consume_uint64(&in);
+ out->reason = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_notify(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t message__nw_size, message__mem_size;
+ uint32_t message__nelements;
+ size_t zero__mem_size;
+ SpiceMsgNotify *out;
+
+ { /* message */
+ uint32_t message_len__value;
+ pos = start + 20;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ message_len__value = read_uint32(pos);
+ message__nelements = message_len__value;
+
+ message__nw_size = message__nelements;
+ message__mem_size = sizeof(uint8_t) * message__nelements;
+ }
+
+ { /* zero */
+ zero__mem_size = sizeof(uint8_t);
+ }
+
+ nw_size = 25 + message__nw_size;
+ mem_size = sizeof(SpiceMsgNotify) + message__mem_size + zero__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgNotify);
+ in = start;
+
+ out = (SpiceMsgNotify *)data;
+
+ out->time_stamp = consume_uint64(&in);
+ out->severity = consume_uint32(&in);
+ out->visibilty = consume_uint32(&in);
+ out->what = consume_uint32(&in);
+ out->message_len = consume_uint32(&in);
+ memcpy(out->message, in, message__nelements);
+ in += message__nelements;
+ end += message__nelements;
+ *(uint8_t *)end = consume_uint8(&in);
+ end += sizeof(uint8_t);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_migrate_begin(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t dst_info__nw_size;
+ SpiceMsgMainMigrationBegin *out;
+
+ { /* dst_info */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t dst_info_host_data__nw_size;
+ uint32_t dst_info_host_data__nelements;
+ size_t dst_info_pub_key_data__nw_size;
+ uint32_t dst_info_pub_key_data__nelements;
+ { /* host_data */
+ uint32_t host_size__value;
+ pos = start2 + 8;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ host_size__value = read_uint32(pos);
+ dst_info_host_data__nelements = host_size__value;
+
+ dst_info_host_data__nw_size = dst_info_host_data__nelements;
+ }
+
+ if (minor >= 1) { /* pub_key_data */
+ uint32_t pub_key_size__value;
+ pos = start2 + 12 + ((minor >= 1)?6:0);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ pub_key_size__value = read_uint32(pos);
+ dst_info_pub_key_data__nelements = pub_key_size__value;
+
+ dst_info_pub_key_data__nw_size = dst_info_pub_key_data__nelements;
+ } else { /* minor < 1 */
+ dst_info_pub_key_data__nelements = 0;
+ dst_info_pub_key_data__nw_size = 0;
+ }
+
+ dst_info__nw_size = 12 + ((minor >= 1)?10:0) + dst_info_host_data__nw_size + dst_info_pub_key_data__nw_size;
+ }
+
+ nw_size = 0 + dst_info__nw_size;
+ mem_size = sizeof(SpiceMsgMainMigrationBegin);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainMigrationBegin);
+ in = start;
+
+ out = (SpiceMsgMainMigrationBegin *)data;
+
+ /* dst_info */ {
+ uint32_t host_data__nelements;
+ uint32_t pub_key_data__nelements;
+ out->dst_info.port = consume_uint16(&in);
+ out->dst_info.sport = consume_uint16(&in);
+ consume_uint32(&in);
+ out->dst_info.host_size = consume_uint32(&in);
+ if (minor >= 1) {
+ out->dst_info.pub_key_type = consume_uint16(&in);
+ } else {
+ out->dst_info.pub_key_type = 0;
+ }
+ if (minor >= 1) {
+ consume_uint32(&in);
+ } else {
+ }
+ if (minor >= 1) {
+ out->dst_info.pub_key_size = consume_uint32(&in);
+ } else {
+ out->dst_info.pub_key_size = 0;
+ }
+ host_data__nelements = out->dst_info.host_size;
+ /* use array as pointer */
+ out->dst_info.host_data = (uint8_t *)in;
+ in += host_data__nelements;
+ if (minor >= 1) {
+ pub_key_data__nelements = out->dst_info.pub_key_size;
+ /* use array as pointer */
+ out->dst_info.pub_key_data = (uint8_t *)in;
+ in += pub_key_data__nelements;
+ }
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_SpiceMsgEmpty(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+
+ nw_size = 0;
+ mem_size = sizeof(SpiceMsgEmpty);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgEmpty);
+ in = start;
+
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_init(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMainInit *out;
+
+ nw_size = 32;
+ mem_size = sizeof(SpiceMsgMainInit);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainInit);
+ in = start;
+
+ out = (SpiceMsgMainInit *)data;
+
+ out->session_id = consume_uint32(&in);
+ out->display_channels_hint = consume_uint32(&in);
+ out->supported_mouse_modes = consume_uint32(&in);
+ out->current_mouse_mode = consume_uint32(&in);
+ out->agent_connected = consume_uint32(&in);
+ out->agent_tokens = consume_uint32(&in);
+ out->multi_media_time = consume_uint32(&in);
+ out->ram_hint = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_channels_list(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t channels__nw_size, channels__mem_size;
+ uint32_t channels__nelements;
+ SpiceMsgChannels *out;
+ uint32_t i;
+
+ { /* channels */
+ uint32_t num_of_channels__value;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_of_channels__value = read_uint32(pos);
+ channels__nelements = num_of_channels__value;
+
+ channels__nw_size = (2) * channels__nelements;
+ channels__mem_size = sizeof(SpiceChannelId) * channels__nelements;
+ }
+
+ nw_size = 4 + channels__nw_size;
+ mem_size = sizeof(SpiceMsgChannels) + channels__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgChannels);
+ in = start;
+
+ out = (SpiceMsgChannels *)data;
+
+ out->num_of_channels = consume_uint32(&in);
+ for (i = 0; i < channels__nelements; i++) {
+ SpiceChannelId *out2;
+ out2 = (SpiceChannelId *)end;
+ end += sizeof(SpiceChannelId);
+
+ out2->type = consume_uint8(&in);
+ out2->id = consume_uint8(&in);
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_mouse_mode(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMainMouseMode *out;
+
+ nw_size = 8;
+ mem_size = sizeof(SpiceMsgMainMouseMode);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainMouseMode);
+ in = start;
+
+ out = (SpiceMsgMainMouseMode *)data;
+
+ out->supported_modes = consume_uint32(&in);
+ out->current_mode = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_multi_media_time(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMainMultiMediaTime *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgMainMultiMediaTime);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainMultiMediaTime);
+ in = start;
+
+ out = (SpiceMsgMainMultiMediaTime *)data;
+
+ out->time = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_agent_disconnected(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMainAgentDisconnect *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgMainAgentDisconnect);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainAgentDisconnect);
+ in = start;
+
+ out = (SpiceMsgMainAgentDisconnect *)data;
+
+ out->error_code = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_agent_token(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgMainAgentTokens *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgMainAgentTokens);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainAgentTokens);
+ in = start;
+
+ out = (SpiceMsgMainAgentTokens *)data;
+
+ out->num_tokens = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_main_migrate_switch_host(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t host_data__nw_size;
+ uint32_t host_data__nelements;
+ size_t cert_subject_data__nw_size;
+ uint32_t cert_subject_data__nelements;
+ SpiceMsgMainMigrationSwitchHost *out;
+
+ { /* host_data */
+ uint32_t host_size__value;
+ pos = start + 8;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ host_size__value = read_uint32(pos);
+ host_data__nelements = host_size__value;
+
+ host_data__nw_size = host_data__nelements;
+ }
+
+ { /* cert_subject_data */
+ uint32_t cert_subject_size__value;
+ pos = start + 16;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ cert_subject_size__value = read_uint32(pos);
+ cert_subject_data__nelements = cert_subject_size__value;
+
+ cert_subject_data__nw_size = cert_subject_data__nelements;
+ }
+
+ nw_size = 20 + host_data__nw_size + cert_subject_data__nw_size;
+ mem_size = sizeof(SpiceMsgMainMigrationSwitchHost);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgMainMigrationSwitchHost);
+ in = start;
+
+ out = (SpiceMsgMainMigrationSwitchHost *)data;
+
+ out->port = consume_uint16(&in);
+ out->sport = consume_uint16(&in);
+ consume_uint32(&in);
+ out->host_size = consume_uint32(&in);
+ consume_uint32(&in);
+ out->cert_subject_size = consume_uint32(&in);
+ /* use array as pointer */
+ out->host_data = (uint8_t *)in;
+ in += host_data__nelements;
+ /* use array as pointer */
+ out->cert_subject_data = (uint8_t *)in;
+ in += cert_subject_data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_MainChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[7] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify
+ };
+ static parse_msg_func_t funcs2[11] = {
+ parse_msg_main_migrate_begin,
+ parse_SpiceMsgEmpty,
+ parse_msg_main_init,
+ parse_msg_main_channels_list,
+ parse_msg_main_mouse_mode,
+ parse_msg_main_multi_media_time,
+ parse_SpiceMsgEmpty,
+ parse_msg_main_agent_disconnected,
+ parse_SpiceMsgData,
+ parse_msg_main_agent_token,
+ parse_msg_main_migrate_switch_host
+ };
+ if (message_type >= 1 && message_type < 8) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 112) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msg_display_mode(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisplayMode *out;
+
+ nw_size = 12;
+ mem_size = sizeof(SpiceMsgDisplayMode);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayMode);
+ in = start;
+
+ out = (SpiceMsgDisplayMode *)data;
+
+ out->x_res = consume_uint32(&in);
+ out->y_res = consume_uint32(&in);
+ out->bits = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static intptr_t validate_SpiceClipRects(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *start = message_start + offset;
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ size_t mem_size, nw_size;
+ size_t rects__nw_size, rects__mem_size;
+ uint32_t rects__nelements;
+
+ if (offset == 0) {
+ return 0;
+ }
+
+ if (SPICE_UNLIKELY(start >= message_end)) {
+ goto error;
+ }
+
+ { /* rects */
+ uint32_t num_rects__value;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ num_rects__value = read_uint32(pos);
+ rects__nelements = num_rects__value;
+
+ rects__nw_size = (16) * rects__nelements;
+ rects__mem_size = sizeof(SpiceRect) * rects__nelements;
+ }
+
+ nw_size = 4 + rects__nw_size;
+ mem_size = sizeof(SpiceClipRects) + rects__mem_size;
+
+ /* Check if struct fits in reported side */
+ if (SPICE_UNLIKELY(start + nw_size > message_end)) {
+ goto error;
+ }
+ return mem_size;
+
+ error:
+ return -1;
+}
+
+static uint8_t * parse_struct_SpiceClipRects(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+ SpiceClipRects *out;
+ uint32_t rects__nelements;
+ uint32_t i;
+
+ end = struct_data + sizeof(SpiceClipRects);
+ out = (SpiceClipRects *)struct_data;
+
+ out->num_rects = consume_uint32(&in);
+ rects__nelements = out->num_rects;
+ for (i = 0; i < rects__nelements; i++) {
+ SpiceRect *out2;
+ out2 = (SpiceRect *)end;
+ end += sizeof(SpiceRect);
+
+ out2->top = consume_int32(&in);
+ out2->left = consume_int32(&in);
+ out2->bottom = consume_int32(&in);
+ out2->right = consume_int32(&in);
+ }
+ return end;
+}
+
+static uint8_t * parse_msg_display_copy_bits(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[1];
+ size_t base__extra_size;
+ SpiceMsgDisplayCopyBits *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ nw_size = 36;
+ mem_size = sizeof(SpiceMsgDisplayCopyBits) + base__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayCopyBits);
+ in = start;
+
+ out = (SpiceMsgDisplayCopyBits *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* src_pos */ {
+ out->src_pos.x = consume_int32(&in);
+ out->src_pos.y = consume_int32(&in);
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_inval_list(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t resources__nw_size, resources__mem_size;
+ uint32_t resources__nelements;
+ SpiceResourceList *out;
+ uint32_t i;
+
+ { /* resources */
+ uint16_t count__value;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ count__value = read_uint16(pos);
+ resources__nelements = count__value;
+
+ resources__nw_size = (9) * resources__nelements;
+ resources__mem_size = sizeof(SpiceResourceID) * resources__nelements;
+ }
+
+ nw_size = 2 + resources__nw_size;
+ mem_size = sizeof(SpiceResourceList) + resources__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceResourceList);
+ in = start;
+
+ out = (SpiceResourceList *)data;
+
+ out->count = consume_uint16(&in);
+ for (i = 0; i < resources__nelements; i++) {
+ SpiceResourceID *out2;
+ out2 = (SpiceResourceID *)end;
+ end += sizeof(SpiceResourceID);
+
+ out2->type = consume_uint8(&in);
+ out2->id = consume_uint64(&in);
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_inval_all_pixmaps(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t wait_list__nw_size, wait_list__mem_size;
+ uint32_t wait_list__nelements;
+ SpiceMsgWaitForChannels *out;
+ uint32_t i;
+
+ { /* wait_list */
+ uint8_t wait_count__value;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ wait_count__value = read_uint8(pos);
+ wait_list__nelements = wait_count__value;
+
+ wait_list__nw_size = (10) * wait_list__nelements;
+ wait_list__mem_size = sizeof(SpiceWaitForChannel) * wait_list__nelements;
+ }
+
+ nw_size = 1 + wait_list__nw_size;
+ mem_size = sizeof(SpiceMsgWaitForChannels) + wait_list__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgWaitForChannels);
+ in = start;
+
+ out = (SpiceMsgWaitForChannels *)data;
+
+ out->wait_count = consume_uint8(&in);
+ for (i = 0; i < wait_list__nelements; i++) {
+ SpiceWaitForChannel *out2;
+ out2 = (SpiceWaitForChannel *)end;
+ end += sizeof(SpiceWaitForChannel);
+
+ out2->channel_type = consume_uint8(&in);
+ out2->channel_id = consume_uint8(&in);
+ out2->message_serial = consume_uint64(&in);
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_inval_palette(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisplayInvalOne *out;
+
+ nw_size = 8;
+ mem_size = sizeof(SpiceMsgDisplayInvalOne);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayInvalOne);
+ in = start;
+
+ out = (SpiceMsgDisplayInvalOne *)data;
+
+ out->id = consume_uint64(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_stream_create(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[1];
+ size_t clip__extra_size;
+ SpiceMsgDisplayStreamCreate *out;
+ uint32_t i;
+
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 52);
+ size_t clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t clip_u_rects__value;
+ pos = (start2 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ clip_u__extra_size = 0;
+ } else {
+ clip_u__extra_size = 0;
+ }
+
+ }
+
+ clip__extra_size = clip_u__extra_size;
+ }
+
+ nw_size = 64;
+ mem_size = sizeof(SpiceMsgDisplayStreamCreate) + clip__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayStreamCreate);
+ in = start;
+
+ out = (SpiceMsgDisplayStreamCreate *)data;
+
+ out->surface_id = 0;
+ out->id = consume_uint32(&in);
+ out->flags = consume_uint32(&in);
+ out->codec_type = consume_uint32(&in);
+ out->stamp = consume_uint64(&in);
+ out->stream_width = consume_uint32(&in);
+ out->stream_height = consume_uint32(&in);
+ out->src_width = consume_uint32(&in);
+ out->src_height = consume_uint32(&in);
+ /* dest */ {
+ out->dest.top = consume_int32(&in);
+ out->dest.left = consume_int32(&in);
+ out->dest.bottom = consume_int32(&in);
+ out->dest.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->clip.type = consume_uint32(&in);
+ if (out->clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_stream_data(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size, data__mem_size;
+ uint32_t data__nelements;
+ SpiceMsgDisplayStreamData *out;
+
+ { /* data */
+ uint32_t data_size__value;
+ pos = start + 8;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ data__nelements = data_size__value;
+
+ data__nw_size = data__nelements;
+ data__mem_size = sizeof(uint8_t) * data__nelements;
+ }
+
+ nw_size = 16 + data__nw_size;
+ mem_size = sizeof(SpiceMsgDisplayStreamData) + data__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayStreamData);
+ in = start;
+
+ out = (SpiceMsgDisplayStreamData *)data;
+
+ /* base */ {
+ out->base.id = consume_uint32(&in);
+ out->base.multi_media_time = consume_uint32(&in);
+ }
+ out->data_size = consume_uint32(&in);
+ consume_uint32(&in);
+ memcpy(out->data, in, data__nelements);
+ in += data__nelements;
+ end += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_stream_clip(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[1];
+ size_t clip__extra_size;
+ SpiceMsgDisplayStreamClip *out;
+ uint32_t i;
+
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 4);
+ size_t clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t clip_u_rects__value;
+ pos = (start2 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ clip_u__extra_size = 0;
+ } else {
+ clip_u__extra_size = 0;
+ }
+
+ }
+
+ clip__extra_size = clip_u__extra_size;
+ }
+
+ nw_size = 16;
+ mem_size = sizeof(SpiceMsgDisplayStreamClip) + clip__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayStreamClip);
+ in = start;
+
+ out = (SpiceMsgDisplayStreamClip *)data;
+
+ out->id = consume_uint32(&in);
+ /* clip */ {
+ out->clip.type = consume_uint32(&in);
+ if (out->clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_stream_destroy(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisplayStreamDestroy *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgDisplayStreamDestroy);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayStreamDestroy);
+ in = start;
+
+ out = (SpiceMsgDisplayStreamDestroy *)data;
+
+ out->id = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static intptr_t validate_SpicePalette(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *start = message_start + offset;
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ size_t mem_size, nw_size;
+ size_t ents__nw_size, ents__mem_size;
+ uint32_t ents__nelements;
+
+ if (offset == 0) {
+ return 0;
+ }
+
+ if (SPICE_UNLIKELY(start >= message_end)) {
+ goto error;
+ }
+
+ { /* ents */
+ uint16_t num_ents__value;
+ pos = start + 8;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ num_ents__value = read_uint16(pos);
+ ents__nelements = num_ents__value;
+
+ ents__nw_size = (4) * ents__nelements;
+ ents__mem_size = sizeof(uint32_t) * ents__nelements;
+ }
+
+ nw_size = 10 + ents__nw_size;
+ mem_size = sizeof(SpicePalette) + ents__mem_size;
+
+ /* Check if struct fits in reported side */
+ if (SPICE_UNLIKELY(start + nw_size > message_end)) {
+ goto error;
+ }
+ return mem_size;
+
+ error:
+ return -1;
+}
+
+static intptr_t validate_SpiceImage(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *start = message_start + offset;
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ size_t mem_size, nw_size;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ size_t u__nw_size, u__extra_size;
+ uint8_t descriptor_type__value;
+
+ if (offset == 0) {
+ return 0;
+ }
+
+ if (SPICE_UNLIKELY(start >= message_end)) {
+ goto error;
+ }
+
+ { /* u */
+ pos = start + 8;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ descriptor_type__value = read_uint8(pos);
+ if (descriptor_type__value == SPICE_IMAGE_TYPE_BITMAP) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ size_t u_pal__extra_size;
+ uint8_t flags__value;
+ size_t u_data__extra_size;
+ uint32_t u_data__array__nelements;
+ { /* pal */
+ pos = start2 + 1;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint8(pos);
+ if ((flags__value & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
+ u_pal__extra_size = 0;
+ } else if (1) {
+ uint64_t u_pal_palette__value;
+ pos = (start2 + 14);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ u_pal_palette__value = read_uint64(pos);
+ ptr_size = validate_SpicePalette(message_start, message_end, u_pal_palette__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ u_pal__extra_size = ptr_size + /* for alignment */ 3;
+ } else {
+ u_pal__extra_size = 0;
+ }
+
+ }
+
+ { /* data */
+ uint64_t data__value;
+ uint32_t u_data__array__nw_size;
+ uint32_t stride__value;
+ uint32_t y__value;
+ pos = (start2 + 22);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ data__value = read_uint64(pos);
+ if (SPICE_UNLIKELY(message_start + data__value >= message_end)) {
+ goto error;
+ }
+ pos = start2 + 10;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ stride__value = read_uint32(pos);
+ pos = start2 + 6;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ y__value = read_uint32(pos);
+ u_data__array__nelements = stride__value * y__value;
+
+ u_data__array__nw_size = u_data__array__nelements;
+ if (SPICE_UNLIKELY(message_start + data__value + u_data__array__nw_size > message_end)) {
+ goto error;
+ }
+ u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ }
+
+ u__nw_size = 30;
+ u__extra_size = u_pal__extra_size + u_data__extra_size;
+ } else if (descriptor_type__value == SPICE_IMAGE_TYPE_QUIC) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ size_t u_data__nw_size, u_data__extra_size;
+ uint32_t u_data__nelements;
+ { /* data */
+ uint32_t data_size__value;
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ u_data__nelements = data_size__value;
+
+ u_data__nw_size = u_data__nelements;
+ u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ }
+
+ u__nw_size = 4 + u_data__nw_size;
+ u__extra_size = u_data__extra_size;
+ } else if (descriptor_type__value == SPICE_IMAGE_TYPE_LZ_RGB || descriptor_type__value == SPICE_IMAGE_TYPE_GLZ_RGB) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ size_t u_data__nw_size, u_data__extra_size;
+ uint32_t u_data__nelements;
+ { /* data */
+ uint32_t data_size__value;
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ u_data__nelements = data_size__value;
+
+ u_data__nw_size = u_data__nelements;
+ u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ }
+
+ u__nw_size = 4 + u_data__nw_size;
+ u__extra_size = u_data__extra_size;
+ } else if (descriptor_type__value == SPICE_IMAGE_TYPE_LZ_PLT) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 18);
+ size_t u_pal__extra_size;
+ uint8_t flags__value;
+ size_t u_data__nw_size, u_data__extra_size;
+ uint32_t u_data__nelements;
+ { /* pal */
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint8(pos);
+ if ((flags__value & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
+ u_pal__extra_size = 0;
+ } else if (1) {
+ uint64_t u_pal_palette__value;
+ pos = (start2 + 5);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ u_pal_palette__value = read_uint64(pos);
+ if (SPICE_UNLIKELY(u_pal_palette__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpicePalette(message_start, message_end, u_pal_palette__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ u_pal__extra_size = ptr_size + /* for alignment */ 3;
+ } else {
+ u_pal__extra_size = 0;
+ }
+
+ }
+
+ { /* data */
+ uint32_t data_size__value;
+ pos = start2 + 1;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ data_size__value = read_uint32(pos);
+ u_data__nelements = data_size__value;
+
+ u_data__nw_size = u_data__nelements;
+ u_data__extra_size = sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ }
+
+ u__nw_size = 13 + u_data__nw_size;
+ u__extra_size = u_pal__extra_size + u_data__extra_size;
+ } else {
+ u__nw_size = 0;
+ u__extra_size = 0;
+ }
+
+ }
+
+ nw_size = 18 + u__nw_size;
+ mem_size = sizeof(SpiceImage) + u__extra_size;
+
+ /* Check if struct fits in reported side */
+ if (SPICE_UNLIKELY(start + nw_size > message_end)) {
+ goto error;
+ }
+ return mem_size;
+
+ error:
+ return -1;
+}
+
+static uint8_t * parse_struct_SpicePalette(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+ SpicePalette *out;
+ uint32_t ents__nelements;
+ uint32_t i;
+
+ end = struct_data + sizeof(SpicePalette);
+ out = (SpicePalette *)struct_data;
+
+ out->unique = consume_uint64(&in);
+ out->num_ents = consume_uint16(&in);
+ ents__nelements = out->num_ents;
+ for (i = 0; i < ents__nelements; i++) {
+ out->ents[i] = consume_uint32(&in);
+ end += sizeof(uint32_t);
+ }
+ return end;
+}
+
+static uint8_t * parse_struct_SpiceImage(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ SpiceImage *out;
+ uint32_t i;
+
+ end = struct_data + sizeof(SpiceImage);
+ out = (SpiceImage *)struct_data;
+
+ /* descriptor */ {
+ out->descriptor.id = consume_uint64(&in);
+ out->descriptor.type = consume_uint8(&in);
+ out->descriptor.flags = consume_uint8(&in);
+ out->descriptor.width = consume_uint32(&in);
+ out->descriptor.height = consume_uint32(&in);
+ }
+ if (out->descriptor.type == SPICE_IMAGE_TYPE_BITMAP) {
+ uint32_t data__array__nelements;
+ SpiceChunks *chunks;
+ out->u.bitmap.format = consume_uint8(&in);
+ out->u.bitmap.flags = consume_uint8(&in);
+ out->u.bitmap.x = consume_uint32(&in);
+ out->u.bitmap.y = consume_uint32(&in);
+ out->u.bitmap.stride = consume_uint32(&in);
+ if ((out->u.bitmap.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
+ out->u.bitmap.palette_id = consume_uint64(&in);
+ } else if (1) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpicePalette;
+ ptr_info[n_ptr].dest = (void **)&out->u.bitmap.palette;
+ n_ptr++;
+ }
+ data__array__nelements = out->u.bitmap.stride * out->u.bitmap.y;
+ /* Reuse data from network message as chunk */
+ chunks = (SpiceChunks *)end;
+ end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ out->u.bitmap.data = chunks;
+ chunks->data_size = data__array__nelements;
+ chunks->flags = 0;
+ chunks->num_chunks = 1;
+ chunks->chunk[0].len = data__array__nelements;
+ chunks->chunk[0].data = message_start + consume_uint64(&in);
+ } else if (out->descriptor.type == SPICE_IMAGE_TYPE_QUIC) {
+ uint32_t data__nelements;
+ SpiceChunks *chunks;
+ out->u.quic.data_size = consume_uint32(&in);
+ data__nelements = out->u.quic.data_size;
+ /* use array as chunk */
+ chunks = (SpiceChunks *)end;
+ end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ out->u.quic.data = chunks;
+ chunks->data_size = data__nelements;
+ chunks->flags = 0;
+ chunks->num_chunks = 1;
+ chunks->chunk[0].len = data__nelements;
+ chunks->chunk[0].data = in;
+ in += data__nelements;
+ } else if (out->descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB || out->descriptor.type == SPICE_IMAGE_TYPE_GLZ_RGB) {
+ uint32_t data__nelements;
+ SpiceChunks *chunks;
+ out->u.lz_rgb.data_size = consume_uint32(&in);
+ data__nelements = out->u.lz_rgb.data_size;
+ /* use array as chunk */
+ chunks = (SpiceChunks *)end;
+ end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ out->u.lz_rgb.data = chunks;
+ chunks->data_size = data__nelements;
+ chunks->flags = 0;
+ chunks->num_chunks = 1;
+ chunks->chunk[0].len = data__nelements;
+ chunks->chunk[0].data = in;
+ in += data__nelements;
+ } else if (out->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) {
+ uint32_t data__nelements;
+ SpiceChunks *chunks;
+ out->u.lz_plt.flags = consume_uint8(&in);
+ out->u.lz_plt.data_size = consume_uint32(&in);
+ if ((out->u.lz_plt.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
+ out->u.lz_plt.palette_id = consume_uint64(&in);
+ } else if (1) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpicePalette;
+ ptr_info[n_ptr].dest = (void **)&out->u.lz_plt.palette;
+ n_ptr++;
+ }
+ data__nelements = out->u.lz_plt.data_size;
+ /* use array as chunk */
+ chunks = (SpiceChunks *)end;
+ end += sizeof(SpiceChunks) + sizeof(SpiceChunk);
+ out->u.lz_plt.data = chunks;
+ chunks->data_size = data__nelements;
+ chunks->flags = 0;
+ chunks->num_chunks = 1;
+ chunks->chunk[0].len = data__nelements;
+ chunks->chunk[0].data = in;
+ in += data__nelements;
+ }
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ return end;
+
+ error:
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_fill(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[3];
+ size_t base__extra_size;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawFill *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
+ size_t data_brush__extra_size;
+ size_t data_mask__extra_size;
+ { /* brush */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
+ size_t data_brush_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_BRUSH_TYPE_SOLID) {
+ data_brush_u__extra_size = 0;
+ } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 4);
+ size_t data_brush_u_pat__extra_size;
+ { /* pat */
+ uint64_t pat__value;
+ pos = (start4 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ pat__value = read_uint64(pos);
+ if (SPICE_UNLIKELY(pat__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_brush_u__extra_size = data_brush_u_pat__extra_size;
+ } else {
+ data_brush_u__extra_size = 0;
+ }
+
+ }
+
+ data_brush__extra_size = data_brush_u__extra_size;
+ }
+
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 22);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint64_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_brush__extra_size + data_mask__extra_size;
+ }
+
+ nw_size = 67;
+ mem_size = sizeof(SpiceMsgDisplayDrawFill) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawFill);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawFill *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* data */ {
+ /* brush */ {
+ uint8_t *in_save;
+ out->data.brush.type = consume_uint32(&in);
+ in_save = in;
+ if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ out->data.brush.u.color = consume_uint32(&in);
+ } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
+ n_ptr++;
+ /* pos */ {
+ out->data.brush.u.pattern.pos.x = consume_int32(&in);
+ out->data.brush.u.pattern.pos.y = consume_int32(&in);
+ }
+ }
+ in = in_save + 16;
+ }
+ out->data.rop_descriptor = consume_uint16(&in);
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_opaque(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[4];
+ size_t base__extra_size;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawOpaque *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
+ size_t data_src_bitmap__extra_size;
+ size_t data_brush__extra_size;
+ size_t data_mask__extra_size;
+ { /* src_bitmap */
+ uint64_t src_bitmap__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* brush */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 24);
+ size_t data_brush_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_BRUSH_TYPE_SOLID) {
+ data_brush_u__extra_size = 0;
+ } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 4);
+ size_t data_brush_u_pat__extra_size;
+ { /* pat */
+ uint64_t pat__value;
+ pos = (start4 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ pat__value = read_uint64(pos);
+ if (SPICE_UNLIKELY(pat__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_brush_u__extra_size = data_brush_u_pat__extra_size;
+ } else {
+ data_brush_u__extra_size = 0;
+ }
+
+ }
+
+ data_brush__extra_size = data_brush_u__extra_size;
+ }
+
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 47);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint64_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_src_bitmap__extra_size + data_brush__extra_size + data_mask__extra_size;
+ }
+
+ nw_size = 92;
+ mem_size = sizeof(SpiceMsgDisplayDrawOpaque) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawOpaque);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawOpaque *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ /* src_area */ {
+ out->data.src_area.top = consume_int32(&in);
+ out->data.src_area.left = consume_int32(&in);
+ out->data.src_area.bottom = consume_int32(&in);
+ out->data.src_area.right = consume_int32(&in);
+ }
+ /* brush */ {
+ uint8_t *in_save;
+ out->data.brush.type = consume_uint32(&in);
+ in_save = in;
+ if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ out->data.brush.u.color = consume_uint32(&in);
+ } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
+ n_ptr++;
+ /* pos */ {
+ out->data.brush.u.pattern.pos.x = consume_int32(&in);
+ out->data.brush.u.pattern.pos.y = consume_int32(&in);
+ }
+ }
+ in = in_save + 16;
+ }
+ out->data.rop_descriptor = consume_uint16(&in);
+ out->data.scale_mode = consume_uint8(&in);
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_copy(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[3];
+ size_t base__extra_size;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawCopy *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
+ size_t data_src_bitmap__extra_size;
+ size_t data_mask__extra_size;
+ { /* src_bitmap */
+ uint64_t src_bitmap__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 27);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint64_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_src_bitmap__extra_size + data_mask__extra_size;
+ }
+
+ nw_size = 72;
+ mem_size = sizeof(SpiceMsgDisplayDrawCopy) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawCopy);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawCopy *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ /* src_area */ {
+ out->data.src_area.top = consume_int32(&in);
+ out->data.src_area.left = consume_int32(&in);
+ out->data.src_area.bottom = consume_int32(&in);
+ out->data.src_area.right = consume_int32(&in);
+ }
+ out->data.rop_descriptor = consume_uint16(&in);
+ out->data.scale_mode = consume_uint8(&in);
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_blend(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[3];
+ size_t base__extra_size;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawBlend *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
+ size_t data_src_bitmap__extra_size;
+ size_t data_mask__extra_size;
+ { /* src_bitmap */
+ uint64_t src_bitmap__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 27);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint64_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_src_bitmap__extra_size + data_mask__extra_size;
+ }
+
+ nw_size = 72;
+ mem_size = sizeof(SpiceMsgDisplayDrawBlend) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawBlend);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawBlend *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ /* src_area */ {
+ out->data.src_area.top = consume_int32(&in);
+ out->data.src_area.left = consume_int32(&in);
+ out->data.src_area.bottom = consume_int32(&in);
+ out->data.src_area.right = consume_int32(&in);
+ }
+ out->data.rop_descriptor = consume_uint16(&in);
+ out->data.scale_mode = consume_uint8(&in);
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_blackness(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t base__extra_size;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawBlackness *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
+ size_t data_mask__extra_size;
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint64_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_mask__extra_size;
+ }
+
+ nw_size = 45;
+ mem_size = sizeof(SpiceMsgDisplayDrawBlackness) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawBlackness);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawBlackness *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* data */ {
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_whiteness(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t base__extra_size;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawWhiteness *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
+ size_t data_mask__extra_size;
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint64_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_mask__extra_size;
+ }
+
+ nw_size = 45;
+ mem_size = sizeof(SpiceMsgDisplayDrawWhiteness) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawWhiteness);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawWhiteness *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* data */ {
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_invers(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t base__extra_size;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawInvers *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
+ size_t data_mask__extra_size;
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 0);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint64_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_mask__extra_size;
+ }
+
+ nw_size = 45;
+ mem_size = sizeof(SpiceMsgDisplayDrawInvers) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawInvers);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawInvers *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* data */ {
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_rop3(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[4];
+ size_t base__extra_size;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawRop3 *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
+ size_t data_src_bitmap__extra_size;
+ size_t data_brush__extra_size;
+ size_t data_mask__extra_size;
+ { /* src_bitmap */
+ uint64_t src_bitmap__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* brush */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 24);
+ size_t data_brush_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_BRUSH_TYPE_SOLID) {
+ data_brush_u__extra_size = 0;
+ } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 4);
+ size_t data_brush_u_pat__extra_size;
+ { /* pat */
+ uint64_t pat__value;
+ pos = (start4 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ pat__value = read_uint64(pos);
+ if (SPICE_UNLIKELY(pat__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_brush_u__extra_size = data_brush_u_pat__extra_size;
+ } else {
+ data_brush_u__extra_size = 0;
+ }
+
+ }
+
+ data_brush__extra_size = data_brush_u__extra_size;
+ }
+
+ { /* mask */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 46);
+ size_t data_mask_bitmap__extra_size;
+ { /* bitmap */
+ uint64_t bitmap__value;
+ pos = (start3 + 9);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_mask_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_mask__extra_size = data_mask_bitmap__extra_size;
+ }
+
+ data__extra_size = data_src_bitmap__extra_size + data_brush__extra_size + data_mask__extra_size;
+ }
+
+ nw_size = 91;
+ mem_size = sizeof(SpiceMsgDisplayDrawRop3) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawRop3);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawRop3 *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ /* src_area */ {
+ out->data.src_area.top = consume_int32(&in);
+ out->data.src_area.left = consume_int32(&in);
+ out->data.src_area.bottom = consume_int32(&in);
+ out->data.src_area.right = consume_int32(&in);
+ }
+ /* brush */ {
+ uint8_t *in_save;
+ out->data.brush.type = consume_uint32(&in);
+ in_save = in;
+ if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ out->data.brush.u.color = consume_uint32(&in);
+ } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
+ n_ptr++;
+ /* pos */ {
+ out->data.brush.u.pattern.pos.x = consume_int32(&in);
+ out->data.brush.u.pattern.pos.y = consume_int32(&in);
+ }
+ }
+ in = in_save + 16;
+ }
+ out->data.rop3 = consume_uint8(&in);
+ out->data.scale_mode = consume_uint8(&in);
+ /* mask */ {
+ out->data.mask.flags = consume_uint8(&in);
+ /* pos */ {
+ out->data.mask.pos.x = consume_int32(&in);
+ out->data.mask.pos.y = consume_int32(&in);
+ }
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.mask.bitmap;
+ n_ptr++;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static intptr_t validate_SpicePath(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *start = message_start + offset;
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ size_t mem_size, nw_size;
+ size_t segments__nw_size, segments__mem_size;
+ uint32_t segments__nelements;
+ uint32_t segments__nbytes;
+
+ if (offset == 0) {
+ return 0;
+ }
+
+ if (SPICE_UNLIKELY(start >= message_end)) {
+ goto error;
+ }
+
+ { /* segments */
+ uint32_t segments_size__value;
+ uint8_t *start2 = (start + 4);
+ uint8_t *start2_array_end;
+ uint32_t segments__element__nw_size;
+ uint32_t segments__element__mem_size;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ segments_size__value = read_uint32(pos);
+ segments__nbytes = segments_size__value;
+ segments__nelements = 0;
+
+ segments__nw_size = segments__nbytes;
+ segments__mem_size = 0;
+ start2_array_end = start2 + segments__nbytes;
+ while (start2 < start2_array_end) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = start2;
+ size_t segments__element_points__nw_size, segments__element_points__mem_size;
+ uint32_t segments__element_points__nelements;
+ segments__nelements += 1;
+ { /* points */
+ uint32_t count__value;
+ pos = start3 + 4;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ count__value = read_uint32(pos);
+ segments__element_points__nelements = count__value;
+
+ segments__element_points__nw_size = (8) * segments__element_points__nelements;
+ segments__element_points__mem_size = sizeof(SpicePointFix) * segments__element_points__nelements;
+ }
+
+ segments__element__nw_size = 8 + segments__element_points__nw_size;
+ segments__element__mem_size = sizeof(SpicePathSeg) + segments__element_points__mem_size;
+ segments__mem_size += sizeof(void *) + SPICE_ALIGN(segments__element__mem_size, 4);
+ start2 += segments__element__nw_size;
+ }
+ if (SPICE_UNLIKELY(start2 != start2_array_end)) {
+ goto error;
+ }
+ pos = start + 0;
+ write_uint32(pos, segments__nelements);
+ }
+
+ nw_size = 4 + segments__nw_size;
+ mem_size = sizeof(SpicePath) + segments__mem_size;
+
+ /* Check if struct fits in reported side */
+ if (SPICE_UNLIKELY(start + nw_size > message_end)) {
+ goto error;
+ }
+ return mem_size;
+
+ error:
+ return -1;
+}
+
+static uint8_t * parse_struct_SpicePath(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+ SpicePath *out;
+ uint32_t segments__nelements;
+ uint32_t i;
+ void * *ptr_array;
+ int ptr_array_index;
+ uint32_t j;
+
+ end = struct_data + sizeof(SpicePath);
+ out = (SpicePath *)struct_data;
+
+ out->num_segments = consume_uint32(&in);
+ segments__nelements = out->num_segments;
+ ptr_array_index = 0;
+ ptr_array = (void **)out->segments;
+ end += sizeof(void *) * segments__nelements;
+ for (i = 0; i < segments__nelements; i++) {
+ SpicePathSeg *out2;
+ uint32_t points__nelements;
+ ptr_array[ptr_array_index++] = end;
+ out2 = (SpicePathSeg *)end;
+ end += sizeof(SpicePathSeg);
+
+ out2->flags = consume_uint32(&in);
+ out2->count = consume_uint32(&in);
+ points__nelements = out2->count;
+ for (j = 0; j < points__nelements; j++) {
+ SpicePointFix *out3;
+ out3 = (SpicePointFix *)end;
+ end += sizeof(SpicePointFix);
+
+ out3->x = consume_int32(&in);
+ out3->y = consume_int32(&in);
+ }
+ /* Align ptr_array element to 4 bytes */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ }
+ return end;
+}
+
+static uint8_t * parse_array_int32(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+ uint32_t i;
+
+ end = struct_data;
+ for (i = 0; i < this_ptr_info->nelements; i++) {
+ *(SPICE_FIXED28_4 *)end = consume_int32(&in);
+ end += sizeof(SPICE_FIXED28_4);
+ }
+ return end;
+}
+
+static uint8_t * parse_msg_display_draw_stroke(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[4];
+ size_t base__extra_size;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawStroke *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
+ size_t data_path__extra_size;
+ size_t data_attr__extra_size;
+ size_t data_brush__extra_size;
+ { /* path */
+ uint64_t path__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ path__value = read_uint64(pos);
+ ptr_size = validate_SpicePath(message_start, message_end, path__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_path__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* attr */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 8);
+ size_t data_attr_style__extra_size;
+ uint32_t data_attr_style__array__nelements;
+ { /* style */
+ uint64_t style__value;
+ uint32_t data_attr_style__array__nw_size;
+ uint32_t data_attr_style__array__mem_size;
+ uint8_t style_nseg__value;
+ pos = (start3 + 12);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ style__value = read_uint64(pos);
+ if (SPICE_UNLIKELY(message_start + style__value >= message_end)) {
+ goto error;
+ }
+ pos = start3 + 3;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ style_nseg__value = read_uint8(pos);
+ data_attr_style__array__nelements = style_nseg__value;
+
+ data_attr_style__array__nw_size = (4) * data_attr_style__array__nelements;
+ data_attr_style__array__mem_size = sizeof(SPICE_FIXED28_4) * data_attr_style__array__nelements;
+ if (SPICE_UNLIKELY(message_start + style__value + data_attr_style__array__nw_size > message_end)) {
+ goto error;
+ }
+ data_attr_style__extra_size = data_attr_style__array__mem_size + /* for alignment */ 3;
+ }
+
+ data_attr__extra_size = data_attr_style__extra_size;
+ }
+
+ { /* brush */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 28);
+ size_t data_brush_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_BRUSH_TYPE_SOLID) {
+ data_brush_u__extra_size = 0;
+ } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 4);
+ size_t data_brush_u_pat__extra_size;
+ { /* pat */
+ uint64_t pat__value;
+ pos = (start4 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ pat__value = read_uint64(pos);
+ if (SPICE_UNLIKELY(pat__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_brush_u__extra_size = data_brush_u_pat__extra_size;
+ } else {
+ data_brush_u__extra_size = 0;
+ }
+
+ }
+
+ data_brush__extra_size = data_brush_u__extra_size;
+ }
+
+ data__extra_size = data_path__extra_size + data_attr__extra_size + data_brush__extra_size;
+ }
+
+ nw_size = 80;
+ mem_size = sizeof(SpiceMsgDisplayDrawStroke) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawStroke);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawStroke *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpicePath;
+ ptr_info[n_ptr].dest = (void **)&out->data.path;
+ n_ptr++;
+ /* attr */ {
+ uint32_t style__array__nelements;
+ out->data.attr.flags = consume_uint8(&in);
+ consume_uint8(&in);
+ consume_uint8(&in);
+ out->data.attr.style_nseg = consume_uint8(&in);
+ consume_int32(&in);
+ consume_int32(&in);
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_array_int32;
+ ptr_info[n_ptr].dest = (void **)&out->data.attr.style;
+ style__array__nelements = out->data.attr.style_nseg;
+ ptr_info[n_ptr].nelements = style__array__nelements;
+ n_ptr++;
+ }
+ /* brush */ {
+ uint8_t *in_save;
+ out->data.brush.type = consume_uint32(&in);
+ in_save = in;
+ if (out->data.brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ out->data.brush.u.color = consume_uint32(&in);
+ } else if (out->data.brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.brush.u.pattern.pat;
+ n_ptr++;
+ /* pos */ {
+ out->data.brush.u.pattern.pos.x = consume_int32(&in);
+ out->data.brush.u.pattern.pos.y = consume_int32(&in);
+ }
+ }
+ in = in_save + 16;
+ }
+ out->data.fore_mode = consume_uint16(&in);
+ out->data.back_mode = consume_uint16(&in);
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static intptr_t validate_SpiceString(uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *start = message_start + offset;
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ size_t mem_size, nw_size;
+ size_t u__nw_size, u__extra_size;
+ uint16_t flags__value;
+ uint32_t i;
+
+ if (offset == 0) {
+ return 0;
+ }
+
+ if (SPICE_UNLIKELY(start >= message_end)) {
+ goto error;
+ }
+
+ { /* u */
+ uint32_t u__mem_size;
+ uint32_t u__nelements;
+ pos = start + 2;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ flags__value = read_uint16(pos);
+ if ((flags__value & SPICE_STRING_FLAGS_RASTER_A1)) {
+ uint16_t length__value;
+ uint8_t *start2 = (start + 4);
+ uint32_t u__element__nw_size;
+ uint32_t u__element__mem_size;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ length__value = read_uint16(pos);
+ u__nelements = length__value;
+
+ u__nw_size = 0;
+ u__mem_size = 0;
+ for (i = 0; i < u__nelements; i++) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = start2;
+ size_t u__element_data__nw_size, u__element_data__mem_size;
+ uint32_t u__element_data__nelements;
+ { /* data */
+ uint16_t width__value;
+ uint16_t height__value;
+ pos = start3 + 16;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ width__value = read_uint16(pos);
+ pos = start3 + 18;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ height__value = read_uint16(pos);
+ u__element_data__nelements = ((width__value + 7) / 8 ) * height__value;
+
+ u__element_data__nw_size = u__element_data__nelements;
+ u__element_data__mem_size = sizeof(uint8_t) * u__element_data__nelements;
+ }
+
+ u__element__nw_size = 20 + u__element_data__nw_size;
+ u__element__mem_size = sizeof(SpiceRasterGlyph) + u__element_data__mem_size;
+ u__nw_size += u__element__nw_size;
+ u__mem_size += sizeof(void *) + SPICE_ALIGN(u__element__mem_size, 4);
+ start2 += u__element__nw_size;
+ }
+ u__extra_size = u__mem_size;
+ } else if ((flags__value & SPICE_STRING_FLAGS_RASTER_A4)) {
+ uint16_t length__value;
+ uint8_t *start2 = (start + 4);
+ uint32_t u__element__nw_size;
+ uint32_t u__element__mem_size;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ length__value = read_uint16(pos);
+ u__nelements = length__value;
+
+ u__nw_size = 0;
+ u__mem_size = 0;
+ for (i = 0; i < u__nelements; i++) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = start2;
+ size_t u__element_data__nw_size, u__element_data__mem_size;
+ uint32_t u__element_data__nelements;
+ { /* data */
+ uint16_t width__value;
+ uint16_t height__value;
+ pos = start3 + 16;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ width__value = read_uint16(pos);
+ pos = start3 + 18;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ height__value = read_uint16(pos);
+ u__element_data__nelements = ((4 * width__value + 7) / 8 ) * height__value;
+
+ u__element_data__nw_size = u__element_data__nelements;
+ u__element_data__mem_size = sizeof(uint8_t) * u__element_data__nelements;
+ }
+
+ u__element__nw_size = 20 + u__element_data__nw_size;
+ u__element__mem_size = sizeof(SpiceRasterGlyph) + u__element_data__mem_size;
+ u__nw_size += u__element__nw_size;
+ u__mem_size += sizeof(void *) + SPICE_ALIGN(u__element__mem_size, 4);
+ start2 += u__element__nw_size;
+ }
+ u__extra_size = u__mem_size;
+ } else if ((flags__value & SPICE_STRING_FLAGS_RASTER_A8)) {
+ uint16_t length__value;
+ uint8_t *start2 = (start + 4);
+ uint32_t u__element__nw_size;
+ uint32_t u__element__mem_size;
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ length__value = read_uint16(pos);
+ u__nelements = length__value;
+
+ u__nw_size = 0;
+ u__mem_size = 0;
+ for (i = 0; i < u__nelements; i++) {
+ SPICE_GNUC_UNUSED uint8_t *start3 = start2;
+ size_t u__element_data__nw_size, u__element_data__mem_size;
+ uint32_t u__element_data__nelements;
+ { /* data */
+ uint16_t width__value;
+ uint16_t height__value;
+ pos = start3 + 16;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ width__value = read_uint16(pos);
+ pos = start3 + 18;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ height__value = read_uint16(pos);
+ u__element_data__nelements = width__value * height__value;
+
+ u__element_data__nw_size = u__element_data__nelements;
+ u__element_data__mem_size = sizeof(uint8_t) * u__element_data__nelements;
+ }
+
+ u__element__nw_size = 20 + u__element_data__nw_size;
+ u__element__mem_size = sizeof(SpiceRasterGlyph) + u__element_data__mem_size;
+ u__nw_size += u__element__nw_size;
+ u__mem_size += sizeof(void *) + SPICE_ALIGN(u__element__mem_size, 4);
+ start2 += u__element__nw_size;
+ }
+ u__extra_size = u__mem_size;
+ } else {
+ u__nw_size = 0;
+ u__extra_size = 0;
+ }
+
+ }
+
+ nw_size = 4 + u__nw_size;
+ mem_size = sizeof(SpiceString) + u__extra_size;
+
+ /* Check if struct fits in reported side */
+ if (SPICE_UNLIKELY(start + nw_size > message_end)) {
+ goto error;
+ }
+ return mem_size;
+
+ error:
+ return -1;
+}
+
+static uint8_t * parse_struct_SpiceString(uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor)
+{
+ uint8_t *in = message_start + this_ptr_info->offset;
+ uint8_t *end;
+ SpiceString *out;
+ uint32_t i;
+
+ end = struct_data + sizeof(SpiceString);
+ out = (SpiceString *)struct_data;
+
+ out->length = consume_uint16(&in);
+ out->flags = consume_uint16(&in);
+ if ((out->flags & SPICE_STRING_FLAGS_RASTER_A1)) {
+ uint32_t glyphs__nelements;
+ void * *ptr_array;
+ int ptr_array_index;
+ glyphs__nelements = out->length;
+ ptr_array_index = 0;
+ ptr_array = (void **)out->glyphs;
+ end += sizeof(void *) * glyphs__nelements;
+ for (i = 0; i < glyphs__nelements; i++) {
+ SpiceRasterGlyph *out2;
+ uint32_t data__nelements;
+ ptr_array[ptr_array_index++] = end;
+ out2 = (SpiceRasterGlyph *)end;
+ end += sizeof(SpiceRasterGlyph);
+
+ /* render_pos */ {
+ out2->render_pos.x = consume_int32(&in);
+ out2->render_pos.y = consume_int32(&in);
+ }
+ /* glyph_origin */ {
+ out2->glyph_origin.x = consume_int32(&in);
+ out2->glyph_origin.y = consume_int32(&in);
+ }
+ out2->width = consume_uint16(&in);
+ out2->height = consume_uint16(&in);
+ data__nelements = ((out2->width + 7) / 8 ) * out2->height;
+ memcpy(out2->data, in, data__nelements);
+ in += data__nelements;
+ end += data__nelements;
+ /* Align ptr_array element to 4 bytes */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ }
+ } else if ((out->flags & SPICE_STRING_FLAGS_RASTER_A4)) {
+ uint32_t glyphs__nelements;
+ void * *ptr_array;
+ int ptr_array_index;
+ glyphs__nelements = out->length;
+ ptr_array_index = 0;
+ ptr_array = (void **)out->glyphs;
+ end += sizeof(void *) * glyphs__nelements;
+ for (i = 0; i < glyphs__nelements; i++) {
+ SpiceRasterGlyph *out2;
+ uint32_t data__nelements;
+ ptr_array[ptr_array_index++] = end;
+ out2 = (SpiceRasterGlyph *)end;
+ end += sizeof(SpiceRasterGlyph);
+
+ /* render_pos */ {
+ out2->render_pos.x = consume_int32(&in);
+ out2->render_pos.y = consume_int32(&in);
+ }
+ /* glyph_origin */ {
+ out2->glyph_origin.x = consume_int32(&in);
+ out2->glyph_origin.y = consume_int32(&in);
+ }
+ out2->width = consume_uint16(&in);
+ out2->height = consume_uint16(&in);
+ data__nelements = ((4 * out2->width + 7) / 8 ) * out2->height;
+ memcpy(out2->data, in, data__nelements);
+ in += data__nelements;
+ end += data__nelements;
+ /* Align ptr_array element to 4 bytes */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ }
+ } else if ((out->flags & SPICE_STRING_FLAGS_RASTER_A8)) {
+ uint32_t glyphs__nelements;
+ void * *ptr_array;
+ int ptr_array_index;
+ glyphs__nelements = out->length;
+ ptr_array_index = 0;
+ ptr_array = (void **)out->glyphs;
+ end += sizeof(void *) * glyphs__nelements;
+ for (i = 0; i < glyphs__nelements; i++) {
+ SpiceRasterGlyph *out2;
+ uint32_t data__nelements;
+ ptr_array[ptr_array_index++] = end;
+ out2 = (SpiceRasterGlyph *)end;
+ end += sizeof(SpiceRasterGlyph);
+
+ /* render_pos */ {
+ out2->render_pos.x = consume_int32(&in);
+ out2->render_pos.y = consume_int32(&in);
+ }
+ /* glyph_origin */ {
+ out2->glyph_origin.x = consume_int32(&in);
+ out2->glyph_origin.y = consume_int32(&in);
+ }
+ out2->width = consume_uint16(&in);
+ out2->height = consume_uint16(&in);
+ data__nelements = out2->width * out2->height;
+ memcpy(out2->data, in, data__nelements);
+ in += data__nelements;
+ end += data__nelements;
+ /* Align ptr_array element to 4 bytes */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ }
+ }
+ return end;
+}
+
+static uint8_t * parse_msg_display_draw_text(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[4];
+ size_t base__extra_size;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawText *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
+ size_t data_str__extra_size;
+ size_t data_fore_brush__extra_size;
+ size_t data_back_brush__extra_size;
+ { /* str */
+ uint64_t str__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ str__value = read_uint64(pos);
+ ptr_size = validate_SpiceString(message_start, message_end, str__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_str__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ { /* fore_brush */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 24);
+ size_t data_fore_brush_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_BRUSH_TYPE_SOLID) {
+ data_fore_brush_u__extra_size = 0;
+ } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 4);
+ size_t data_fore_brush_u_pat__extra_size;
+ { /* pat */
+ uint64_t pat__value;
+ pos = (start4 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ pat__value = read_uint64(pos);
+ if (SPICE_UNLIKELY(pat__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_fore_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_fore_brush_u__extra_size = data_fore_brush_u_pat__extra_size;
+ } else {
+ data_fore_brush_u__extra_size = 0;
+ }
+
+ }
+
+ data_fore_brush__extra_size = data_fore_brush_u__extra_size;
+ }
+
+ { /* back_brush */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 44);
+ size_t data_back_brush_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_BRUSH_TYPE_SOLID) {
+ data_back_brush_u__extra_size = 0;
+ } else if (type__value == SPICE_BRUSH_TYPE_PATTERN) {
+ SPICE_GNUC_UNUSED uint8_t *start4 = (start3 + 4);
+ size_t data_back_brush_u_pat__extra_size;
+ { /* pat */
+ uint64_t pat__value;
+ pos = (start4 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ pat__value = read_uint64(pos);
+ if (SPICE_UNLIKELY(pat__value == 0)) {
+ goto error;
+ }
+ ptr_size = validate_SpiceImage(message_start, message_end, pat__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_back_brush_u_pat__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data_back_brush_u__extra_size = data_back_brush_u_pat__extra_size;
+ } else {
+ data_back_brush_u__extra_size = 0;
+ }
+
+ }
+
+ data_back_brush__extra_size = data_back_brush_u__extra_size;
+ }
+
+ data__extra_size = data_str__extra_size + data_fore_brush__extra_size + data_back_brush__extra_size;
+ }
+
+ nw_size = 96;
+ mem_size = sizeof(SpiceMsgDisplayDrawText) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawText);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawText *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceString;
+ ptr_info[n_ptr].dest = (void **)&out->data.str;
+ n_ptr++;
+ /* back_area */ {
+ out->data.back_area.top = consume_int32(&in);
+ out->data.back_area.left = consume_int32(&in);
+ out->data.back_area.bottom = consume_int32(&in);
+ out->data.back_area.right = consume_int32(&in);
+ }
+ /* fore_brush */ {
+ uint8_t *in_save;
+ out->data.fore_brush.type = consume_uint32(&in);
+ in_save = in;
+ if (out->data.fore_brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ out->data.fore_brush.u.color = consume_uint32(&in);
+ } else if (out->data.fore_brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.fore_brush.u.pattern.pat;
+ n_ptr++;
+ /* pos */ {
+ out->data.fore_brush.u.pattern.pos.x = consume_int32(&in);
+ out->data.fore_brush.u.pattern.pos.y = consume_int32(&in);
+ }
+ }
+ in = in_save + 16;
+ }
+ /* back_brush */ {
+ uint8_t *in_save;
+ out->data.back_brush.type = consume_uint32(&in);
+ in_save = in;
+ if (out->data.back_brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ out->data.back_brush.u.color = consume_uint32(&in);
+ } else if (out->data.back_brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.back_brush.u.pattern.pat;
+ n_ptr++;
+ /* pos */ {
+ out->data.back_brush.u.pattern.pos.x = consume_int32(&in);
+ out->data.back_brush.u.pattern.pos.y = consume_int32(&in);
+ }
+ }
+ in = in_save + 16;
+ }
+ out->data.fore_mode = consume_uint16(&in);
+ out->data.back_mode = consume_uint16(&in);
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_transparent(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t base__extra_size;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawTransparent *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
+ size_t data_src_bitmap__extra_size;
+ { /* src_bitmap */
+ uint64_t src_bitmap__value;
+ pos = (start2 + 0);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data__extra_size = data_src_bitmap__extra_size;
+ }
+
+ nw_size = 60;
+ mem_size = sizeof(SpiceMsgDisplayDrawTransparent) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawTransparent);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawTransparent *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* data */ {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ /* src_area */ {
+ out->data.src_area.top = consume_int32(&in);
+ out->data.src_area.left = consume_int32(&in);
+ out->data.src_area.bottom = consume_int32(&in);
+ out->data.src_area.right = consume_int32(&in);
+ }
+ out->data.src_color = consume_uint32(&in);
+ out->data.true_color = consume_uint32(&in);
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_display_draw_alpha_blend(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t base__extra_size;
+ size_t data__extra_size;
+ SpiceMsgDisplayDrawAlphaBlend *out;
+ uint32_t i;
+
+ { /* base */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 0);
+ size_t base_clip__extra_size;
+ { /* clip */
+ SPICE_GNUC_UNUSED uint8_t *start3 = (start2 + 16);
+ size_t base_clip_u__extra_size;
+ uint32_t type__value;
+ { /* u */
+ pos = start3 + 0;
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint32(pos);
+ if (type__value == SPICE_CLIP_TYPE_RECTS) {
+ uint64_t base_clip_u_rects__value;
+ pos = (start3 + 4);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ base_clip_u_rects__value = read_uint64(pos);
+ ptr_size = validate_SpiceClipRects(message_start, message_end, base_clip_u_rects__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ base_clip_u__extra_size = ptr_size + /* for alignment */ 3;
+ } else if (1) {
+ base_clip_u__extra_size = 0;
+ } else {
+ base_clip_u__extra_size = 0;
+ }
+
+ }
+
+ base_clip__extra_size = base_clip_u__extra_size;
+ }
+
+ base__extra_size = base_clip__extra_size;
+ }
+
+ { /* data */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 28);
+ size_t data_src_bitmap__extra_size;
+ { /* src_bitmap */
+ uint64_t src_bitmap__value;
+ pos = (start2 + 1);
+ if (SPICE_UNLIKELY(pos + 8 > message_end)) {
+ goto error;
+ }
+ src_bitmap__value = read_uint64(pos);
+ ptr_size = validate_SpiceImage(message_start, message_end, src_bitmap__value, minor);
+ if (SPICE_UNLIKELY(ptr_size < 0)) {
+ goto error;
+ }
+ data_src_bitmap__extra_size = ptr_size + /* for alignment */ 3;
+ }
+
+ data__extra_size = data_src_bitmap__extra_size;
+ }
+
+ nw_size = 53;
+ mem_size = sizeof(SpiceMsgDisplayDrawAlphaBlend) + base__extra_size + data__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayDrawAlphaBlend);
+ in = start;
+
+ out = (SpiceMsgDisplayDrawAlphaBlend *)data;
+
+ /* base */ {
+ out->base.surface_id = 0;
+ /* box */ {
+ out->base.box.top = consume_int32(&in);
+ out->base.box.left = consume_int32(&in);
+ out->base.box.bottom = consume_int32(&in);
+ out->base.box.right = consume_int32(&in);
+ }
+ /* clip */ {
+ out->base.clip.type = consume_uint32(&in);
+ if (out->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceClipRects;
+ ptr_info[n_ptr].dest = (void **)&out->base.clip.rects;
+ n_ptr++;
+ } else if (1) {
+ consume_uint64(&in);
+ }
+ }
+ }
+ /* data */ {
+ out->data.alpha_flags = 0;
+ out->data.alpha = consume_uint8(&in);
+ ptr_info[n_ptr].offset = consume_uint64(&in);
+ ptr_info[n_ptr].parse = parse_struct_SpiceImage;
+ ptr_info[n_ptr].dest = (void **)&out->data.src_bitmap;
+ n_ptr++;
+ /* src_area */ {
+ out->data.src_area.top = consume_int32(&in);
+ out->data.src_area.left = consume_int32(&in);
+ out->data.src_area.bottom = consume_int32(&in);
+ out->data.src_area.right = consume_int32(&in);
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_DisplayChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[7] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify
+ };
+ static parse_msg_func_t funcs2[8] = {
+ parse_msg_display_mode,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgEmpty,
+ parse_msg_display_copy_bits,
+ parse_msg_display_inval_list,
+ parse_msg_display_inval_all_pixmaps,
+ parse_msg_display_inval_palette,
+ parse_SpiceMsgEmpty
+ };
+ static parse_msg_func_t funcs3[5] = {
+ parse_msg_display_stream_create,
+ parse_msg_display_stream_data,
+ parse_msg_display_stream_clip,
+ parse_msg_display_stream_destroy,
+ parse_SpiceMsgEmpty
+ };
+ static parse_msg_func_t funcs4[12] = {
+ parse_msg_display_draw_fill,
+ parse_msg_display_draw_opaque,
+ parse_msg_display_draw_copy,
+ parse_msg_display_draw_blend,
+ parse_msg_display_draw_blackness,
+ parse_msg_display_draw_whiteness,
+ parse_msg_display_draw_invers,
+ parse_msg_display_draw_rop3,
+ parse_msg_display_draw_stroke,
+ parse_msg_display_draw_text,
+ parse_msg_display_draw_transparent,
+ parse_msg_display_draw_alpha_blend
+ };
+ if (message_type >= 1 && message_type < 8) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 109) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 122 && message_type < 127) {
+ return funcs3[message_type-122](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 302 && message_type < 314) {
+ return funcs4[message_type-302](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msg_inputs_init(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgInputsInit *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgInputsInit);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgInputsInit);
+ in = start;
+
+ out = (SpiceMsgInputsInit *)data;
+
+ out->keyboard_modifiers = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_inputs_key_modifiers(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgInputsKeyModifiers *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgInputsKeyModifiers);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgInputsKeyModifiers);
+ in = start;
+
+ out = (SpiceMsgInputsKeyModifiers *)data;
+
+ out->modifiers = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_InputsChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[7] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify
+ };
+ static parse_msg_func_t funcs2[2] = {
+ parse_msg_inputs_init,
+ parse_msg_inputs_key_modifiers
+ };
+ static parse_msg_func_t funcs3[1] = {
+ parse_SpiceMsgEmpty
+ };
+ if (message_type >= 1 && message_type < 8) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 103) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 111 && message_type < 112) {
+ return funcs3[message_type-111](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msg_cursor_init(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t cursor__nw_size;
+ SpiceMsgCursorInit *out;
+
+ { /* cursor */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 9);
+ size_t cursor_data__nw_size;
+ uint32_t cursor_data__nelements;
+ { /* data */
+ cursor_data__nelements = message_end - (start2 + 22);
+
+ cursor_data__nw_size = cursor_data__nelements;
+ }
+
+ cursor__nw_size = 22 + cursor_data__nw_size;
+ }
+
+ nw_size = 9 + cursor__nw_size;
+ mem_size = sizeof(SpiceMsgCursorInit);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgCursorInit);
+ in = start;
+
+ out = (SpiceMsgCursorInit *)data;
+
+ /* position */ {
+ out->position.x = consume_int16(&in);
+ out->position.y = consume_int16(&in);
+ }
+ out->trail_length = consume_uint16(&in);
+ out->trail_frequency = consume_uint16(&in);
+ out->visible = consume_uint8(&in);
+ /* cursor */ {
+ uint32_t data__nelements;
+ out->cursor.flags = consume_uint32(&in);
+ /* header */ {
+ out->cursor.header.unique = consume_uint64(&in);
+ out->cursor.header.type = consume_uint16(&in);
+ out->cursor.header.width = consume_uint16(&in);
+ out->cursor.header.height = consume_uint16(&in);
+ out->cursor.header.hot_spot_x = consume_uint16(&in);
+ out->cursor.header.hot_spot_y = consume_uint16(&in);
+ }
+ data__nelements = (message_end - in) / (1);
+ /* use array as pointer */
+ out->cursor.data = (uint8_t *)in;
+ out->cursor.data_size = data__nelements;
+ in += data__nelements;
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_cursor_set(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t cursor__nw_size;
+ SpiceMsgCursorSet *out;
+
+ { /* cursor */
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 5);
+ size_t cursor_data__nw_size;
+ uint32_t cursor_data__nelements;
+ { /* data */
+ cursor_data__nelements = message_end - (start2 + 22);
+
+ cursor_data__nw_size = cursor_data__nelements;
+ }
+
+ cursor__nw_size = 22 + cursor_data__nw_size;
+ }
+
+ nw_size = 5 + cursor__nw_size;
+ mem_size = sizeof(SpiceMsgCursorSet);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgCursorSet);
+ in = start;
+
+ out = (SpiceMsgCursorSet *)data;
+
+ /* position */ {
+ out->position.x = consume_int16(&in);
+ out->position.y = consume_int16(&in);
+ }
+ out->visible = consume_uint8(&in);
+ /* cursor */ {
+ uint32_t data__nelements;
+ out->cursor.flags = consume_uint32(&in);
+ /* header */ {
+ out->cursor.header.unique = consume_uint64(&in);
+ out->cursor.header.type = consume_uint16(&in);
+ out->cursor.header.width = consume_uint16(&in);
+ out->cursor.header.height = consume_uint16(&in);
+ out->cursor.header.hot_spot_x = consume_uint16(&in);
+ out->cursor.header.hot_spot_y = consume_uint16(&in);
+ }
+ data__nelements = (message_end - in) / (1);
+ /* use array as pointer */
+ out->cursor.data = (uint8_t *)in;
+ out->cursor.data_size = data__nelements;
+ in += data__nelements;
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_cursor_move(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgCursorMove *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgCursorMove);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgCursorMove);
+ in = start;
+
+ out = (SpiceMsgCursorMove *)data;
+
+ /* position */ {
+ out->position.x = consume_int16(&in);
+ out->position.y = consume_int16(&in);
+ }
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_cursor_trail(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgCursorTrail *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgCursorTrail);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgCursorTrail);
+ in = start;
+
+ out = (SpiceMsgCursorTrail *)data;
+
+ out->length = consume_uint16(&in);
+ out->frequency = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_cursor_inval_one(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisplayInvalOne *out;
+
+ nw_size = 8;
+ mem_size = sizeof(SpiceMsgDisplayInvalOne);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisplayInvalOne);
+ in = start;
+
+ out = (SpiceMsgDisplayInvalOne *)data;
+
+ out->id = consume_uint64(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_CursorChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[7] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify
+ };
+ static parse_msg_func_t funcs2[8] = {
+ parse_msg_cursor_init,
+ parse_SpiceMsgEmpty,
+ parse_msg_cursor_set,
+ parse_msg_cursor_move,
+ parse_SpiceMsgEmpty,
+ parse_msg_cursor_trail,
+ parse_msg_cursor_inval_one,
+ parse_SpiceMsgEmpty
+ };
+ if (message_type >= 1 && message_type < 8) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 109) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msg_playback_data(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size;
+ uint32_t data__nelements;
+ SpiceMsgPlaybackPacket *out;
+
+ { /* data */
+ data__nelements = message_end - (start + 4);
+
+ data__nw_size = data__nelements;
+ }
+
+ nw_size = 4 + data__nw_size;
+ mem_size = sizeof(SpiceMsgPlaybackPacket);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgPlaybackPacket);
+ in = start;
+
+ out = (SpiceMsgPlaybackPacket *)data;
+
+ out->time = consume_uint32(&in);
+ /* use array as pointer */
+ out->data = (uint8_t *)in;
+ out->data_size = data__nelements;
+ in += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_playback_mode(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size;
+ uint32_t data__nelements;
+ SpiceMsgPlaybackMode *out;
+
+ { /* data */
+ data__nelements = message_end - (start + 8);
+
+ data__nw_size = data__nelements;
+ }
+
+ nw_size = 8 + data__nw_size;
+ mem_size = sizeof(SpiceMsgPlaybackMode);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgPlaybackMode);
+ in = start;
+
+ out = (SpiceMsgPlaybackMode *)data;
+
+ out->time = consume_uint32(&in);
+ out->mode = consume_uint32(&in);
+ /* use array as pointer */
+ out->data = (uint8_t *)in;
+ out->data_size = data__nelements;
+ in += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msg_playback_start(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgPlaybackStart *out;
+
+ nw_size = 16;
+ mem_size = sizeof(SpiceMsgPlaybackStart);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgPlaybackStart);
+ in = start;
+
+ out = (SpiceMsgPlaybackStart *)data;
+
+ out->channels = consume_uint32(&in);
+ out->format = consume_uint32(&in);
+ out->frequency = consume_uint32(&in);
+ out->time = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_PlaybackChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[7] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify
+ };
+ static parse_msg_func_t funcs2[4] = {
+ parse_msg_playback_data,
+ parse_msg_playback_mode,
+ parse_msg_playback_start,
+ parse_SpiceMsgEmpty
+ };
+ if (message_type >= 1 && message_type < 8) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 105) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msg_record_start(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgRecordStart *out;
+
+ nw_size = 12;
+ mem_size = sizeof(SpiceMsgRecordStart);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgRecordStart);
+ in = start;
+
+ out = (SpiceMsgRecordStart *)data;
+
+ out->channels = consume_uint32(&in);
+ out->format = consume_uint32(&in);
+ out->frequency = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_RecordChannel_msg(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[7] = {
+ parse_msg_migrate,
+ parse_SpiceMsgData,
+ parse_msg_set_ack,
+ parse_msg_ping,
+ parse_msg_wait_for_channels,
+ parse_msg_disconnecting,
+ parse_msg_notify
+ };
+ static parse_msg_func_t funcs2[2] = {
+ parse_msg_record_start,
+ parse_SpiceMsgEmpty
+ };
+ if (message_type >= 1 && message_type < 8) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 103) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+spice_parse_channel_func_t spice_get_server_channel_parser1(uint32_t channel, unsigned int *max_message_type)
+{
+ static struct {spice_parse_channel_func_t func; unsigned int max_messages; } channels[7] = {
+ { NULL, 0 },
+ { parse_MainChannel_msg, 111},
+ { parse_DisplayChannel_msg, 313},
+ { parse_InputsChannel_msg, 111},
+ { parse_CursorChannel_msg, 108},
+ { parse_PlaybackChannel_msg, 104},
+ { parse_RecordChannel_msg, 102}
+ };
+ if (channel < 7) {
+ if (max_message_type != NULL) {
+ *max_message_type = channels[channel].max_messages;
+ }
+ return channels[channel].func;
+ }
+ return NULL;
+}
+
+uint8_t * spice_parse_msg1(uint8_t *message_start, uint8_t *message_end, uint32_t channel, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ spice_parse_channel_func_t func;
+ func = spice_get_server_channel_parser1(channel, NULL);
+ if (func != NULL) {
+ return func(message_start, message_end, message_type, minor, size_out, free_message);
+ }
+ return NULL;
+}
--- /dev/null
+/* this is a file autogenerated by spice_codegen.py */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "client_marshallers.h"
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <spice/protocol.h>
+#include <spice/macros.h>
+#include "common/marshaller.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable:4101)
+#pragma warning(disable:4018)
+#endif
+
+static void spice_marshall_msgc_ack_sync(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcAckSync *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcAckSync *src;
+ src = (SpiceMsgcAckSync *)msg;
+
+ spice_marshaller_add_uint32(m, src->generation);
+}
+
+static void spice_marshall_SpiceMsgEmpty(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgEmpty *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+}
+
+static void spice_marshall_msgc_pong(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgPing *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgPing *src;
+ src = (SpiceMsgPing *)msg;
+
+ spice_marshaller_add_uint32(m, src->id);
+ spice_marshaller_add_uint64(m, src->timestamp);
+}
+
+static void spice_marshall_SpiceMsgData(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgData *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+}
+
+static void spice_marshall_msgc_disconnecting(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisconnect *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisconnect *src;
+ src = (SpiceMsgDisconnect *)msg;
+
+ spice_marshaller_add_uint64(m, src->time_stamp);
+ spice_marshaller_add_uint32(m, src->reason);
+}
+
+static void spice_marshall_msgc_main_client_info(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcClientInfo *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcClientInfo *src;
+ src = (SpiceMsgcClientInfo *)msg;
+
+ spice_marshaller_add_uint64(m, src->cache_size);
+}
+
+static void spice_marshall_msgc_main_mouse_mode_request(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMainMouseModeRequest *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMainMouseModeRequest *src;
+ src = (SpiceMsgcMainMouseModeRequest *)msg;
+
+ spice_marshaller_add_uint16(m, src->mode);
+}
+
+static void spice_marshall_msgc_main_agent_start(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMainAgentStart *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMainAgentStart *src;
+ src = (SpiceMsgcMainAgentStart *)msg;
+
+ spice_marshaller_add_uint32(m, src->num_tokens);
+}
+
+static void spice_marshall_msgc_main_agent_token(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMainAgentTokens *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMainAgentTokens *src;
+ src = (SpiceMsgcMainAgentTokens *)msg;
+
+ spice_marshaller_add_uint32(m, src->num_tokens);
+}
+
+static void spice_marshall_msgc_main_migrate_dst_do_seamless(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMainMigrateDstDoSeamless *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMainMigrateDstDoSeamless *src;
+ src = (SpiceMsgcMainMigrateDstDoSeamless *)msg;
+
+ spice_marshaller_add_uint32(m, src->src_version);
+}
+
+static void spice_marshall_msgc_display_init(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcDisplayInit *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcDisplayInit *src;
+ src = (SpiceMsgcDisplayInit *)msg;
+
+ spice_marshaller_add_uint8(m, src->pixmap_cache_id);
+ spice_marshaller_add_int64(m, src->pixmap_cache_size);
+ spice_marshaller_add_uint8(m, src->glz_dictionary_id);
+ spice_marshaller_add_int32(m, src->glz_dictionary_window_size);
+}
+
+static void spice_marshall_msgc_display_stream_report(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcDisplayStreamReport *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcDisplayStreamReport *src;
+ src = (SpiceMsgcDisplayStreamReport *)msg;
+
+ spice_marshaller_add_uint32(m, src->stream_id);
+ spice_marshaller_add_uint32(m, src->unique_id);
+ spice_marshaller_add_uint32(m, src->start_frame_mm_time);
+ spice_marshaller_add_uint32(m, src->end_frame_mm_time);
+ spice_marshaller_add_uint32(m, src->num_frames);
+ spice_marshaller_add_uint32(m, src->num_drops);
+ spice_marshaller_add_int32(m, src->last_frame_delay);
+ spice_marshaller_add_uint32(m, src->audio_delay);
+}
+
+static void spice_marshall_msgc_display_preferred_compression(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcDisplayPreferredCompression *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcDisplayPreferredCompression *src;
+ src = (SpiceMsgcDisplayPreferredCompression *)msg;
+
+ spice_marshaller_add_uint8(m, src->image_compression);
+}
+
+static void spice_marshall_msgc_display_gl_draw_done(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcDisplayGlDrawDone *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+}
+
+static void spice_marshall_msgc_inputs_key_down(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcKeyDown *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcKeyDown *src;
+ src = (SpiceMsgcKeyDown *)msg;
+
+ spice_marshaller_add_uint32(m, src->code);
+}
+
+static void spice_marshall_msgc_inputs_key_up(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcKeyUp *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcKeyUp *src;
+ src = (SpiceMsgcKeyUp *)msg;
+
+ spice_marshaller_add_uint32(m, src->code);
+}
+
+static void spice_marshall_msgc_inputs_key_modifiers(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcKeyModifiers *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcKeyModifiers *src;
+ src = (SpiceMsgcKeyModifiers *)msg;
+
+ spice_marshaller_add_uint16(m, src->modifiers);
+}
+
+static void spice_marshall_msgc_inputs_mouse_motion(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMouseMotion *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMouseMotion *src;
+ src = (SpiceMsgcMouseMotion *)msg;
+
+ spice_marshaller_add_int32(m, src->dx);
+ spice_marshaller_add_int32(m, src->dy);
+ spice_marshaller_add_uint16(m, src->buttons_state);
+}
+
+static void spice_marshall_msgc_inputs_mouse_position(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMousePosition *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMousePosition *src;
+ src = (SpiceMsgcMousePosition *)msg;
+
+ spice_marshaller_add_uint32(m, src->x);
+ spice_marshaller_add_uint32(m, src->y);
+ spice_marshaller_add_uint16(m, src->buttons_state);
+ spice_marshaller_add_uint8(m, src->display_id);
+}
+
+static void spice_marshall_msgc_inputs_mouse_press(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMousePress *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMousePress *src;
+ src = (SpiceMsgcMousePress *)msg;
+
+ spice_marshaller_add_uint8(m, src->button);
+ spice_marshaller_add_uint16(m, src->buttons_state);
+}
+
+static void spice_marshall_msgc_inputs_mouse_release(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMouseRelease *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMouseRelease *src;
+ src = (SpiceMsgcMouseRelease *)msg;
+
+ spice_marshaller_add_uint8(m, src->button);
+ spice_marshaller_add_uint16(m, src->buttons_state);
+}
+
+static void spice_marshall_msgc_record_data(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcRecordPacket *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcRecordPacket *src;
+ src = (SpiceMsgcRecordPacket *)msg;
+
+ spice_marshaller_add_uint32(m, src->time);
+ /* Don't marshall @nomarshal data */
+}
+
+static void spice_marshall_msgc_record_mode(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcRecordMode *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcRecordMode *src;
+ src = (SpiceMsgcRecordMode *)msg;
+
+ spice_marshaller_add_uint32(m, src->time);
+ spice_marshaller_add_uint16(m, src->mode);
+ /* Remaining data must be appended manually */
+}
+
+static void spice_marshall_msgc_record_start_mark(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcRecordStartMark *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcRecordStartMark *src;
+ src = (SpiceMsgcRecordStartMark *)msg;
+
+ spice_marshaller_add_uint32(m, src->time);
+}
+
+SPICE_GNUC_UNUSED static void spice_marshall_array_uint8(SpiceMarshaller *m, uint8_t *ptr, unsigned count)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ uint32_t i;
+
+ for (i = 0; i < count; i++) {
+ spice_marshaller_add_uint8(m, *ptr++);
+ }
+}
+
+static void spice_marshall_msgc_tunnel_service_add(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcTunnelAddGenericService *msg, SpiceMarshaller **name_out, SpiceMarshaller **description_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcTunnelAddGenericService *src;
+ uint32_t i;
+ *name_out = NULL;
+ *description_out = NULL;
+ src = (SpiceMsgcTunnelAddGenericService *)msg;
+
+ spice_marshaller_add_uint16(m, src->type);
+ spice_marshaller_add_uint32(m, src->id);
+ spice_marshaller_add_uint32(m, src->group);
+ spice_marshaller_add_uint32(m, src->port);
+ *name_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ *description_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ if (src->type == SPICE_TUNNEL_SERVICE_TYPE_IPP) {
+ uint8_t *ipv4__element;
+ spice_marshaller_add_uint16(m, src->u.ip.type);
+ if (src->u.ip.type == SPICE_TUNNEL_IP_TYPE_IPv4) {
+ ipv4__element = src->u.ip.u.ipv4;
+ for (i = 0; i < 4; i++) {
+ spice_marshaller_add_uint8(m, *ipv4__element);
+ ipv4__element++;
+ }
+ }
+ }
+}
+
+static void spice_marshall_msgc_tunnel_service_remove(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcTunnelRemoveService *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcTunnelRemoveService *src;
+ src = (SpiceMsgcTunnelRemoveService *)msg;
+
+ spice_marshaller_add_uint32(m, src->id);
+}
+
+static void spice_marshall_msgc_tunnel_socket_open_ack(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcTunnelSocketOpenAck *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcTunnelSocketOpenAck *src;
+ src = (SpiceMsgcTunnelSocketOpenAck *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+ spice_marshaller_add_uint32(m, src->tokens);
+}
+
+static void spice_marshall_msgc_tunnel_socket_open_nack(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcTunnelSocketOpenNack *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcTunnelSocketOpenNack *src;
+ src = (SpiceMsgcTunnelSocketOpenNack *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+}
+
+static void spice_marshall_msgc_tunnel_socket_fin(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcTunnelSocketFin *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcTunnelSocketFin *src;
+ src = (SpiceMsgcTunnelSocketFin *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+}
+
+static void spice_marshall_msgc_tunnel_socket_closed(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcTunnelSocketClosed *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcTunnelSocketClosed *src;
+ src = (SpiceMsgcTunnelSocketClosed *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+}
+
+static void spice_marshall_msgc_tunnel_socket_closed_ack(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcTunnelSocketClosedAck *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcTunnelSocketClosedAck *src;
+ src = (SpiceMsgcTunnelSocketClosedAck *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+}
+
+static void spice_marshall_msgc_tunnel_socket_data(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcTunnelSocketData *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcTunnelSocketData *src;
+ src = (SpiceMsgcTunnelSocketData *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+ /* Remaining data must be appended manually */
+}
+
+static void spice_marshall_msgc_tunnel_socket_token(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcTunnelSocketTokens *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcTunnelSocketTokens *src;
+ src = (SpiceMsgcTunnelSocketTokens *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+ spice_marshaller_add_uint32(m, src->num_tokens);
+}
+
+#ifdef USE_SMARTCARD
+static void spice_marshall_msgc_smartcard_data(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcSmartcard *msg, SpiceMarshaller **reader_name_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcSmartcard *src;
+ *reader_name_out = NULL;
+ src = (SpiceMsgcSmartcard *)msg;
+
+ /* header */ {
+ spice_marshaller_add_uint32(m, src->header.type);
+ spice_marshaller_add_uint32(m, src->header.reader_id);
+ spice_marshaller_add_uint32(m, src->header.length);
+ }
+ if (src->header.type == SPICE_VSC_MESSAGE_TYPE_ReaderAdd) {
+ /* Don't marshall @nomarshal reader_name */
+ } else if (src->header.type == SPICE_VSC_MESSAGE_TYPE_ATR || src->header.type == SPICE_VSC_MESSAGE_TYPE_APDU) {
+ /* Remaining data must be appended manually */
+ } else if (src->header.type == SPICE_VSC_MESSAGE_TYPE_Error) {
+ spice_marshaller_add_uint32(m, src->error.code);
+ }
+}
+
+static void spice_marshall_msgc_smartcard_header(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED VSCMsgHeader *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ VSCMsgHeader *src;
+ src = (VSCMsgHeader *)msg;
+
+ spice_marshaller_add_uint32(m, src->type);
+ spice_marshaller_add_uint32(m, src->reader_id);
+ spice_marshaller_add_uint32(m, src->length);
+}
+
+static void spice_marshall_msgc_smartcard_error(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED VSCMsgError *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ VSCMsgError *src;
+ src = (VSCMsgError *)msg;
+
+ spice_marshaller_add_uint32(m, src->code);
+}
+
+static void spice_marshall_msgc_smartcard_atr(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED VSCMsgATR *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+}
+
+static void spice_marshall_msgc_smartcard_reader_add(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED VSCMsgReaderAdd *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+}
+
+#endif /* USE_SMARTCARD */
+static void spice_marshall_SpiceMsgCompressedData(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgCompressedData *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgCompressedData *src;
+ src = (SpiceMsgCompressedData *)msg;
+
+ spice_marshaller_add_uint8(m, src->type);
+ if (src->type == SPICE_DATA_COMPRESSION_TYPE_NONE) {
+ } else if (1) {
+ spice_marshaller_add_uint32(m, src->uncompressed_size);
+ }
+ /* Remaining data must be appended manually */
+}
+
+static void spice_marshall_msgc_port_event(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcPortEvent *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcPortEvent *src;
+ src = (SpiceMsgcPortEvent *)msg;
+
+ spice_marshaller_add_uint8(m, src->event);
+}
+
+SpiceMessageMarshallers * spice_message_marshallers_get(void)
+{
+ static SpiceMessageMarshallers marshallers = {NULL};
+
+ marshallers.msg_SpiceMsgCompressedData = spice_marshall_SpiceMsgCompressedData;
+ marshallers.msg_SpiceMsgData = spice_marshall_SpiceMsgData;
+ marshallers.msg_SpiceMsgEmpty = spice_marshall_SpiceMsgEmpty;
+ marshallers.msgc_ack_sync = spice_marshall_msgc_ack_sync;
+ marshallers.msgc_disconnecting = spice_marshall_msgc_disconnecting;
+ marshallers.msgc_display_gl_draw_done = spice_marshall_msgc_display_gl_draw_done;
+ marshallers.msgc_display_init = spice_marshall_msgc_display_init;
+ marshallers.msgc_display_preferred_compression = spice_marshall_msgc_display_preferred_compression;
+ marshallers.msgc_display_stream_report = spice_marshall_msgc_display_stream_report;
+ marshallers.msgc_inputs_key_down = spice_marshall_msgc_inputs_key_down;
+ marshallers.msgc_inputs_key_modifiers = spice_marshall_msgc_inputs_key_modifiers;
+ marshallers.msgc_inputs_key_up = spice_marshall_msgc_inputs_key_up;
+ marshallers.msgc_inputs_mouse_motion = spice_marshall_msgc_inputs_mouse_motion;
+ marshallers.msgc_inputs_mouse_position = spice_marshall_msgc_inputs_mouse_position;
+ marshallers.msgc_inputs_mouse_press = spice_marshall_msgc_inputs_mouse_press;
+ marshallers.msgc_inputs_mouse_release = spice_marshall_msgc_inputs_mouse_release;
+ marshallers.msgc_main_agent_start = spice_marshall_msgc_main_agent_start;
+ marshallers.msgc_main_agent_token = spice_marshall_msgc_main_agent_token;
+ marshallers.msgc_main_client_info = spice_marshall_msgc_main_client_info;
+ marshallers.msgc_main_migrate_dst_do_seamless = spice_marshall_msgc_main_migrate_dst_do_seamless;
+ marshallers.msgc_main_mouse_mode_request = spice_marshall_msgc_main_mouse_mode_request;
+ marshallers.msgc_pong = spice_marshall_msgc_pong;
+ marshallers.msgc_port_event = spice_marshall_msgc_port_event;
+ marshallers.msgc_record_data = spice_marshall_msgc_record_data;
+ marshallers.msgc_record_mode = spice_marshall_msgc_record_mode;
+ marshallers.msgc_record_start_mark = spice_marshall_msgc_record_start_mark;
+#ifdef USE_SMARTCARD
+ marshallers.msgc_smartcard_atr = spice_marshall_msgc_smartcard_atr;
+#endif /* USE_SMARTCARD */
+#ifdef USE_SMARTCARD
+ marshallers.msgc_smartcard_data = spice_marshall_msgc_smartcard_data;
+#endif /* USE_SMARTCARD */
+#ifdef USE_SMARTCARD
+ marshallers.msgc_smartcard_error = spice_marshall_msgc_smartcard_error;
+#endif /* USE_SMARTCARD */
+#ifdef USE_SMARTCARD
+ marshallers.msgc_smartcard_header = spice_marshall_msgc_smartcard_header;
+#endif /* USE_SMARTCARD */
+#ifdef USE_SMARTCARD
+ marshallers.msgc_smartcard_reader_add = spice_marshall_msgc_smartcard_reader_add;
+#endif /* USE_SMARTCARD */
+ marshallers.msgc_tunnel_service_add = spice_marshall_msgc_tunnel_service_add;
+ marshallers.msgc_tunnel_service_remove = spice_marshall_msgc_tunnel_service_remove;
+ marshallers.msgc_tunnel_socket_closed = spice_marshall_msgc_tunnel_socket_closed;
+ marshallers.msgc_tunnel_socket_closed_ack = spice_marshall_msgc_tunnel_socket_closed_ack;
+ marshallers.msgc_tunnel_socket_data = spice_marshall_msgc_tunnel_socket_data;
+ marshallers.msgc_tunnel_socket_fin = spice_marshall_msgc_tunnel_socket_fin;
+ marshallers.msgc_tunnel_socket_open_ack = spice_marshall_msgc_tunnel_socket_open_ack;
+ marshallers.msgc_tunnel_socket_open_nack = spice_marshall_msgc_tunnel_socket_open_nack;
+ marshallers.msgc_tunnel_socket_token = spice_marshall_msgc_tunnel_socket_token;
+
+ return &marshallers;
+}
+
--- /dev/null
+/* this is a file autogenerated by spice_codegen.py */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "common/messages.h"
+#include <spice/protocol.h>
+#include "common/marshaller.h"
+
+#ifndef _H_GENERATED_CLIENT_MARSHALLERS
+#define _H_GENERATED_CLIENT_MARSHALLERS
+
+SPICE_BEGIN_DECLS
+
+typedef struct {
+ void (*msgc_ack_sync)(SpiceMarshaller *m, SpiceMsgcAckSync *msg);
+ void (*msg_SpiceMsgEmpty)(SpiceMarshaller *m, SpiceMsgEmpty *msg);
+ void (*msgc_pong)(SpiceMarshaller *m, SpiceMsgPing *msg);
+ void (*msg_SpiceMsgData)(SpiceMarshaller *m, SpiceMsgData *msg);
+ void (*msgc_disconnecting)(SpiceMarshaller *m, SpiceMsgDisconnect *msg);
+ void (*msgc_main_client_info)(SpiceMarshaller *m, SpiceMsgcClientInfo *msg);
+ void (*msgc_main_mouse_mode_request)(SpiceMarshaller *m, SpiceMsgcMainMouseModeRequest *msg);
+ void (*msgc_main_agent_start)(SpiceMarshaller *m, SpiceMsgcMainAgentStart *msg);
+ void (*msgc_main_agent_token)(SpiceMarshaller *m, SpiceMsgcMainAgentTokens *msg);
+ void (*msgc_main_migrate_dst_do_seamless)(SpiceMarshaller *m, SpiceMsgcMainMigrateDstDoSeamless *msg);
+ void (*msgc_display_init)(SpiceMarshaller *m, SpiceMsgcDisplayInit *msg);
+ void (*msgc_display_stream_report)(SpiceMarshaller *m, SpiceMsgcDisplayStreamReport *msg);
+ void (*msgc_display_preferred_compression)(SpiceMarshaller *m, SpiceMsgcDisplayPreferredCompression *msg);
+ void (*msgc_display_gl_draw_done)(SpiceMarshaller *m, SpiceMsgcDisplayGlDrawDone *msg);
+ void (*msgc_inputs_key_down)(SpiceMarshaller *m, SpiceMsgcKeyDown *msg);
+ void (*msgc_inputs_key_up)(SpiceMarshaller *m, SpiceMsgcKeyUp *msg);
+ void (*msgc_inputs_key_modifiers)(SpiceMarshaller *m, SpiceMsgcKeyModifiers *msg);
+ void (*msgc_inputs_mouse_motion)(SpiceMarshaller *m, SpiceMsgcMouseMotion *msg);
+ void (*msgc_inputs_mouse_position)(SpiceMarshaller *m, SpiceMsgcMousePosition *msg);
+ void (*msgc_inputs_mouse_press)(SpiceMarshaller *m, SpiceMsgcMousePress *msg);
+ void (*msgc_inputs_mouse_release)(SpiceMarshaller *m, SpiceMsgcMouseRelease *msg);
+ void (*msgc_record_data)(SpiceMarshaller *m, SpiceMsgcRecordPacket *msg);
+ void (*msgc_record_mode)(SpiceMarshaller *m, SpiceMsgcRecordMode *msg);
+ void (*msgc_record_start_mark)(SpiceMarshaller *m, SpiceMsgcRecordStartMark *msg);
+ void (*msgc_tunnel_service_add)(SpiceMarshaller *m, SpiceMsgcTunnelAddGenericService *msg, SpiceMarshaller **name_out, SpiceMarshaller **description_out);
+ void (*msgc_tunnel_service_remove)(SpiceMarshaller *m, SpiceMsgcTunnelRemoveService *msg);
+ void (*msgc_tunnel_socket_open_ack)(SpiceMarshaller *m, SpiceMsgcTunnelSocketOpenAck *msg);
+ void (*msgc_tunnel_socket_open_nack)(SpiceMarshaller *m, SpiceMsgcTunnelSocketOpenNack *msg);
+ void (*msgc_tunnel_socket_fin)(SpiceMarshaller *m, SpiceMsgcTunnelSocketFin *msg);
+ void (*msgc_tunnel_socket_closed)(SpiceMarshaller *m, SpiceMsgcTunnelSocketClosed *msg);
+ void (*msgc_tunnel_socket_closed_ack)(SpiceMarshaller *m, SpiceMsgcTunnelSocketClosedAck *msg);
+ void (*msgc_tunnel_socket_data)(SpiceMarshaller *m, SpiceMsgcTunnelSocketData *msg);
+ void (*msgc_tunnel_socket_token)(SpiceMarshaller *m, SpiceMsgcTunnelSocketTokens *msg);
+#ifdef USE_SMARTCARD
+ void (*msgc_smartcard_data)(SpiceMarshaller *m, SpiceMsgcSmartcard *msg, SpiceMarshaller **reader_name_out);
+ void (*msgc_smartcard_header)(SpiceMarshaller *m, VSCMsgHeader *msg);
+ void (*msgc_smartcard_error)(SpiceMarshaller *m, VSCMsgError *msg);
+ void (*msgc_smartcard_atr)(SpiceMarshaller *m, VSCMsgATR *msg);
+ void (*msgc_smartcard_reader_add)(SpiceMarshaller *m, VSCMsgReaderAdd *msg);
+#endif /* USE_SMARTCARD */
+ void (*msg_SpiceMsgCompressedData)(SpiceMarshaller *m, SpiceMsgCompressedData *msg);
+ void (*msgc_port_event)(SpiceMarshaller *m, SpiceMsgcPortEvent *msg);
+} SpiceMessageMarshallers;
+
+SpiceMessageMarshallers *spice_message_marshallers_get(void);
+
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/* this is a file autogenerated by spice_codegen.py */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "common/messages.h"
+#include "client_marshallers.h"
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <spice/protocol.h>
+#include <spice/macros.h>
+#include "common/marshaller.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable:4101)
+#pragma warning(disable:4018)
+#endif
+
+static void spice_marshall_msgc_ack_sync(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcAckSync *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcAckSync *src;
+ src = (SpiceMsgcAckSync *)msg;
+
+ spice_marshaller_add_uint32(m, src->generation);
+}
+
+static void spice_marshall_SpiceMsgEmpty(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgEmpty *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+}
+
+static void spice_marshall_msgc_pong(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgPing *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgPing *src;
+ src = (SpiceMsgPing *)msg;
+
+ spice_marshaller_add_uint32(m, src->id);
+ spice_marshaller_add_uint64(m, src->timestamp);
+}
+
+static void spice_marshall_SpiceMsgData(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgData *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+}
+
+static void spice_marshall_msgc_disconnecting(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisconnect *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisconnect *src;
+ src = (SpiceMsgDisconnect *)msg;
+
+ spice_marshaller_add_uint64(m, src->time_stamp);
+ spice_marshaller_add_uint32(m, src->reason);
+}
+
+static void spice_marshall_msgc_main_client_info(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcClientInfo *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcClientInfo *src;
+ src = (SpiceMsgcClientInfo *)msg;
+
+ spice_marshaller_add_uint64(m, src->cache_size);
+}
+
+static void spice_marshall_msgc_main_mouse_mode_request(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMainMouseModeRequest *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMainMouseModeRequest *src;
+ src = (SpiceMsgcMainMouseModeRequest *)msg;
+
+ spice_marshaller_add_uint32(m, src->mode);
+}
+
+static void spice_marshall_msgc_main_agent_start(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMainAgentStart *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMainAgentStart *src;
+ src = (SpiceMsgcMainAgentStart *)msg;
+
+ spice_marshaller_add_uint32(m, src->num_tokens);
+}
+
+static void spice_marshall_msgc_main_agent_token(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMainAgentTokens *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMainAgentTokens *src;
+ src = (SpiceMsgcMainAgentTokens *)msg;
+
+ spice_marshaller_add_uint32(m, src->num_tokens);
+}
+
+static void spice_marshall_msgc_display_init(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcDisplayInit *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcDisplayInit *src;
+ src = (SpiceMsgcDisplayInit *)msg;
+
+ spice_marshaller_add_uint8(m, src->pixmap_cache_id);
+ spice_marshaller_add_int64(m, src->pixmap_cache_size);
+ spice_marshaller_add_uint8(m, src->glz_dictionary_id);
+ spice_marshaller_add_int32(m, src->glz_dictionary_window_size);
+}
+
+static void spice_marshall_msgc_inputs_key_down(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcKeyDown *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcKeyDown *src;
+ src = (SpiceMsgcKeyDown *)msg;
+
+ spice_marshaller_add_uint32(m, src->code);
+}
+
+static void spice_marshall_msgc_inputs_key_up(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcKeyUp *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcKeyUp *src;
+ src = (SpiceMsgcKeyUp *)msg;
+
+ spice_marshaller_add_uint32(m, src->code);
+}
+
+static void spice_marshall_msgc_inputs_key_modifiers(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcKeyModifiers *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcKeyModifiers *src;
+ src = (SpiceMsgcKeyModifiers *)msg;
+
+ spice_marshaller_add_uint32(m, src->modifiers);
+}
+
+static void spice_marshall_msgc_inputs_mouse_motion(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMouseMotion *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMouseMotion *src;
+ src = (SpiceMsgcMouseMotion *)msg;
+
+ spice_marshaller_add_int32(m, src->dx);
+ spice_marshaller_add_int32(m, src->dy);
+ spice_marshaller_add_uint32(m, src->buttons_state);
+}
+
+static void spice_marshall_msgc_inputs_mouse_position(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMousePosition *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMousePosition *src;
+ src = (SpiceMsgcMousePosition *)msg;
+
+ spice_marshaller_add_uint32(m, src->x);
+ spice_marshaller_add_uint32(m, src->y);
+ spice_marshaller_add_uint32(m, src->buttons_state);
+ spice_marshaller_add_uint8(m, src->display_id);
+}
+
+static void spice_marshall_msgc_inputs_mouse_press(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMousePress *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMousePress *src;
+ src = (SpiceMsgcMousePress *)msg;
+
+ spice_marshaller_add_uint32(m, src->button);
+ spice_marshaller_add_uint32(m, src->buttons_state);
+}
+
+static void spice_marshall_msgc_inputs_mouse_release(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcMouseRelease *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcMouseRelease *src;
+ src = (SpiceMsgcMouseRelease *)msg;
+
+ spice_marshaller_add_uint32(m, src->button);
+ spice_marshaller_add_uint32(m, src->buttons_state);
+}
+
+static void spice_marshall_msgc_record_data(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcRecordPacket *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcRecordPacket *src;
+ src = (SpiceMsgcRecordPacket *)msg;
+
+ spice_marshaller_add_uint32(m, src->time);
+ /* Don't marshall @nomarshal data */
+}
+
+static void spice_marshall_msgc_record_mode(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcRecordMode *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcRecordMode *src;
+ src = (SpiceMsgcRecordMode *)msg;
+
+ spice_marshaller_add_uint32(m, src->time);
+ spice_marshaller_add_uint32(m, src->mode);
+ /* Remaining data must be appended manually */
+}
+
+static void spice_marshall_msgc_record_start_mark(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgcRecordStartMark *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgcRecordStartMark *src;
+ src = (SpiceMsgcRecordStartMark *)msg;
+
+ spice_marshaller_add_uint32(m, src->time);
+}
+
+SpiceMessageMarshallers * spice_message_marshallers_get1(void)
+{
+ static SpiceMessageMarshallers marshallers = {NULL};
+
+ marshallers.msg_SpiceMsgData = spice_marshall_SpiceMsgData;
+ marshallers.msg_SpiceMsgEmpty = spice_marshall_SpiceMsgEmpty;
+ marshallers.msgc_ack_sync = spice_marshall_msgc_ack_sync;
+ marshallers.msgc_disconnecting = spice_marshall_msgc_disconnecting;
+ marshallers.msgc_display_init = spice_marshall_msgc_display_init;
+ marshallers.msgc_inputs_key_down = spice_marshall_msgc_inputs_key_down;
+ marshallers.msgc_inputs_key_modifiers = spice_marshall_msgc_inputs_key_modifiers;
+ marshallers.msgc_inputs_key_up = spice_marshall_msgc_inputs_key_up;
+ marshallers.msgc_inputs_mouse_motion = spice_marshall_msgc_inputs_mouse_motion;
+ marshallers.msgc_inputs_mouse_position = spice_marshall_msgc_inputs_mouse_position;
+ marshallers.msgc_inputs_mouse_press = spice_marshall_msgc_inputs_mouse_press;
+ marshallers.msgc_inputs_mouse_release = spice_marshall_msgc_inputs_mouse_release;
+ marshallers.msgc_main_agent_start = spice_marshall_msgc_main_agent_start;
+ marshallers.msgc_main_agent_token = spice_marshall_msgc_main_agent_token;
+ marshallers.msgc_main_client_info = spice_marshall_msgc_main_client_info;
+ marshallers.msgc_main_mouse_mode_request = spice_marshall_msgc_main_mouse_mode_request;
+ marshallers.msgc_pong = spice_marshall_msgc_pong;
+ marshallers.msgc_record_data = spice_marshall_msgc_record_data;
+ marshallers.msgc_record_mode = spice_marshall_msgc_record_mode;
+ marshallers.msgc_record_start_mark = spice_marshall_msgc_record_start_mark;
+
+ return &marshallers;
+}
+
--- /dev/null
+/* this is a file autogenerated by spice_codegen.py */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "common/messages.h"
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <spice/protocol.h>
+#include <spice/macros.h>
+#include <common/mem.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable:4101)
+#endif
+
+
+
+#ifdef WORDS_BIGENDIAN
+#define read_int8(ptr) (*((int8_t *)(ptr)))
+#define write_int8(ptr, val) *(int8_t *)(ptr) = val
+#define read_uint8(ptr) (*((uint8_t *)(ptr)))
+#define write_uint8(ptr, val) *(uint8_t *)(ptr) = val
+#define read_int16(ptr) ((int16_t)SPICE_BYTESWAP16(*((uint16_t *)(ptr))))
+#define write_int16(ptr, val) *(uint16_t *)(ptr) = SPICE_BYTESWAP16((uint16_t)val)
+#define read_uint16(ptr) ((uint16_t)SPICE_BYTESWAP16(*((uint16_t *)(ptr))))
+#define write_uint16(ptr, val) *(uint16_t *)(ptr) = SPICE_BYTESWAP16((uint16_t)val)
+#define read_int32(ptr) ((int32_t)SPICE_BYTESWAP32(*((uint32_t *)(ptr))))
+#define write_int32(ptr, val) *(uint32_t *)(ptr) = SPICE_BYTESWAP32((uint32_t)val)
+#define read_uint32(ptr) ((uint32_t)SPICE_BYTESWAP32(*((uint32_t *)(ptr))))
+#define write_uint32(ptr, val) *(uint32_t *)(ptr) = SPICE_BYTESWAP32((uint32_t)val)
+#define read_int64(ptr) ((int64_t)SPICE_BYTESWAP64(*((uint64_t *)(ptr))))
+#define write_int64(ptr, val) *(uint64_t *)(ptr) = SPICE_BYTESWAP64((uint64_t)val)
+#define read_uint64(ptr) ((uint64_t)SPICE_BYTESWAP64(*((uint64_t *)(ptr))))
+#define write_uint64(ptr, val) *(uint64_t *)(ptr) = SPICE_BYTESWAP64((uint64_t)val)
+#else
+#define read_int8(ptr) (*((int8_t *)(ptr)))
+#define write_int8(ptr, val) (*((int8_t *)(ptr))) = val
+#define read_uint8(ptr) (*((uint8_t *)(ptr)))
+#define write_uint8(ptr, val) (*((uint8_t *)(ptr))) = val
+#define read_int16(ptr) (*((int16_t *)(ptr)))
+#define write_int16(ptr, val) (*((int16_t *)(ptr))) = val
+#define read_uint16(ptr) (*((uint16_t *)(ptr)))
+#define write_uint16(ptr, val) (*((uint16_t *)(ptr))) = val
+#define read_int32(ptr) (*((int32_t *)(ptr)))
+#define write_int32(ptr, val) (*((int32_t *)(ptr))) = val
+#define read_uint32(ptr) (*((uint32_t *)(ptr)))
+#define write_uint32(ptr, val) (*((uint32_t *)(ptr))) = val
+#define read_int64(ptr) (*((int64_t *)(ptr)))
+#define write_int64(ptr, val) (*((int64_t *)(ptr))) = val
+#define read_uint64(ptr) (*((uint64_t *)(ptr)))
+#define write_uint64(ptr, val) (*((uint64_t *)(ptr))) = val
+#endif
+
+static int8_t SPICE_GNUC_UNUSED consume_int8(uint8_t **ptr)
+{
+ int8_t val;
+ val = read_int8(*ptr);
+ *ptr += 1;
+ return val;
+}
+
+static uint8_t SPICE_GNUC_UNUSED consume_uint8(uint8_t **ptr)
+{
+ uint8_t val;
+ val = read_uint8(*ptr);
+ *ptr += 1;
+ return val;
+}
+
+static int16_t SPICE_GNUC_UNUSED consume_int16(uint8_t **ptr)
+{
+ int16_t val;
+ val = read_int16(*ptr);
+ *ptr += 2;
+ return val;
+}
+
+static uint16_t SPICE_GNUC_UNUSED consume_uint16(uint8_t **ptr)
+{
+ uint16_t val;
+ val = read_uint16(*ptr);
+ *ptr += 2;
+ return val;
+}
+
+static int32_t SPICE_GNUC_UNUSED consume_int32(uint8_t **ptr)
+{
+ int32_t val;
+ val = read_int32(*ptr);
+ *ptr += 4;
+ return val;
+}
+
+static uint32_t SPICE_GNUC_UNUSED consume_uint32(uint8_t **ptr)
+{
+ uint32_t val;
+ val = read_uint32(*ptr);
+ *ptr += 4;
+ return val;
+}
+
+static int64_t SPICE_GNUC_UNUSED consume_int64(uint8_t **ptr)
+{
+ int64_t val;
+ val = read_int64(*ptr);
+ *ptr += 8;
+ return val;
+}
+
+static uint64_t SPICE_GNUC_UNUSED consume_uint64(uint8_t **ptr)
+{
+ uint64_t val;
+ val = read_uint64(*ptr);
+ *ptr += 8;
+ return val;
+}
+static int SPICE_GNUC_UNUSED consume_fd(uint8_t **ptr)
+{
+ return -1;
+}
+
+typedef struct PointerInfo PointerInfo;
+typedef void (*message_destructor_t)(uint8_t *message);
+typedef uint8_t * (*parse_func_t)(uint8_t *message_start, uint8_t *message_end, uint8_t *struct_data, PointerInfo *ptr_info, int minor);
+typedef uint8_t * (*parse_msg_func_t)(uint8_t *message_start, uint8_t *message_end, int minor, size_t *size_out, message_destructor_t *free_message);
+typedef uint8_t * (*spice_parse_channel_func_t)(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, int minor, size_t *size_out, message_destructor_t *free_message);
+
+struct PointerInfo {
+ uint64_t offset;
+ parse_func_t parse;
+ void * *dest;
+ uint32_t nelements;
+};
+
+static uint8_t * parse_msgc_ack_sync(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcAckSync *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgcAckSync);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcAckSync);
+ in = start;
+
+ out = (SpiceMsgcAckSync *)data;
+
+ out->generation = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_SpiceMsgEmpty(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+
+ nw_size = 0;
+ mem_size = sizeof(SpiceMsgEmpty);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgEmpty);
+ in = start;
+
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_pong(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgPing *out;
+
+ nw_size = 12;
+ mem_size = sizeof(SpiceMsgPing);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgPing);
+ in = start;
+
+ out = (SpiceMsgPing *)data;
+
+ out->id = consume_uint32(&in);
+ out->timestamp = consume_uint64(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static void nofree(SPICE_GNUC_UNUSED uint8_t *data)
+{
+}
+
+static uint8_t * parse_SpiceMsgData(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t data__nw_size;
+ uint32_t data__nelements;
+
+ { /* data */
+ data__nelements = message_end - (start + 0);
+
+ data__nw_size = data__nelements;
+ }
+
+ nw_size = 0 + data__nw_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = message_start;
+ *size = message_end - message_start;
+ *free_message = nofree;
+ return data;
+
+}
+
+static uint8_t * parse_msgc_disconnecting(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgDisconnect *out;
+
+ nw_size = 12;
+ mem_size = sizeof(SpiceMsgDisconnect);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgDisconnect);
+ in = start;
+
+ out = (SpiceMsgDisconnect *)data;
+
+ out->time_stamp = consume_uint64(&in);
+ out->reason = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_main_client_info(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcClientInfo *out;
+
+ nw_size = 8;
+ mem_size = sizeof(SpiceMsgcClientInfo);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcClientInfo);
+ in = start;
+
+ out = (SpiceMsgcClientInfo *)data;
+
+ out->cache_size = consume_uint64(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_main_mouse_mode_request(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcMainMouseModeRequest *out;
+
+ nw_size = 2;
+ mem_size = sizeof(SpiceMsgcMainMouseModeRequest);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcMainMouseModeRequest);
+ in = start;
+
+ out = (SpiceMsgcMainMouseModeRequest *)data;
+
+ out->mode = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_main_agent_start(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcMainAgentStart *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgcMainAgentStart);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcMainAgentStart);
+ in = start;
+
+ out = (SpiceMsgcMainAgentStart *)data;
+
+ out->num_tokens = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_main_agent_token(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcMainAgentTokens *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgcMainAgentTokens);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcMainAgentTokens);
+ in = start;
+
+ out = (SpiceMsgcMainAgentTokens *)data;
+
+ out->num_tokens = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_main_migrate_dst_do_seamless(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcMainMigrateDstDoSeamless *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgcMainMigrateDstDoSeamless);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcMainMigrateDstDoSeamless);
+ in = start;
+
+ out = (SpiceMsgcMainMigrateDstDoSeamless *)data;
+
+ out->src_version = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_MainChannel_msgc(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[6] = {
+ parse_msgc_ack_sync,
+ parse_SpiceMsgEmpty,
+ parse_msgc_pong,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_msgc_disconnecting
+ };
+ static parse_msg_func_t funcs2[11] = {
+ parse_msgc_main_client_info,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgEmpty,
+ parse_msgc_main_mouse_mode_request,
+ parse_msgc_main_agent_start,
+ parse_SpiceMsgData,
+ parse_msgc_main_agent_token,
+ parse_SpiceMsgEmpty,
+ parse_msgc_main_migrate_dst_do_seamless,
+ parse_SpiceMsgEmpty
+ };
+ if (message_type >= 1 && message_type < 7) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 112) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msgc_display_init(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcDisplayInit *out;
+
+ nw_size = 14;
+ mem_size = sizeof(SpiceMsgcDisplayInit);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcDisplayInit);
+ in = start;
+
+ out = (SpiceMsgcDisplayInit *)data;
+
+ out->pixmap_cache_id = consume_uint8(&in);
+ out->pixmap_cache_size = consume_int64(&in);
+ out->glz_dictionary_id = consume_uint8(&in);
+ out->glz_dictionary_window_size = consume_int32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_display_stream_report(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcDisplayStreamReport *out;
+
+ nw_size = 32;
+ mem_size = sizeof(SpiceMsgcDisplayStreamReport);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcDisplayStreamReport);
+ in = start;
+
+ out = (SpiceMsgcDisplayStreamReport *)data;
+
+ out->stream_id = consume_uint32(&in);
+ out->unique_id = consume_uint32(&in);
+ out->start_frame_mm_time = consume_uint32(&in);
+ out->end_frame_mm_time = consume_uint32(&in);
+ out->num_frames = consume_uint32(&in);
+ out->num_drops = consume_uint32(&in);
+ out->last_frame_delay = consume_int32(&in);
+ out->audio_delay = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_display_preferred_compression(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcDisplayPreferredCompression *out;
+
+ nw_size = 1;
+ mem_size = sizeof(SpiceMsgcDisplayPreferredCompression);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcDisplayPreferredCompression);
+ in = start;
+
+ out = (SpiceMsgcDisplayPreferredCompression *)data;
+
+ out->image_compression = consume_uint8(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_display_gl_draw_done(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+
+ nw_size = 0;
+ mem_size = sizeof(SpiceMsgcDisplayGlDrawDone);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcDisplayGlDrawDone);
+ in = start;
+
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_DisplayChannel_msgc(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[6] = {
+ parse_msgc_ack_sync,
+ parse_SpiceMsgEmpty,
+ parse_msgc_pong,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_msgc_disconnecting
+ };
+ static parse_msg_func_t funcs2[4] = {
+ parse_msgc_display_init,
+ parse_msgc_display_stream_report,
+ parse_msgc_display_preferred_compression,
+ parse_msgc_display_gl_draw_done
+ };
+ if (message_type >= 1 && message_type < 7) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 105) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msgc_inputs_key_down(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcKeyDown *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgcKeyDown);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcKeyDown);
+ in = start;
+
+ out = (SpiceMsgcKeyDown *)data;
+
+ out->code = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_inputs_key_up(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcKeyUp *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgcKeyUp);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcKeyUp);
+ in = start;
+
+ out = (SpiceMsgcKeyUp *)data;
+
+ out->code = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_inputs_key_modifiers(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcKeyModifiers *out;
+
+ nw_size = 2;
+ mem_size = sizeof(SpiceMsgcKeyModifiers);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcKeyModifiers);
+ in = start;
+
+ out = (SpiceMsgcKeyModifiers *)data;
+
+ out->modifiers = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_inputs_mouse_motion(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcMouseMotion *out;
+
+ nw_size = 10;
+ mem_size = sizeof(SpiceMsgcMouseMotion);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcMouseMotion);
+ in = start;
+
+ out = (SpiceMsgcMouseMotion *)data;
+
+ out->dx = consume_int32(&in);
+ out->dy = consume_int32(&in);
+ out->buttons_state = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_inputs_mouse_position(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcMousePosition *out;
+
+ nw_size = 11;
+ mem_size = sizeof(SpiceMsgcMousePosition);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcMousePosition);
+ in = start;
+
+ out = (SpiceMsgcMousePosition *)data;
+
+ out->x = consume_uint32(&in);
+ out->y = consume_uint32(&in);
+ out->buttons_state = consume_uint16(&in);
+ out->display_id = consume_uint8(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_inputs_mouse_press(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcMousePress *out;
+
+ nw_size = 3;
+ mem_size = sizeof(SpiceMsgcMousePress);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcMousePress);
+ in = start;
+
+ out = (SpiceMsgcMousePress *)data;
+
+ out->button = consume_uint8(&in);
+ out->buttons_state = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_inputs_mouse_release(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcMouseRelease *out;
+
+ nw_size = 3;
+ mem_size = sizeof(SpiceMsgcMouseRelease);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcMouseRelease);
+ in = start;
+
+ out = (SpiceMsgcMouseRelease *)data;
+
+ out->button = consume_uint8(&in);
+ out->buttons_state = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_InputsChannel_msgc(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[6] = {
+ parse_msgc_ack_sync,
+ parse_SpiceMsgEmpty,
+ parse_msgc_pong,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_msgc_disconnecting
+ };
+ static parse_msg_func_t funcs2[4] = {
+ parse_msgc_inputs_key_down,
+ parse_msgc_inputs_key_up,
+ parse_msgc_inputs_key_modifiers,
+ parse_SpiceMsgData
+ };
+ static parse_msg_func_t funcs3[4] = {
+ parse_msgc_inputs_mouse_motion,
+ parse_msgc_inputs_mouse_position,
+ parse_msgc_inputs_mouse_press,
+ parse_msgc_inputs_mouse_release
+ };
+ if (message_type >= 1 && message_type < 7) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 105) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 111 && message_type < 115) {
+ return funcs3[message_type-111](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_CursorChannel_msgc(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[6] = {
+ parse_msgc_ack_sync,
+ parse_SpiceMsgEmpty,
+ parse_msgc_pong,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_msgc_disconnecting
+ };
+ if (message_type >= 1 && message_type < 7) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_PlaybackChannel_msgc(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[6] = {
+ parse_msgc_ack_sync,
+ parse_SpiceMsgEmpty,
+ parse_msgc_pong,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_msgc_disconnecting
+ };
+ if (message_type >= 1 && message_type < 7) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msgc_record_data(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size;
+ uint32_t data__nelements;
+ SpiceMsgcRecordPacket *out;
+
+ { /* data */
+ data__nelements = message_end - (start + 4);
+
+ data__nw_size = data__nelements;
+ }
+
+ nw_size = 4 + data__nw_size;
+ mem_size = sizeof(SpiceMsgcRecordPacket);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcRecordPacket);
+ in = start;
+
+ out = (SpiceMsgcRecordPacket *)data;
+
+ out->time = consume_uint32(&in);
+ /* use array as pointer */
+ out->data = (uint8_t *)in;
+ out->data_size = data__nelements;
+ in += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_record_mode(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size;
+ uint32_t data__nelements;
+ SpiceMsgcRecordMode *out;
+
+ { /* data */
+ data__nelements = message_end - (start + 6);
+
+ data__nw_size = data__nelements;
+ }
+
+ nw_size = 6 + data__nw_size;
+ mem_size = sizeof(SpiceMsgcRecordMode);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcRecordMode);
+ in = start;
+
+ out = (SpiceMsgcRecordMode *)data;
+
+ out->time = consume_uint32(&in);
+ out->mode = consume_uint16(&in);
+ /* use array as pointer */
+ out->data = (uint8_t *)in;
+ out->data_size = data__nelements;
+ in += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_record_start_mark(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcRecordStartMark *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgcRecordStartMark);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcRecordStartMark);
+ in = start;
+
+ out = (SpiceMsgcRecordStartMark *)data;
+
+ out->time = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_RecordChannel_msgc(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[6] = {
+ parse_msgc_ack_sync,
+ parse_SpiceMsgEmpty,
+ parse_msgc_pong,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_msgc_disconnecting
+ };
+ static parse_msg_func_t funcs2[3] = {
+ parse_msgc_record_data,
+ parse_msgc_record_mode,
+ parse_msgc_record_start_mark
+ };
+ if (message_type >= 1 && message_type < 7) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 104) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msgc_tunnel_service_add(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SPICE_GNUC_UNUSED intptr_t ptr_size;
+ uint32_t n_ptr=0;
+ PointerInfo ptr_info[2];
+ size_t name__extra_size;
+ size_t description__extra_size;
+ size_t u__nw_size;
+ uint16_t type__value;
+ SpiceMsgcTunnelAddGenericService *out;
+ uint32_t i;
+
+ { /* name */
+ uint32_t name__value;
+ uint32_t name__array__nw_size;
+ pos = (start + 14);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ name__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(message_start + name__value >= message_end)) {
+ goto error;
+ }
+ name__array__nw_size = spice_strnlen((char *)message_start + name__value, message_end - (message_start + name__value));
+ if (SPICE_UNLIKELY(*(message_start + name__value + name__array__nw_size) != 0)) {
+ goto error;
+ }
+ /* @nocopy, so no extra size */
+ name__extra_size = 0;
+ }
+
+ { /* description */
+ uint32_t description__value;
+ uint32_t description__array__nw_size;
+ pos = (start + 18);
+ if (SPICE_UNLIKELY(pos + 4 > message_end)) {
+ goto error;
+ }
+ description__value = read_uint32(pos);
+ if (SPICE_UNLIKELY(message_start + description__value >= message_end)) {
+ goto error;
+ }
+ description__array__nw_size = spice_strnlen((char *)message_start + description__value, message_end - (message_start + description__value));
+ if (SPICE_UNLIKELY(*(message_start + description__value + description__array__nw_size) != 0)) {
+ goto error;
+ }
+ /* @nocopy, so no extra size */
+ description__extra_size = 0;
+ }
+
+ { /* u */
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint16(pos);
+ if (type__value == SPICE_TUNNEL_SERVICE_TYPE_IPP) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 22);
+ size_t u_u__nw_size;
+ uint16_t type__value;
+ { /* u */
+ uint32_t u_u__nelements;
+ pos = start2 + 0;
+ if (SPICE_UNLIKELY(pos + 2 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint16(pos);
+ if (type__value == SPICE_TUNNEL_IP_TYPE_IPv4) {
+ u_u__nelements = 4;
+
+ u_u__nw_size = u_u__nelements;
+ } else {
+ u_u__nw_size = 0;
+ }
+
+ }
+
+ u__nw_size = 2 + u_u__nw_size;
+ } else {
+ u__nw_size = 0;
+ }
+
+ }
+
+ nw_size = 22 + u__nw_size;
+ mem_size = sizeof(SpiceMsgcTunnelAddGenericService) + name__extra_size + description__extra_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcTunnelAddGenericService);
+ in = start;
+
+ out = (SpiceMsgcTunnelAddGenericService *)data;
+
+ out->type = consume_uint16(&in);
+ out->id = consume_uint32(&in);
+ out->group = consume_uint32(&in);
+ out->port = consume_uint32(&in);
+ /* Reuse data from network message */
+ out->name = (size_t)(message_start + consume_uint32(&in));
+ /* Reuse data from network message */
+ out->description = (size_t)(message_start + consume_uint32(&in));
+ if (out->type == SPICE_TUNNEL_SERVICE_TYPE_IPP) {
+ out->u.ip.type = consume_uint16(&in);
+ if (out->u.ip.type == SPICE_TUNNEL_IP_TYPE_IPv4) {
+ uint32_t ipv4__nelements;
+ ipv4__nelements = 4;
+ memcpy(out->u.ip.u.ipv4, in, ipv4__nelements);
+ in += ipv4__nelements;
+ }
+ }
+
+ assert(in <= message_end);
+
+ for (i = 0; i < n_ptr; i++) {
+ if (ptr_info[i].offset == 0) {
+ *ptr_info[i].dest = NULL;
+ } else {
+ /* Align to 32 bit */
+ end = (uint8_t *)SPICE_ALIGN((size_t)end, 4);
+ *ptr_info[i].dest = (void *)end;
+ end = ptr_info[i].parse(message_start, message_end, end, &ptr_info[i], minor);
+ if (SPICE_UNLIKELY(end == NULL)) {
+ goto error;
+ }
+ }
+ }
+
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_tunnel_service_remove(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcTunnelRemoveService *out;
+
+ nw_size = 4;
+ mem_size = sizeof(SpiceMsgcTunnelRemoveService);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcTunnelRemoveService);
+ in = start;
+
+ out = (SpiceMsgcTunnelRemoveService *)data;
+
+ out->id = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_tunnel_socket_open_ack(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcTunnelSocketOpenAck *out;
+
+ nw_size = 6;
+ mem_size = sizeof(SpiceMsgcTunnelSocketOpenAck);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcTunnelSocketOpenAck);
+ in = start;
+
+ out = (SpiceMsgcTunnelSocketOpenAck *)data;
+
+ out->connection_id = consume_uint16(&in);
+ out->tokens = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_tunnel_socket_open_nack(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcTunnelSocketOpenNack *out;
+
+ nw_size = 2;
+ mem_size = sizeof(SpiceMsgcTunnelSocketOpenNack);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcTunnelSocketOpenNack);
+ in = start;
+
+ out = (SpiceMsgcTunnelSocketOpenNack *)data;
+
+ out->connection_id = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_tunnel_socket_fin(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcTunnelSocketFin *out;
+
+ nw_size = 2;
+ mem_size = sizeof(SpiceMsgcTunnelSocketFin);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcTunnelSocketFin);
+ in = start;
+
+ out = (SpiceMsgcTunnelSocketFin *)data;
+
+ out->connection_id = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_tunnel_socket_closed(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcTunnelSocketClosed *out;
+
+ nw_size = 2;
+ mem_size = sizeof(SpiceMsgcTunnelSocketClosed);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcTunnelSocketClosed);
+ in = start;
+
+ out = (SpiceMsgcTunnelSocketClosed *)data;
+
+ out->connection_id = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_tunnel_socket_closed_ack(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcTunnelSocketClosedAck *out;
+
+ nw_size = 2;
+ mem_size = sizeof(SpiceMsgcTunnelSocketClosedAck);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcTunnelSocketClosedAck);
+ in = start;
+
+ out = (SpiceMsgcTunnelSocketClosedAck *)data;
+
+ out->connection_id = consume_uint16(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_tunnel_socket_data(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t data__nw_size, data__mem_size;
+ uint32_t data__nelements;
+ SpiceMsgcTunnelSocketData *out;
+
+ { /* data */
+ data__nelements = message_end - (start + 2);
+
+ data__nw_size = data__nelements;
+ data__mem_size = sizeof(uint8_t) * data__nelements;
+ }
+
+ nw_size = 2 + data__nw_size;
+ mem_size = sizeof(SpiceMsgcTunnelSocketData) + data__mem_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcTunnelSocketData);
+ in = start;
+
+ out = (SpiceMsgcTunnelSocketData *)data;
+
+ out->connection_id = consume_uint16(&in);
+ memcpy(out->data, in, data__nelements);
+ in += data__nelements;
+ end += data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_msgc_tunnel_socket_token(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcTunnelSocketTokens *out;
+
+ nw_size = 6;
+ mem_size = sizeof(SpiceMsgcTunnelSocketTokens);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcTunnelSocketTokens);
+ in = start;
+
+ out = (SpiceMsgcTunnelSocketTokens *)data;
+
+ out->connection_id = consume_uint16(&in);
+ out->num_tokens = consume_uint32(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_TunnelChannel_msgc(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[6] = {
+ parse_msgc_ack_sync,
+ parse_SpiceMsgEmpty,
+ parse_msgc_pong,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_msgc_disconnecting
+ };
+ static parse_msg_func_t funcs2[9] = {
+ parse_msgc_tunnel_service_add,
+ parse_msgc_tunnel_service_remove,
+ parse_msgc_tunnel_socket_open_ack,
+ parse_msgc_tunnel_socket_open_nack,
+ parse_msgc_tunnel_socket_fin,
+ parse_msgc_tunnel_socket_closed,
+ parse_msgc_tunnel_socket_closed_ack,
+ parse_msgc_tunnel_socket_data,
+ parse_msgc_tunnel_socket_token
+ };
+ if (message_type >= 1 && message_type < 7) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 110) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+#ifdef USE_SMARTCARD
+
+static uint8_t * parse_msgc_smartcard_reader_add(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ uint8_t *in, *end;
+ size_t reader_name__nw_size;
+ uint32_t reader_name__nelements;
+ VSCMsgReaderAdd *out;
+
+ { /* reader_name */
+ reader_name__nelements = message_end - (start + 0);
+
+ reader_name__nw_size = reader_name__nelements;
+ }
+
+ nw_size = 0 + reader_name__nw_size;
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(VSCMsgReaderAdd);
+ in = start;
+
+ out = (VSCMsgReaderAdd *)data;
+
+ memcpy(out->reader_name, in, reader_name__nelements);
+ in += reader_name__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_SmartcardChannel_msgc(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[6] = {
+ parse_msgc_ack_sync,
+ parse_SpiceMsgEmpty,
+ parse_msgc_pong,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_msgc_disconnecting
+ };
+ static parse_msg_func_t funcs2[1] = {
+ parse_msgc_smartcard_reader_add
+ };
+ if (message_type >= 1 && message_type < 7) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 102) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+#endif /* USE_SMARTCARD */
+
+
+
+static uint8_t * parse_SpiceMsgCompressedData(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ size_t u__nw_size;
+ uint8_t type__value;
+ size_t compressed_data__nw_size;
+ uint32_t compressed_data__nelements;
+ SpiceMsgCompressedData *out;
+
+ { /* u */
+ pos = start + 0;
+ if (SPICE_UNLIKELY(pos + 1 > message_end)) {
+ goto error;
+ }
+ type__value = read_uint8(pos);
+ if (type__value == SPICE_DATA_COMPRESSION_TYPE_NONE) {
+ SPICE_GNUC_UNUSED uint8_t *start2 = (start + 1);
+ u__nw_size = 0;
+ } else if (1) {
+ u__nw_size = 4;
+ } else {
+ u__nw_size = 0;
+ }
+
+ }
+
+ { /* compressed_data */
+ compressed_data__nelements = message_end - (start + 1 + u__nw_size);
+
+ compressed_data__nw_size = compressed_data__nelements;
+ }
+
+ nw_size = 1 + u__nw_size + compressed_data__nw_size;
+ mem_size = sizeof(SpiceMsgCompressedData);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgCompressedData);
+ in = start;
+
+ out = (SpiceMsgCompressedData *)data;
+
+ out->type = consume_uint8(&in);
+ if (out->type == SPICE_DATA_COMPRESSION_TYPE_NONE) {
+ } else if (1) {
+ out->uncompressed_size = consume_uint32(&in);
+ }
+ /* use array as pointer */
+ out->compressed_data = (uint8_t *)in;
+ out->compressed_size = compressed_data__nelements;
+ in += compressed_data__nelements;
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_UsbredirChannel_msgc(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[6] = {
+ parse_msgc_ack_sync,
+ parse_SpiceMsgEmpty,
+ parse_msgc_pong,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_msgc_disconnecting
+ };
+ static parse_msg_func_t funcs2[2] = {
+ parse_SpiceMsgData,
+ parse_SpiceMsgCompressedData
+ };
+ if (message_type >= 1 && message_type < 7) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 103) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_msgc_port_event(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
+{
+ SPICE_GNUC_UNUSED uint8_t *pos;
+ uint8_t *start = message_start;
+ uint8_t *data = NULL;
+ size_t nw_size;
+ size_t mem_size;
+ uint8_t *in, *end;
+ SpiceMsgcPortEvent *out;
+
+ nw_size = 1;
+ mem_size = sizeof(SpiceMsgcPortEvent);
+
+ /* Check if message fits in reported side */
+ if (start + nw_size > message_end) {
+ return NULL;
+ }
+
+ /* Validated extents and calculated size */
+ data = (uint8_t *)malloc(mem_size);
+ if (SPICE_UNLIKELY(data == NULL)) {
+ goto error;
+ }
+ end = data + sizeof(SpiceMsgcPortEvent);
+ in = start;
+
+ out = (SpiceMsgcPortEvent *)data;
+
+ out->event = consume_uint8(&in);
+
+ assert(in <= message_end);
+ assert(end <= data + mem_size);
+
+ *size = end - data;
+ *free_message = (message_destructor_t) free;
+ return data;
+
+ error:
+ if (data != NULL) {
+ free(data);
+ }
+ return NULL;
+}
+
+static uint8_t * parse_PortChannel_msgc(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[6] = {
+ parse_msgc_ack_sync,
+ parse_SpiceMsgEmpty,
+ parse_msgc_pong,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_msgc_disconnecting
+ };
+ static parse_msg_func_t funcs2[2] = {
+ parse_SpiceMsgData,
+ parse_SpiceMsgCompressedData
+ };
+ static parse_msg_func_t funcs3[1] = {
+ parse_msgc_port_event
+ };
+ if (message_type >= 1 && message_type < 7) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 103) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 201 && message_type < 202) {
+ return funcs3[message_type-201](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+
+
+static uint8_t * parse_WebDAVChannel_msgc(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ static parse_msg_func_t funcs1[6] = {
+ parse_msgc_ack_sync,
+ parse_SpiceMsgEmpty,
+ parse_msgc_pong,
+ parse_SpiceMsgEmpty,
+ parse_SpiceMsgData,
+ parse_msgc_disconnecting
+ };
+ static parse_msg_func_t funcs2[2] = {
+ parse_SpiceMsgData,
+ parse_SpiceMsgCompressedData
+ };
+ static parse_msg_func_t funcs3[1] = {
+ parse_msgc_port_event
+ };
+ if (message_type >= 1 && message_type < 7) {
+ return funcs1[message_type-1](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 101 && message_type < 103) {
+ return funcs2[message_type-101](message_start, message_end, minor, size_out, free_message);
+ } else if (message_type >= 201 && message_type < 202) {
+ return funcs3[message_type-201](message_start, message_end, minor, size_out, free_message);
+ }
+ return NULL;
+}
+
+spice_parse_channel_func_t spice_get_client_channel_parser(uint32_t channel, unsigned int *max_message_type)
+{
+ static struct {spice_parse_channel_func_t func; unsigned int max_messages; } channels[12] = {
+ { NULL, 0 },
+ { parse_MainChannel_msgc, 111},
+ { parse_DisplayChannel_msgc, 104},
+ { parse_InputsChannel_msgc, 114},
+ { parse_CursorChannel_msgc, 6},
+ { parse_PlaybackChannel_msgc, 6},
+ { parse_RecordChannel_msgc, 103},
+ { parse_TunnelChannel_msgc, 109},
+#ifdef USE_SMARTCARD
+ { parse_SmartcardChannel_msgc, 101},
+#else /* USE_SMARTCARD */
+ { NULL, 0 },
+#endif /* USE_SMARTCARD */
+ { parse_UsbredirChannel_msgc, 102},
+ { parse_PortChannel_msgc, 201},
+ { parse_WebDAVChannel_msgc, 201}
+ };
+ if (channel < 12) {
+ if (max_message_type != NULL) {
+ *max_message_type = channels[channel].max_messages;
+ }
+ return channels[channel].func;
+ }
+ return NULL;
+}
+
+uint8_t * spice_parse_reply(uint8_t *message_start, uint8_t *message_end, uint32_t channel, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message)
+{
+ spice_parse_channel_func_t func;
+ func = spice_get_client_channel_parser(channel, NULL);
+ if (func != NULL) {
+ return func(message_start, message_end, message_type, minor, size_out, free_message);
+ }
+ return NULL;
+}
--- /dev/null
+/* this is a file autogenerated by spice_codegen.py */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "common/messages.h"
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <spice/protocol.h>
+#include <spice/macros.h>
+#include "common/marshaller.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable:4101)
+#pragma warning(disable:4018)
+#endif
+
+void spice_marshall_msg_migrate(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMigrate *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMigrate *src;
+ src = (SpiceMsgMigrate *)msg;
+
+ spice_marshaller_add_uint32(m, src->flags);
+}
+
+void spice_marshall_SpiceMsgData(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgData *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+}
+
+void spice_marshall_msg_set_ack(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgSetAck *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgSetAck *src;
+ src = (SpiceMsgSetAck *)msg;
+
+ spice_marshaller_add_uint32(m, src->generation);
+ spice_marshaller_add_uint32(m, src->window);
+}
+
+void spice_marshall_msg_ping(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgPing *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgPing *src;
+ src = (SpiceMsgPing *)msg;
+
+ spice_marshaller_add_uint32(m, src->id);
+ spice_marshaller_add_uint64(m, src->timestamp);
+ /* Remaining data must be appended manually */
+}
+
+void spice_marshall_msg_wait_for_channels(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgWaitForChannels *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgWaitForChannels *src;
+ SpiceWaitForChannel *wait_list__element;
+ uint32_t i;
+ src = (SpiceMsgWaitForChannels *)msg;
+
+ spice_marshaller_add_uint8(m, src->wait_count);
+ wait_list__element = src->wait_list;
+ for (i = 0; i < src->wait_count; i++) {
+ SpiceWaitForChannel *src2;
+ src2 = (SpiceWaitForChannel *)wait_list__element;
+
+ spice_marshaller_add_uint8(m, src2->channel_type);
+ spice_marshaller_add_uint8(m, src2->channel_id);
+ spice_marshaller_add_uint64(m, src2->message_serial);
+ wait_list__element++;
+ }
+}
+
+void spice_marshall_msg_disconnecting(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisconnect *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisconnect *src;
+ src = (SpiceMsgDisconnect *)msg;
+
+ spice_marshaller_add_uint64(m, src->time_stamp);
+ spice_marshaller_add_uint32(m, src->reason);
+}
+
+void spice_marshall_msg_notify(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgNotify *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgNotify *src;
+ src = (SpiceMsgNotify *)msg;
+
+ spice_marshaller_add_uint64(m, src->time_stamp);
+ spice_marshaller_add_uint32(m, src->severity);
+ spice_marshaller_add_uint32(m, src->visibilty);
+ spice_marshaller_add_uint32(m, src->what);
+ spice_marshaller_add_uint32(m, src->message_len);
+ /* Don't marshall @nomarshal message */
+}
+
+void spice_marshall_SpiceMsgEmpty(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgEmpty *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+}
+
+SPICE_GNUC_UNUSED static void spice_marshall_array_uint8(SpiceMarshaller *m, uint8_t *ptr, unsigned count)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ uint32_t i;
+
+ for (i = 0; i < count; i++) {
+ spice_marshaller_add_uint8(m, *ptr++);
+ }
+}
+
+void spice_marshall_msg_main_migrate_begin(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMainMigrationBegin *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMainMigrationBegin *src;
+ src = (SpiceMsgMainMigrationBegin *)msg;
+
+ /* dst_info */ {
+ spice_marshaller_add_uint16(m, src->dst_info.port);
+ spice_marshaller_add_uint16(m, src->dst_info.sport);
+ spice_marshaller_add_uint32(m, src->dst_info.host_size);
+ m2 = spice_marshaller_get_ptr_submarshaller(m, 0);
+ spice_marshall_array_uint8(m2, src->dst_info.host_data, src->dst_info.host_size);
+ spice_marshaller_add_uint32(m, src->dst_info.cert_subject_size);
+ m2 = spice_marshaller_get_ptr_submarshaller(m, 0);
+ if (src->dst_info.cert_subject_data != NULL) {
+ spice_marshall_array_uint8(m2, src->dst_info.cert_subject_data, src->dst_info.cert_subject_size);
+ }
+ }
+}
+
+void spice_marshall_msg_main_init(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMainInit *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMainInit *src;
+ src = (SpiceMsgMainInit *)msg;
+
+ spice_marshaller_add_uint32(m, src->session_id);
+ spice_marshaller_add_uint32(m, src->display_channels_hint);
+ spice_marshaller_add_uint32(m, src->supported_mouse_modes);
+ spice_marshaller_add_uint32(m, src->current_mouse_mode);
+ spice_marshaller_add_uint32(m, src->agent_connected);
+ spice_marshaller_add_uint32(m, src->agent_tokens);
+ spice_marshaller_add_uint32(m, src->multi_media_time);
+ spice_marshaller_add_uint32(m, src->ram_hint);
+}
+
+void spice_marshall_msg_main_channels_list(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgChannels *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgChannels *src;
+ SpiceChannelId *channels__element;
+ uint32_t i;
+ src = (SpiceMsgChannels *)msg;
+
+ spice_marshaller_add_uint32(m, src->num_of_channels);
+ channels__element = src->channels;
+ for (i = 0; i < src->num_of_channels; i++) {
+ SpiceChannelId *src2;
+ src2 = (SpiceChannelId *)channels__element;
+
+ spice_marshaller_add_uint8(m, src2->type);
+ spice_marshaller_add_uint8(m, src2->id);
+ channels__element++;
+ }
+}
+
+void spice_marshall_msg_main_mouse_mode(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMainMouseMode *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMainMouseMode *src;
+ src = (SpiceMsgMainMouseMode *)msg;
+
+ spice_marshaller_add_uint16(m, src->supported_modes);
+ spice_marshaller_add_uint16(m, src->current_mode);
+}
+
+void spice_marshall_msg_main_multi_media_time(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMainMultiMediaTime *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMainMultiMediaTime *src;
+ src = (SpiceMsgMainMultiMediaTime *)msg;
+
+ spice_marshaller_add_uint32(m, src->time);
+}
+
+void spice_marshall_msg_main_agent_disconnected(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMainAgentDisconnect *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMainAgentDisconnect *src;
+ src = (SpiceMsgMainAgentDisconnect *)msg;
+
+ spice_marshaller_add_uint32(m, src->error_code);
+}
+
+void spice_marshall_msg_main_agent_token(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMainAgentTokens *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMainAgentTokens *src;
+ src = (SpiceMsgMainAgentTokens *)msg;
+
+ spice_marshaller_add_uint32(m, src->num_tokens);
+}
+
+void spice_marshall_msg_main_migrate_switch_host(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMainMigrationSwitchHost *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMainMigrationSwitchHost *src;
+ src = (SpiceMsgMainMigrationSwitchHost *)msg;
+
+ spice_marshaller_add_uint16(m, src->port);
+ spice_marshaller_add_uint16(m, src->sport);
+ spice_marshaller_add_uint32(m, src->host_size);
+ m2 = spice_marshaller_get_ptr_submarshaller(m, 0);
+ if (src->host_data != NULL) {
+ spice_marshall_array_uint8(m2, src->host_data, src->host_size);
+ }
+ spice_marshaller_add_uint32(m, src->cert_subject_size);
+ m2 = spice_marshaller_get_ptr_submarshaller(m, 0);
+ if (src->cert_subject_data != NULL) {
+ spice_marshall_array_uint8(m2, src->cert_subject_data, src->cert_subject_size);
+ }
+}
+
+void spice_marshall_msg_main_name(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMainName *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMainName *src;
+ uint8_t *name__element;
+ uint32_t i;
+ src = (SpiceMsgMainName *)msg;
+
+ spice_marshaller_add_uint32(m, src->name_len);
+ name__element = src->name;
+ for (i = 0; i < src->name_len; i++) {
+ spice_marshaller_add_uint8(m, *name__element);
+ name__element++;
+ }
+}
+
+void spice_marshall_msg_main_uuid(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMainUuid *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMainUuid *src;
+ uint8_t *uuid__element;
+ uint32_t i;
+ src = (SpiceMsgMainUuid *)msg;
+
+ uuid__element = src->uuid;
+ for (i = 0; i < 16; i++) {
+ spice_marshaller_add_uint8(m, *uuid__element);
+ uuid__element++;
+ }
+}
+
+void spice_marshall_msg_main_agent_connected_tokens(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMainAgentConnectedTokens *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMainAgentConnectedTokens *src;
+ src = (SpiceMsgMainAgentConnectedTokens *)msg;
+
+ spice_marshaller_add_uint32(m, src->num_tokens);
+}
+
+void spice_marshall_msg_main_migrate_begin_seamless(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMainMigrateBeginSeamless *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMainMigrateBeginSeamless *src;
+ src = (SpiceMsgMainMigrateBeginSeamless *)msg;
+
+ /* dst_info */ {
+ spice_marshaller_add_uint16(m, src->dst_info.port);
+ spice_marshaller_add_uint16(m, src->dst_info.sport);
+ spice_marshaller_add_uint32(m, src->dst_info.host_size);
+ m2 = spice_marshaller_get_ptr_submarshaller(m, 0);
+ spice_marshall_array_uint8(m2, src->dst_info.host_data, src->dst_info.host_size);
+ spice_marshaller_add_uint32(m, src->dst_info.cert_subject_size);
+ m2 = spice_marshaller_get_ptr_submarshaller(m, 0);
+ if (src->dst_info.cert_subject_data != NULL) {
+ spice_marshall_array_uint8(m2, src->dst_info.cert_subject_data, src->dst_info.cert_subject_size);
+ }
+ }
+ spice_marshaller_add_uint32(m, src->src_mig_version);
+}
+
+void spice_marshall_msg_display_mode(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayMode *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayMode *src;
+ src = (SpiceMsgDisplayMode *)msg;
+
+ spice_marshaller_add_uint32(m, src->x_res);
+ spice_marshaller_add_uint32(m, src->y_res);
+ spice_marshaller_add_uint32(m, src->bits);
+}
+
+void spice_marshall_msg_display_copy_bits(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayCopyBits *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayCopyBits *src;
+ uint32_t i;
+ src = (SpiceMsgDisplayCopyBits *)msg;
+
+ /* base */ {
+ spice_marshaller_add_uint32(m, src->base.surface_id);
+ /* box */ {
+ spice_marshaller_add_int32(m, src->base.box.top);
+ spice_marshaller_add_int32(m, src->base.box.left);
+ spice_marshaller_add_int32(m, src->base.box.bottom);
+ spice_marshaller_add_int32(m, src->base.box.right);
+ }
+ /* clip */ {
+ spice_marshaller_add_uint8(m, src->base.clip.type);
+ if (src->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ SpiceRect *rects__element;
+ spice_marshaller_add_uint32(m, src->base.clip.rects->num_rects);
+ rects__element = src->base.clip.rects->rects;
+ for (i = 0; i < src->base.clip.rects->num_rects; i++) {
+ SpiceRect *src2;
+ src2 = (SpiceRect *)rects__element;
+
+ spice_marshaller_add_int32(m, src2->top);
+ spice_marshaller_add_int32(m, src2->left);
+ spice_marshaller_add_int32(m, src2->bottom);
+ spice_marshaller_add_int32(m, src2->right);
+ rects__element++;
+ }
+ }
+ }
+ }
+ /* src_pos */ {
+ spice_marshaller_add_int32(m, src->src_pos.x);
+ spice_marshaller_add_int32(m, src->src_pos.y);
+ }
+}
+
+void spice_marshall_msg_display_inval_list(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceResourceList *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceResourceList *src;
+ SpiceResourceID *resources__element;
+ uint32_t i;
+ src = (SpiceResourceList *)msg;
+
+ spice_marshaller_add_uint16(m, src->count);
+ resources__element = src->resources;
+ for (i = 0; i < src->count; i++) {
+ SpiceResourceID *src2;
+ src2 = (SpiceResourceID *)resources__element;
+
+ spice_marshaller_add_uint8(m, src2->type);
+ spice_marshaller_add_uint64(m, src2->id);
+ resources__element++;
+ }
+}
+
+void spice_marshall_msg_display_inval_all_pixmaps(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgWaitForChannels *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgWaitForChannels *src;
+ SpiceWaitForChannel *wait_list__element;
+ uint32_t i;
+ src = (SpiceMsgWaitForChannels *)msg;
+
+ spice_marshaller_add_uint8(m, src->wait_count);
+ wait_list__element = src->wait_list;
+ for (i = 0; i < src->wait_count; i++) {
+ SpiceWaitForChannel *src2;
+ src2 = (SpiceWaitForChannel *)wait_list__element;
+
+ spice_marshaller_add_uint8(m, src2->channel_type);
+ spice_marshaller_add_uint8(m, src2->channel_id);
+ spice_marshaller_add_uint64(m, src2->message_serial);
+ wait_list__element++;
+ }
+}
+
+void spice_marshall_msg_display_inval_palette(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayInvalOne *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayInvalOne *src;
+ src = (SpiceMsgDisplayInvalOne *)msg;
+
+ spice_marshaller_add_uint64(m, src->id);
+}
+
+void spice_marshall_msg_display_stream_create(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayStreamCreate *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayStreamCreate *src;
+ uint32_t i;
+ src = (SpiceMsgDisplayStreamCreate *)msg;
+
+ spice_marshaller_add_uint32(m, src->surface_id);
+ spice_marshaller_add_uint32(m, src->id);
+ spice_marshaller_add_uint8(m, src->flags);
+ spice_marshaller_add_uint8(m, src->codec_type);
+ spice_marshaller_add_uint64(m, src->stamp);
+ spice_marshaller_add_uint32(m, src->stream_width);
+ spice_marshaller_add_uint32(m, src->stream_height);
+ spice_marshaller_add_uint32(m, src->src_width);
+ spice_marshaller_add_uint32(m, src->src_height);
+ /* dest */ {
+ spice_marshaller_add_int32(m, src->dest.top);
+ spice_marshaller_add_int32(m, src->dest.left);
+ spice_marshaller_add_int32(m, src->dest.bottom);
+ spice_marshaller_add_int32(m, src->dest.right);
+ }
+ /* clip */ {
+ spice_marshaller_add_uint8(m, src->clip.type);
+ if (src->clip.type == SPICE_CLIP_TYPE_RECTS) {
+ SpiceRect *rects__element;
+ spice_marshaller_add_uint32(m, src->clip.rects->num_rects);
+ rects__element = src->clip.rects->rects;
+ for (i = 0; i < src->clip.rects->num_rects; i++) {
+ SpiceRect *src2;
+ src2 = (SpiceRect *)rects__element;
+
+ spice_marshaller_add_int32(m, src2->top);
+ spice_marshaller_add_int32(m, src2->left);
+ spice_marshaller_add_int32(m, src2->bottom);
+ spice_marshaller_add_int32(m, src2->right);
+ rects__element++;
+ }
+ }
+ }
+}
+
+void spice_marshall_msg_display_stream_data(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayStreamData *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayStreamData *src;
+ src = (SpiceMsgDisplayStreamData *)msg;
+
+ /* base */ {
+ spice_marshaller_add_uint32(m, src->base.id);
+ spice_marshaller_add_uint32(m, src->base.multi_media_time);
+ }
+ spice_marshaller_add_uint32(m, src->data_size);
+ /* Don't marshall @nomarshal data */
+}
+
+void spice_marshall_msg_display_stream_clip(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayStreamClip *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayStreamClip *src;
+ uint32_t i;
+ src = (SpiceMsgDisplayStreamClip *)msg;
+
+ spice_marshaller_add_uint32(m, src->id);
+ /* clip */ {
+ spice_marshaller_add_uint8(m, src->clip.type);
+ if (src->clip.type == SPICE_CLIP_TYPE_RECTS) {
+ SpiceRect *rects__element;
+ spice_marshaller_add_uint32(m, src->clip.rects->num_rects);
+ rects__element = src->clip.rects->rects;
+ for (i = 0; i < src->clip.rects->num_rects; i++) {
+ SpiceRect *src2;
+ src2 = (SpiceRect *)rects__element;
+
+ spice_marshaller_add_int32(m, src2->top);
+ spice_marshaller_add_int32(m, src2->left);
+ spice_marshaller_add_int32(m, src2->bottom);
+ spice_marshaller_add_int32(m, src2->right);
+ rects__element++;
+ }
+ }
+ }
+}
+
+void spice_marshall_msg_display_stream_destroy(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayStreamDestroy *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayStreamDestroy *src;
+ src = (SpiceMsgDisplayStreamDestroy *)msg;
+
+ spice_marshaller_add_uint32(m, src->id);
+}
+
+void spice_marshall_msg_display_draw_fill(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawFill *msg, SpiceMarshaller **brush_pat_out, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ *brush_pat_out = NULL;
+ *mask_bitmap_out = NULL;
+}
+
+void spice_marshall_msg_display_draw_opaque(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawOpaque *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **pat_out, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ *src_bitmap_out = NULL;
+ *pat_out = NULL;
+ *mask_bitmap_out = NULL;
+}
+
+void spice_marshall_Palette(SpiceMarshaller *m, SpicePalette *ptr)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpicePalette *src;
+ uint32_t *ents__element;
+ uint32_t i;
+
+ src = (SpicePalette *)ptr;
+
+ spice_marshaller_add_uint64(m, src->unique);
+ spice_marshaller_add_uint16(m, src->num_ents);
+ ents__element = src->ents;
+ for (i = 0; i < src->num_ents; i++) {
+ spice_marshaller_add_uint32(m, *ents__element);
+ ents__element++;
+ }
+}
+
+void spice_marshall_Image(SpiceMarshaller *m, SpiceImage *ptr, SpiceMarshaller **bitmap_palette_out, SpiceMarshaller **lzplt_palette_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceImage *src;
+ *bitmap_palette_out = NULL;
+ *lzplt_palette_out = NULL;
+
+ src = (SpiceImage *)ptr;
+
+ /* descriptor */ {
+ spice_marshaller_add_uint64(m, src->descriptor.id);
+ spice_marshaller_add_uint8(m, src->descriptor.type);
+ spice_marshaller_add_uint8(m, src->descriptor.flags);
+ spice_marshaller_add_uint32(m, src->descriptor.width);
+ spice_marshaller_add_uint32(m, src->descriptor.height);
+ }
+ if (src->descriptor.type == SPICE_IMAGE_TYPE_BITMAP) {
+ spice_marshaller_add_uint8(m, src->u.bitmap.format);
+ spice_marshaller_add_uint8(m, src->u.bitmap.flags);
+ spice_marshaller_add_uint32(m, src->u.bitmap.x);
+ spice_marshaller_add_uint32(m, src->u.bitmap.y);
+ spice_marshaller_add_uint32(m, src->u.bitmap.stride);
+ if ((src->u.bitmap.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
+ spice_marshaller_add_uint64(m, src->u.bitmap.palette_id);
+ } else if (1) {
+ *bitmap_palette_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+ /* Don't marshall @nomarshal data */
+ } else if (src->descriptor.type == SPICE_IMAGE_TYPE_QUIC) {
+ spice_marshaller_add_uint32(m, src->u.quic.data_size);
+ /* Don't marshall @nomarshal data */
+ } else if (src->descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB || src->descriptor.type == SPICE_IMAGE_TYPE_GLZ_RGB) {
+ spice_marshaller_add_uint32(m, src->u.lz_rgb.data_size);
+ /* Don't marshall @nomarshal data */
+ } else if (src->descriptor.type == SPICE_IMAGE_TYPE_JPEG) {
+ spice_marshaller_add_uint32(m, src->u.jpeg.data_size);
+ /* Don't marshall @nomarshal data */
+ } else if (src->descriptor.type == SPICE_IMAGE_TYPE_LZ4) {
+ spice_marshaller_add_uint32(m, src->u.lz4.data_size);
+ /* Don't marshall @nomarshal data */
+ } else if (src->descriptor.type == SPICE_IMAGE_TYPE_LZ_PLT) {
+ spice_marshaller_add_uint8(m, src->u.lz_plt.flags);
+ spice_marshaller_add_uint32(m, src->u.lz_plt.data_size);
+ if ((src->u.lz_plt.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)) {
+ spice_marshaller_add_uint64(m, src->u.lz_plt.palette_id);
+ } else if (1) {
+ *lzplt_palette_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+ /* Don't marshall @nomarshal data */
+ } else if (src->descriptor.type == SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB) {
+ spice_marshaller_add_uint32(m, src->u.zlib_glz.glz_data_size);
+ spice_marshaller_add_uint32(m, src->u.zlib_glz.data_size);
+ /* Don't marshall @nomarshal data */
+ } else if (src->descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA) {
+ spice_marshaller_add_uint8(m, src->u.jpeg_alpha.flags);
+ spice_marshaller_add_uint32(m, src->u.jpeg_alpha.jpeg_size);
+ spice_marshaller_add_uint32(m, src->u.jpeg_alpha.data_size);
+ /* Don't marshall @nomarshal data */
+ } else if (src->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) {
+ spice_marshaller_add_uint32(m, src->u.surface.surface_id);
+ }
+}
+
+void spice_marshall_msg_display_draw_copy(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawCopy *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayDrawCopy *src;
+ uint32_t i;
+ *src_bitmap_out = NULL;
+ *mask_bitmap_out = NULL;
+ src = (SpiceMsgDisplayDrawCopy *)msg;
+
+ /* base */ {
+ spice_marshaller_add_uint32(m, src->base.surface_id);
+ /* box */ {
+ spice_marshaller_add_int32(m, src->base.box.top);
+ spice_marshaller_add_int32(m, src->base.box.left);
+ spice_marshaller_add_int32(m, src->base.box.bottom);
+ spice_marshaller_add_int32(m, src->base.box.right);
+ }
+ /* clip */ {
+ spice_marshaller_add_uint8(m, src->base.clip.type);
+ if (src->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ SpiceRect *rects__element;
+ spice_marshaller_add_uint32(m, src->base.clip.rects->num_rects);
+ rects__element = src->base.clip.rects->rects;
+ for (i = 0; i < src->base.clip.rects->num_rects; i++) {
+ SpiceRect *src2;
+ src2 = (SpiceRect *)rects__element;
+
+ spice_marshaller_add_int32(m, src2->top);
+ spice_marshaller_add_int32(m, src2->left);
+ spice_marshaller_add_int32(m, src2->bottom);
+ spice_marshaller_add_int32(m, src2->right);
+ rects__element++;
+ }
+ }
+ }
+ }
+ /* data */ {
+ *src_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* src_area */ {
+ spice_marshaller_add_int32(m, src->data.src_area.top);
+ spice_marshaller_add_int32(m, src->data.src_area.left);
+ spice_marshaller_add_int32(m, src->data.src_area.bottom);
+ spice_marshaller_add_int32(m, src->data.src_area.right);
+ }
+ spice_marshaller_add_uint16(m, src->data.rop_descriptor);
+ spice_marshaller_add_uint8(m, src->data.scale_mode);
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->data.mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->data.mask.pos.x);
+ spice_marshaller_add_int32(m, src->data.mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+ }
+}
+
+void spice_marshall_msg_display_draw_blend(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawBlend *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayDrawBlend *src;
+ uint32_t i;
+ *src_bitmap_out = NULL;
+ *mask_bitmap_out = NULL;
+ src = (SpiceMsgDisplayDrawBlend *)msg;
+
+ /* base */ {
+ spice_marshaller_add_uint32(m, src->base.surface_id);
+ /* box */ {
+ spice_marshaller_add_int32(m, src->base.box.top);
+ spice_marshaller_add_int32(m, src->base.box.left);
+ spice_marshaller_add_int32(m, src->base.box.bottom);
+ spice_marshaller_add_int32(m, src->base.box.right);
+ }
+ /* clip */ {
+ spice_marshaller_add_uint8(m, src->base.clip.type);
+ if (src->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ SpiceRect *rects__element;
+ spice_marshaller_add_uint32(m, src->base.clip.rects->num_rects);
+ rects__element = src->base.clip.rects->rects;
+ for (i = 0; i < src->base.clip.rects->num_rects; i++) {
+ SpiceRect *src2;
+ src2 = (SpiceRect *)rects__element;
+
+ spice_marshaller_add_int32(m, src2->top);
+ spice_marshaller_add_int32(m, src2->left);
+ spice_marshaller_add_int32(m, src2->bottom);
+ spice_marshaller_add_int32(m, src2->right);
+ rects__element++;
+ }
+ }
+ }
+ }
+ /* data */ {
+ *src_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* src_area */ {
+ spice_marshaller_add_int32(m, src->data.src_area.top);
+ spice_marshaller_add_int32(m, src->data.src_area.left);
+ spice_marshaller_add_int32(m, src->data.src_area.bottom);
+ spice_marshaller_add_int32(m, src->data.src_area.right);
+ }
+ spice_marshaller_add_uint16(m, src->data.rop_descriptor);
+ spice_marshaller_add_uint8(m, src->data.scale_mode);
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->data.mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->data.mask.pos.x);
+ spice_marshaller_add_int32(m, src->data.mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+ }
+}
+
+void spice_marshall_msg_display_draw_blackness(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawBlackness *msg, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayDrawBlackness *src;
+ uint32_t i;
+ *mask_bitmap_out = NULL;
+ src = (SpiceMsgDisplayDrawBlackness *)msg;
+
+ /* base */ {
+ spice_marshaller_add_uint32(m, src->base.surface_id);
+ /* box */ {
+ spice_marshaller_add_int32(m, src->base.box.top);
+ spice_marshaller_add_int32(m, src->base.box.left);
+ spice_marshaller_add_int32(m, src->base.box.bottom);
+ spice_marshaller_add_int32(m, src->base.box.right);
+ }
+ /* clip */ {
+ spice_marshaller_add_uint8(m, src->base.clip.type);
+ if (src->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ SpiceRect *rects__element;
+ spice_marshaller_add_uint32(m, src->base.clip.rects->num_rects);
+ rects__element = src->base.clip.rects->rects;
+ for (i = 0; i < src->base.clip.rects->num_rects; i++) {
+ SpiceRect *src2;
+ src2 = (SpiceRect *)rects__element;
+
+ spice_marshaller_add_int32(m, src2->top);
+ spice_marshaller_add_int32(m, src2->left);
+ spice_marshaller_add_int32(m, src2->bottom);
+ spice_marshaller_add_int32(m, src2->right);
+ rects__element++;
+ }
+ }
+ }
+ }
+ /* data */ {
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->data.mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->data.mask.pos.x);
+ spice_marshaller_add_int32(m, src->data.mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+ }
+}
+
+void spice_marshall_msg_display_draw_whiteness(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawWhiteness *msg, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayDrawWhiteness *src;
+ uint32_t i;
+ *mask_bitmap_out = NULL;
+ src = (SpiceMsgDisplayDrawWhiteness *)msg;
+
+ /* base */ {
+ spice_marshaller_add_uint32(m, src->base.surface_id);
+ /* box */ {
+ spice_marshaller_add_int32(m, src->base.box.top);
+ spice_marshaller_add_int32(m, src->base.box.left);
+ spice_marshaller_add_int32(m, src->base.box.bottom);
+ spice_marshaller_add_int32(m, src->base.box.right);
+ }
+ /* clip */ {
+ spice_marshaller_add_uint8(m, src->base.clip.type);
+ if (src->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ SpiceRect *rects__element;
+ spice_marshaller_add_uint32(m, src->base.clip.rects->num_rects);
+ rects__element = src->base.clip.rects->rects;
+ for (i = 0; i < src->base.clip.rects->num_rects; i++) {
+ SpiceRect *src2;
+ src2 = (SpiceRect *)rects__element;
+
+ spice_marshaller_add_int32(m, src2->top);
+ spice_marshaller_add_int32(m, src2->left);
+ spice_marshaller_add_int32(m, src2->bottom);
+ spice_marshaller_add_int32(m, src2->right);
+ rects__element++;
+ }
+ }
+ }
+ }
+ /* data */ {
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->data.mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->data.mask.pos.x);
+ spice_marshaller_add_int32(m, src->data.mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+ }
+}
+
+void spice_marshall_msg_display_draw_invers(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawInvers *msg, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayDrawInvers *src;
+ uint32_t i;
+ *mask_bitmap_out = NULL;
+ src = (SpiceMsgDisplayDrawInvers *)msg;
+
+ /* base */ {
+ spice_marshaller_add_uint32(m, src->base.surface_id);
+ /* box */ {
+ spice_marshaller_add_int32(m, src->base.box.top);
+ spice_marshaller_add_int32(m, src->base.box.left);
+ spice_marshaller_add_int32(m, src->base.box.bottom);
+ spice_marshaller_add_int32(m, src->base.box.right);
+ }
+ /* clip */ {
+ spice_marshaller_add_uint8(m, src->base.clip.type);
+ if (src->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ SpiceRect *rects__element;
+ spice_marshaller_add_uint32(m, src->base.clip.rects->num_rects);
+ rects__element = src->base.clip.rects->rects;
+ for (i = 0; i < src->base.clip.rects->num_rects; i++) {
+ SpiceRect *src2;
+ src2 = (SpiceRect *)rects__element;
+
+ spice_marshaller_add_int32(m, src2->top);
+ spice_marshaller_add_int32(m, src2->left);
+ spice_marshaller_add_int32(m, src2->bottom);
+ spice_marshaller_add_int32(m, src2->right);
+ rects__element++;
+ }
+ }
+ }
+ }
+ /* data */ {
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->data.mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->data.mask.pos.x);
+ spice_marshaller_add_int32(m, src->data.mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+ }
+}
+
+void spice_marshall_msg_display_draw_rop3(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawRop3 *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **pat_out, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ *src_bitmap_out = NULL;
+ *pat_out = NULL;
+ *mask_bitmap_out = NULL;
+}
+
+void spice_marshall_msg_display_draw_stroke(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawStroke *msg, SpiceMarshaller **style_out, SpiceMarshaller **pat_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ *style_out = NULL;
+ *pat_out = NULL;
+}
+
+void spice_marshall_msg_display_draw_text(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawText *msg, SpiceMarshaller **fore_brush_pat_out, SpiceMarshaller **back_brush_pat_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ *fore_brush_pat_out = NULL;
+ *back_brush_pat_out = NULL;
+}
+
+void spice_marshall_msg_display_draw_transparent(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawTransparent *msg, SpiceMarshaller **src_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayDrawTransparent *src;
+ uint32_t i;
+ *src_bitmap_out = NULL;
+ src = (SpiceMsgDisplayDrawTransparent *)msg;
+
+ /* base */ {
+ spice_marshaller_add_uint32(m, src->base.surface_id);
+ /* box */ {
+ spice_marshaller_add_int32(m, src->base.box.top);
+ spice_marshaller_add_int32(m, src->base.box.left);
+ spice_marshaller_add_int32(m, src->base.box.bottom);
+ spice_marshaller_add_int32(m, src->base.box.right);
+ }
+ /* clip */ {
+ spice_marshaller_add_uint8(m, src->base.clip.type);
+ if (src->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ SpiceRect *rects__element;
+ spice_marshaller_add_uint32(m, src->base.clip.rects->num_rects);
+ rects__element = src->base.clip.rects->rects;
+ for (i = 0; i < src->base.clip.rects->num_rects; i++) {
+ SpiceRect *src2;
+ src2 = (SpiceRect *)rects__element;
+
+ spice_marshaller_add_int32(m, src2->top);
+ spice_marshaller_add_int32(m, src2->left);
+ spice_marshaller_add_int32(m, src2->bottom);
+ spice_marshaller_add_int32(m, src2->right);
+ rects__element++;
+ }
+ }
+ }
+ }
+ /* data */ {
+ *src_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* src_area */ {
+ spice_marshaller_add_int32(m, src->data.src_area.top);
+ spice_marshaller_add_int32(m, src->data.src_area.left);
+ spice_marshaller_add_int32(m, src->data.src_area.bottom);
+ spice_marshaller_add_int32(m, src->data.src_area.right);
+ }
+ spice_marshaller_add_uint32(m, src->data.src_color);
+ spice_marshaller_add_uint32(m, src->data.true_color);
+ }
+}
+
+void spice_marshall_msg_display_draw_alpha_blend(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawAlphaBlend *msg, SpiceMarshaller **src_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayDrawAlphaBlend *src;
+ uint32_t i;
+ *src_bitmap_out = NULL;
+ src = (SpiceMsgDisplayDrawAlphaBlend *)msg;
+
+ /* base */ {
+ spice_marshaller_add_uint32(m, src->base.surface_id);
+ /* box */ {
+ spice_marshaller_add_int32(m, src->base.box.top);
+ spice_marshaller_add_int32(m, src->base.box.left);
+ spice_marshaller_add_int32(m, src->base.box.bottom);
+ spice_marshaller_add_int32(m, src->base.box.right);
+ }
+ /* clip */ {
+ spice_marshaller_add_uint8(m, src->base.clip.type);
+ if (src->base.clip.type == SPICE_CLIP_TYPE_RECTS) {
+ SpiceRect *rects__element;
+ spice_marshaller_add_uint32(m, src->base.clip.rects->num_rects);
+ rects__element = src->base.clip.rects->rects;
+ for (i = 0; i < src->base.clip.rects->num_rects; i++) {
+ SpiceRect *src2;
+ src2 = (SpiceRect *)rects__element;
+
+ spice_marshaller_add_int32(m, src2->top);
+ spice_marshaller_add_int32(m, src2->left);
+ spice_marshaller_add_int32(m, src2->bottom);
+ spice_marshaller_add_int32(m, src2->right);
+ rects__element++;
+ }
+ }
+ }
+ }
+ /* data */ {
+ spice_marshaller_add_uint8(m, src->data.alpha_flags);
+ spice_marshaller_add_uint8(m, src->data.alpha);
+ *src_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* src_area */ {
+ spice_marshaller_add_int32(m, src->data.src_area.top);
+ spice_marshaller_add_int32(m, src->data.src_area.left);
+ spice_marshaller_add_int32(m, src->data.src_area.bottom);
+ spice_marshaller_add_int32(m, src->data.src_area.right);
+ }
+ }
+}
+
+void spice_marshall_msg_display_surface_create(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgSurfaceCreate *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgSurfaceCreate *src;
+ src = (SpiceMsgSurfaceCreate *)msg;
+
+ spice_marshaller_add_uint32(m, src->surface_id);
+ spice_marshaller_add_uint32(m, src->width);
+ spice_marshaller_add_uint32(m, src->height);
+ spice_marshaller_add_uint32(m, src->format);
+ spice_marshaller_add_uint32(m, src->flags);
+}
+
+void spice_marshall_msg_display_surface_destroy(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgSurfaceDestroy *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgSurfaceDestroy *src;
+ src = (SpiceMsgSurfaceDestroy *)msg;
+
+ spice_marshaller_add_uint32(m, src->surface_id);
+}
+
+void spice_marshall_msg_display_stream_data_sized(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayStreamDataSized *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayStreamDataSized *src;
+ src = (SpiceMsgDisplayStreamDataSized *)msg;
+
+ /* base */ {
+ spice_marshaller_add_uint32(m, src->base.id);
+ spice_marshaller_add_uint32(m, src->base.multi_media_time);
+ }
+ spice_marshaller_add_uint32(m, src->width);
+ spice_marshaller_add_uint32(m, src->height);
+ /* dest */ {
+ spice_marshaller_add_int32(m, src->dest.top);
+ spice_marshaller_add_int32(m, src->dest.left);
+ spice_marshaller_add_int32(m, src->dest.bottom);
+ spice_marshaller_add_int32(m, src->dest.right);
+ }
+ spice_marshaller_add_uint32(m, src->data_size);
+ /* Don't marshall @nomarshal data */
+}
+
+void spice_marshall_msg_display_monitors_config(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayMonitorsConfig *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayMonitorsConfig *src;
+ SpiceHead *heads__element;
+ uint32_t i;
+ src = (SpiceMsgDisplayMonitorsConfig *)msg;
+
+ spice_marshaller_add_uint16(m, src->count);
+ spice_marshaller_add_uint16(m, src->max_allowed);
+ heads__element = src->heads;
+ for (i = 0; i < src->count; i++) {
+ SpiceHead *src2;
+ src2 = (SpiceHead *)heads__element;
+
+ spice_marshaller_add_uint32(m, src2->id);
+ spice_marshaller_add_uint32(m, src2->surface_id);
+ spice_marshaller_add_uint32(m, src2->width);
+ spice_marshaller_add_uint32(m, src2->height);
+ spice_marshaller_add_uint32(m, src2->x);
+ spice_marshaller_add_uint32(m, src2->y);
+ spice_marshaller_add_uint32(m, src2->flags);
+ heads__element++;
+ }
+}
+
+void spice_marshall_msg_display_draw_composite(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayDrawComposite *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ *src_bitmap_out = NULL;
+ *mask_bitmap_out = NULL;
+}
+
+void spice_marshall_msg_display_stream_activate_report(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayStreamActivateReport *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayStreamActivateReport *src;
+ src = (SpiceMsgDisplayStreamActivateReport *)msg;
+
+ spice_marshaller_add_uint32(m, src->stream_id);
+ spice_marshaller_add_uint32(m, src->unique_id);
+ spice_marshaller_add_uint32(m, src->max_window_size);
+ spice_marshaller_add_uint32(m, src->timeout_ms);
+}
+
+void spice_marshall_msg_display_gl_scanout_unix(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayGlScanoutUnix *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayGlScanoutUnix *src;
+ src = (SpiceMsgDisplayGlScanoutUnix *)msg;
+
+ spice_marshaller_add_fd(m, src->drm_dma_buf_fd);
+ spice_marshaller_add_uint32(m, src->width);
+ spice_marshaller_add_uint32(m, src->height);
+ spice_marshaller_add_uint32(m, src->stride);
+ spice_marshaller_add_uint32(m, src->drm_fourcc_format);
+ spice_marshaller_add_uint32(m, src->flags);
+}
+
+void spice_marshall_msg_display_gl_draw(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayGlDraw *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayGlDraw *src;
+ src = (SpiceMsgDisplayGlDraw *)msg;
+
+ spice_marshaller_add_uint32(m, src->x);
+ spice_marshaller_add_uint32(m, src->y);
+ spice_marshaller_add_uint32(m, src->w);
+ spice_marshaller_add_uint32(m, src->h);
+}
+
+void spice_marshall_msg_inputs_init(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgInputsInit *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgInputsInit *src;
+ src = (SpiceMsgInputsInit *)msg;
+
+ spice_marshaller_add_uint16(m, src->keyboard_modifiers);
+}
+
+void spice_marshall_msg_inputs_key_modifiers(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgInputsKeyModifiers *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgInputsKeyModifiers *src;
+ src = (SpiceMsgInputsKeyModifiers *)msg;
+
+ spice_marshaller_add_uint16(m, src->modifiers);
+}
+
+void spice_marshall_msg_cursor_init(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgCursorInit *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgCursorInit *src;
+ src = (SpiceMsgCursorInit *)msg;
+
+ /* position */ {
+ spice_marshaller_add_int16(m, src->position.x);
+ spice_marshaller_add_int16(m, src->position.y);
+ }
+ spice_marshaller_add_uint16(m, src->trail_length);
+ spice_marshaller_add_uint16(m, src->trail_frequency);
+ spice_marshaller_add_uint8(m, src->visible);
+ /* cursor */ {
+ spice_marshaller_add_uint16(m, src->cursor.flags);
+ if (!(src->cursor.flags & SPICE_CURSOR_FLAGS_NONE)) {
+ spice_marshaller_add_uint64(m, src->cursor.header.unique);
+ spice_marshaller_add_uint8(m, src->cursor.header.type);
+ spice_marshaller_add_uint16(m, src->cursor.header.width);
+ spice_marshaller_add_uint16(m, src->cursor.header.height);
+ spice_marshaller_add_uint16(m, src->cursor.header.hot_spot_x);
+ spice_marshaller_add_uint16(m, src->cursor.header.hot_spot_y);
+ }
+ /* Remaining data must be appended manually */
+ }
+}
+
+void spice_marshall_msg_cursor_set(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgCursorSet *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgCursorSet *src;
+ src = (SpiceMsgCursorSet *)msg;
+
+ /* position */ {
+ spice_marshaller_add_int16(m, src->position.x);
+ spice_marshaller_add_int16(m, src->position.y);
+ }
+ spice_marshaller_add_uint8(m, src->visible);
+ /* cursor */ {
+ spice_marshaller_add_uint16(m, src->cursor.flags);
+ if (!(src->cursor.flags & SPICE_CURSOR_FLAGS_NONE)) {
+ spice_marshaller_add_uint64(m, src->cursor.header.unique);
+ spice_marshaller_add_uint8(m, src->cursor.header.type);
+ spice_marshaller_add_uint16(m, src->cursor.header.width);
+ spice_marshaller_add_uint16(m, src->cursor.header.height);
+ spice_marshaller_add_uint16(m, src->cursor.header.hot_spot_x);
+ spice_marshaller_add_uint16(m, src->cursor.header.hot_spot_y);
+ }
+ /* Remaining data must be appended manually */
+ }
+}
+
+void spice_marshall_msg_cursor_move(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgCursorMove *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgCursorMove *src;
+ src = (SpiceMsgCursorMove *)msg;
+
+ /* position */ {
+ spice_marshaller_add_int16(m, src->position.x);
+ spice_marshaller_add_int16(m, src->position.y);
+ }
+}
+
+void spice_marshall_msg_cursor_trail(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgCursorTrail *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgCursorTrail *src;
+ src = (SpiceMsgCursorTrail *)msg;
+
+ spice_marshaller_add_uint16(m, src->length);
+ spice_marshaller_add_uint16(m, src->frequency);
+}
+
+void spice_marshall_msg_cursor_inval_one(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgDisplayInvalOne *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayInvalOne *src;
+ src = (SpiceMsgDisplayInvalOne *)msg;
+
+ spice_marshaller_add_uint64(m, src->id);
+}
+
+void spice_marshall_msg_playback_data(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgPlaybackPacket *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgPlaybackPacket *src;
+ src = (SpiceMsgPlaybackPacket *)msg;
+
+ spice_marshaller_add_uint32(m, src->time);
+ /* Remaining data must be appended manually */
+}
+
+void spice_marshall_msg_playback_mode(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgPlaybackMode *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgPlaybackMode *src;
+ src = (SpiceMsgPlaybackMode *)msg;
+
+ spice_marshaller_add_uint32(m, src->time);
+ spice_marshaller_add_uint16(m, src->mode);
+ /* Remaining data must be appended manually */
+}
+
+void spice_marshall_msg_playback_start(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgPlaybackStart *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgPlaybackStart *src;
+ src = (SpiceMsgPlaybackStart *)msg;
+
+ spice_marshaller_add_uint32(m, src->channels);
+ spice_marshaller_add_uint16(m, src->format);
+ spice_marshaller_add_uint32(m, src->frequency);
+ spice_marshaller_add_uint32(m, src->time);
+}
+
+void spice_marshall_SpiceMsgAudioVolume(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgAudioVolume *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgAudioVolume *src;
+ uint16_t *volume__element;
+ uint32_t i;
+ src = (SpiceMsgAudioVolume *)msg;
+
+ spice_marshaller_add_uint8(m, src->nchannels);
+ volume__element = src->volume;
+ for (i = 0; i < src->nchannels; i++) {
+ spice_marshaller_add_uint16(m, *volume__element);
+ volume__element++;
+ }
+}
+
+void spice_marshall_SpiceMsgAudioMute(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgAudioMute *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgAudioMute *src;
+ src = (SpiceMsgAudioMute *)msg;
+
+ spice_marshaller_add_uint8(m, src->mute);
+}
+
+void spice_marshall_msg_playback_latency(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgPlaybackLatency *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgPlaybackLatency *src;
+ src = (SpiceMsgPlaybackLatency *)msg;
+
+ spice_marshaller_add_uint32(m, src->latency_ms);
+}
+
+void spice_marshall_msg_record_start(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgRecordStart *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgRecordStart *src;
+ src = (SpiceMsgRecordStart *)msg;
+
+ spice_marshaller_add_uint32(m, src->channels);
+ spice_marshaller_add_uint16(m, src->format);
+ spice_marshaller_add_uint32(m, src->frequency);
+}
+
+void spice_marshall_msg_tunnel_init(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgTunnelInit *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgTunnelInit *src;
+ src = (SpiceMsgTunnelInit *)msg;
+
+ spice_marshaller_add_uint16(m, src->max_num_of_sockets);
+ spice_marshaller_add_uint32(m, src->max_socket_data_size);
+}
+
+void spice_marshall_msg_tunnel_service_ip_map(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgTunnelServiceIpMap *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgTunnelServiceIpMap *src;
+ uint32_t i;
+ src = (SpiceMsgTunnelServiceIpMap *)msg;
+
+ spice_marshaller_add_uint32(m, src->service_id);
+ /* virtual_ip */ {
+ uint8_t *ipv4__element;
+ spice_marshaller_add_uint16(m, src->virtual_ip.type);
+ if (src->virtual_ip.type == SPICE_TUNNEL_IP_TYPE_IPv4) {
+ ipv4__element = src->virtual_ip.u.ipv4;
+ for (i = 0; i < 4; i++) {
+ spice_marshaller_add_uint8(m, *ipv4__element);
+ ipv4__element++;
+ }
+ }
+ }
+}
+
+void spice_marshall_msg_tunnel_socket_open(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgTunnelSocketOpen *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgTunnelSocketOpen *src;
+ src = (SpiceMsgTunnelSocketOpen *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+ spice_marshaller_add_uint32(m, src->service_id);
+ spice_marshaller_add_uint32(m, src->tokens);
+}
+
+void spice_marshall_msg_tunnel_socket_fin(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgTunnelSocketFin *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgTunnelSocketFin *src;
+ src = (SpiceMsgTunnelSocketFin *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+}
+
+void spice_marshall_msg_tunnel_socket_close(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgTunnelSocketClose *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgTunnelSocketClose *src;
+ src = (SpiceMsgTunnelSocketClose *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+}
+
+void spice_marshall_msg_tunnel_socket_data(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgTunnelSocketData *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgTunnelSocketData *src;
+ src = (SpiceMsgTunnelSocketData *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+ /* Remaining data must be appended manually */
+}
+
+void spice_marshall_msg_tunnel_socket_closed_ack(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgTunnelSocketClosedAck *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgTunnelSocketClosedAck *src;
+ src = (SpiceMsgTunnelSocketClosedAck *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+}
+
+void spice_marshall_msg_tunnel_socket_token(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgTunnelSocketTokens *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgTunnelSocketTokens *src;
+ src = (SpiceMsgTunnelSocketTokens *)msg;
+
+ spice_marshaller_add_uint16(m, src->connection_id);
+ spice_marshaller_add_uint32(m, src->num_tokens);
+}
+
+#ifdef USE_SMARTCARD
+void spice_marshall_msg_smartcard_data(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgSmartcard *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgSmartcard *src;
+ src = (SpiceMsgSmartcard *)msg;
+
+ spice_marshaller_add_uint32(m, src->type);
+ spice_marshaller_add_uint32(m, src->reader_id);
+ spice_marshaller_add_uint32(m, src->length);
+ /* Don't marshall @nomarshal data */
+}
+
+#endif /* USE_SMARTCARD */
+void spice_marshall_SpiceMsgCompressedData(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgCompressedData *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgCompressedData *src;
+ src = (SpiceMsgCompressedData *)msg;
+
+ spice_marshaller_add_uint8(m, src->type);
+ if (src->type == SPICE_DATA_COMPRESSION_TYPE_NONE) {
+ } else if (1) {
+ spice_marshaller_add_uint32(m, src->uncompressed_size);
+ }
+ /* Remaining data must be appended manually */
+}
+
+void spice_marshall_msg_port_init(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgPortInit *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgPortInit *src;
+ src = (SpiceMsgPortInit *)msg;
+
+ spice_marshaller_add_uint32(m, src->name_size);
+ m2 = spice_marshaller_get_ptr_submarshaller(m, 0);
+ spice_marshall_array_uint8(m2, src->name, src->name_size);
+ spice_marshaller_add_uint8(m, src->opened);
+}
+
+void spice_marshall_msg_port_event(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgPortEvent *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgPortEvent *src;
+ src = (SpiceMsgPortEvent *)msg;
+
+ spice_marshaller_add_uint8(m, src->event);
+}
+
+void spice_marshall_String(SpiceMarshaller *m, SpiceString *ptr)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceString *src;
+ SpiceRasterGlyph * *glyphs__element;
+ uint32_t i;
+ uint32_t j;
+
+ src = (SpiceString *)ptr;
+
+ spice_marshaller_add_uint16(m, src->length);
+ spice_marshaller_add_uint8(m, src->flags);
+ if ((src->flags & SPICE_STRING_FLAGS_RASTER_A1)) {
+ glyphs__element = src->glyphs;
+ for (i = 0; i < src->length; i++) {
+ SpiceRasterGlyph *src2;
+ uint8_t *data__element;
+ src2 = (SpiceRasterGlyph *)*glyphs__element;
+
+ /* render_pos */ {
+ spice_marshaller_add_int32(m, src2->render_pos.x);
+ spice_marshaller_add_int32(m, src2->render_pos.y);
+ }
+ /* glyph_origin */ {
+ spice_marshaller_add_int32(m, src2->glyph_origin.x);
+ spice_marshaller_add_int32(m, src2->glyph_origin.y);
+ }
+ spice_marshaller_add_uint16(m, src2->width);
+ spice_marshaller_add_uint16(m, src2->height);
+ data__element = src2->data;
+ for (j = 0; j < (unsigned) (((src2->width + 7) / 8 ) * src2->height); j++) {
+ spice_marshaller_add_uint8(m, *data__element);
+ data__element++;
+ }
+ glyphs__element++;
+ }
+ } else if ((src->flags & SPICE_STRING_FLAGS_RASTER_A4)) {
+ glyphs__element = src->glyphs;
+ for (i = 0; i < src->length; i++) {
+ SpiceRasterGlyph *src2;
+ uint8_t *data__element;
+ src2 = (SpiceRasterGlyph *)*glyphs__element;
+
+ /* render_pos */ {
+ spice_marshaller_add_int32(m, src2->render_pos.x);
+ spice_marshaller_add_int32(m, src2->render_pos.y);
+ }
+ /* glyph_origin */ {
+ spice_marshaller_add_int32(m, src2->glyph_origin.x);
+ spice_marshaller_add_int32(m, src2->glyph_origin.y);
+ }
+ spice_marshaller_add_uint16(m, src2->width);
+ spice_marshaller_add_uint16(m, src2->height);
+ data__element = src2->data;
+ for (j = 0; j < (unsigned) (((4 * src2->width + 7) / 8 ) * src2->height); j++) {
+ spice_marshaller_add_uint8(m, *data__element);
+ data__element++;
+ }
+ glyphs__element++;
+ }
+ } else if ((src->flags & SPICE_STRING_FLAGS_RASTER_A8)) {
+ glyphs__element = src->glyphs;
+ for (i = 0; i < src->length; i++) {
+ SpiceRasterGlyph *src2;
+ uint8_t *data__element;
+ src2 = (SpiceRasterGlyph *)*glyphs__element;
+
+ /* render_pos */ {
+ spice_marshaller_add_int32(m, src2->render_pos.x);
+ spice_marshaller_add_int32(m, src2->render_pos.y);
+ }
+ /* glyph_origin */ {
+ spice_marshaller_add_int32(m, src2->glyph_origin.x);
+ spice_marshaller_add_int32(m, src2->glyph_origin.y);
+ }
+ spice_marshaller_add_uint16(m, src2->width);
+ spice_marshaller_add_uint16(m, src2->height);
+ data__element = src2->data;
+ for (j = 0; j < (unsigned) (src2->width * src2->height); j++) {
+ spice_marshaller_add_uint8(m, *data__element);
+ data__element++;
+ }
+ glyphs__element++;
+ }
+ }
+}
+void spice_marshall_Rect(SpiceMarshaller *m, SpiceRect *ptr)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceRect *src;
+
+ src = (SpiceRect *)ptr;
+
+ spice_marshaller_add_int32(m, src->top);
+ spice_marshaller_add_int32(m, src->left);
+ spice_marshaller_add_int32(m, src->bottom);
+ spice_marshaller_add_int32(m, src->right);
+}
+void spice_marshall_Point(SpiceMarshaller *m, SpicePoint *ptr)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpicePoint *src;
+
+ src = (SpicePoint *)ptr;
+
+ spice_marshaller_add_int32(m, src->x);
+ spice_marshaller_add_int32(m, src->y);
+}
+void spice_marshall_DisplayBase(SpiceMarshaller *m, SpiceMsgDisplayBase *ptr)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgDisplayBase *src;
+ uint32_t i;
+
+ src = (SpiceMsgDisplayBase *)ptr;
+
+ spice_marshaller_add_uint32(m, src->surface_id);
+ /* box */ {
+ spice_marshaller_add_int32(m, src->box.top);
+ spice_marshaller_add_int32(m, src->box.left);
+ spice_marshaller_add_int32(m, src->box.bottom);
+ spice_marshaller_add_int32(m, src->box.right);
+ }
+ /* clip */ {
+ spice_marshaller_add_uint8(m, src->clip.type);
+ if (src->clip.type == SPICE_CLIP_TYPE_RECTS) {
+ SpiceRect *rects__element;
+ spice_marshaller_add_uint32(m, src->clip.rects->num_rects);
+ rects__element = src->clip.rects->rects;
+ for (i = 0; i < src->clip.rects->num_rects; i++) {
+ SpiceRect *src2;
+ src2 = (SpiceRect *)rects__element;
+
+ spice_marshaller_add_int32(m, src2->top);
+ spice_marshaller_add_int32(m, src2->left);
+ spice_marshaller_add_int32(m, src2->bottom);
+ spice_marshaller_add_int32(m, src2->right);
+ rects__element++;
+ }
+ }
+ }
+}
+void spice_marshall_Fill(SpiceMarshaller *m, SpiceFill *ptr, SpiceMarshaller **brush_pat_out, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceFill *src;
+ *brush_pat_out = NULL;
+ *mask_bitmap_out = NULL;
+
+ src = (SpiceFill *)ptr;
+
+ /* brush */ {
+ spice_marshaller_add_uint8(m, src->brush.type);
+ if (src->brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ spice_marshaller_add_uint32(m, src->brush.u.color);
+ } else if (src->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ *brush_pat_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->brush.u.pattern.pos.x);
+ spice_marshaller_add_int32(m, src->brush.u.pattern.pos.y);
+ }
+ }
+ }
+ spice_marshaller_add_uint16(m, src->rop_descriptor);
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->mask.pos.x);
+ spice_marshaller_add_int32(m, src->mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+}
+void spice_marshall_Opaque(SpiceMarshaller *m, SpiceOpaque *ptr, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **pat_out, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceOpaque *src;
+ *src_bitmap_out = NULL;
+ *pat_out = NULL;
+ *mask_bitmap_out = NULL;
+
+ src = (SpiceOpaque *)ptr;
+
+ *src_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* src_area */ {
+ spice_marshaller_add_int32(m, src->src_area.top);
+ spice_marshaller_add_int32(m, src->src_area.left);
+ spice_marshaller_add_int32(m, src->src_area.bottom);
+ spice_marshaller_add_int32(m, src->src_area.right);
+ }
+ /* brush */ {
+ spice_marshaller_add_uint8(m, src->brush.type);
+ if (src->brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ spice_marshaller_add_uint32(m, src->brush.u.color);
+ } else if (src->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ *pat_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->brush.u.pattern.pos.x);
+ spice_marshaller_add_int32(m, src->brush.u.pattern.pos.y);
+ }
+ }
+ }
+ spice_marshaller_add_uint16(m, src->rop_descriptor);
+ spice_marshaller_add_uint8(m, src->scale_mode);
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->mask.pos.x);
+ spice_marshaller_add_int32(m, src->mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+}
+void spice_marshall_Copy(SpiceMarshaller *m, SpiceCopy *ptr, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceCopy *src;
+ *src_bitmap_out = NULL;
+ *mask_bitmap_out = NULL;
+
+ src = (SpiceCopy *)ptr;
+
+ *src_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* src_area */ {
+ spice_marshaller_add_int32(m, src->src_area.top);
+ spice_marshaller_add_int32(m, src->src_area.left);
+ spice_marshaller_add_int32(m, src->src_area.bottom);
+ spice_marshaller_add_int32(m, src->src_area.right);
+ }
+ spice_marshaller_add_uint16(m, src->rop_descriptor);
+ spice_marshaller_add_uint8(m, src->scale_mode);
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->mask.pos.x);
+ spice_marshaller_add_int32(m, src->mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+}
+void spice_marshall_Blend(SpiceMarshaller *m, SpiceCopy *ptr, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceCopy *src;
+ *src_bitmap_out = NULL;
+ *mask_bitmap_out = NULL;
+
+ src = (SpiceCopy *)ptr;
+
+ *src_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* src_area */ {
+ spice_marshaller_add_int32(m, src->src_area.top);
+ spice_marshaller_add_int32(m, src->src_area.left);
+ spice_marshaller_add_int32(m, src->src_area.bottom);
+ spice_marshaller_add_int32(m, src->src_area.right);
+ }
+ spice_marshaller_add_uint16(m, src->rop_descriptor);
+ spice_marshaller_add_uint8(m, src->scale_mode);
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->mask.pos.x);
+ spice_marshaller_add_int32(m, src->mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+}
+void spice_marshall_Blackness(SpiceMarshaller *m, SpiceBlackness *ptr, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceBlackness *src;
+ *mask_bitmap_out = NULL;
+
+ src = (SpiceBlackness *)ptr;
+
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->mask.pos.x);
+ spice_marshaller_add_int32(m, src->mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+}
+void spice_marshall_Whiteness(SpiceMarshaller *m, SpiceWhiteness *ptr, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceWhiteness *src;
+ *mask_bitmap_out = NULL;
+
+ src = (SpiceWhiteness *)ptr;
+
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->mask.pos.x);
+ spice_marshaller_add_int32(m, src->mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+}
+void spice_marshall_Invers(SpiceMarshaller *m, SpiceInvers *ptr, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceInvers *src;
+ *mask_bitmap_out = NULL;
+
+ src = (SpiceInvers *)ptr;
+
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->mask.pos.x);
+ spice_marshaller_add_int32(m, src->mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+}
+void spice_marshall_Rop3(SpiceMarshaller *m, SpiceRop3 *ptr, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **pat_out, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceRop3 *src;
+ *src_bitmap_out = NULL;
+ *pat_out = NULL;
+ *mask_bitmap_out = NULL;
+
+ src = (SpiceRop3 *)ptr;
+
+ *src_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* src_area */ {
+ spice_marshaller_add_int32(m, src->src_area.top);
+ spice_marshaller_add_int32(m, src->src_area.left);
+ spice_marshaller_add_int32(m, src->src_area.bottom);
+ spice_marshaller_add_int32(m, src->src_area.right);
+ }
+ /* brush */ {
+ spice_marshaller_add_uint8(m, src->brush.type);
+ if (src->brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ spice_marshaller_add_uint32(m, src->brush.u.color);
+ } else if (src->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ *pat_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->brush.u.pattern.pos.x);
+ spice_marshaller_add_int32(m, src->brush.u.pattern.pos.y);
+ }
+ }
+ }
+ spice_marshaller_add_uint8(m, src->rop3);
+ spice_marshaller_add_uint8(m, src->scale_mode);
+ /* mask */ {
+ spice_marshaller_add_uint8(m, src->mask.flags);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->mask.pos.x);
+ spice_marshaller_add_int32(m, src->mask.pos.y);
+ }
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+}
+void spice_marshall_Path(SpiceMarshaller *m, SpicePath *ptr)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpicePath *src;
+ SpicePathSeg * *segments__element;
+ uint32_t i;
+ uint32_t j;
+
+ src = (SpicePath *)ptr;
+
+ spice_marshaller_add_uint32(m, src->num_segments);
+ segments__element = src->segments;
+ for (i = 0; i < src->num_segments; i++) {
+ SpicePathSeg *src2;
+ SpicePointFix *points__element;
+ src2 = (SpicePathSeg *)*segments__element;
+
+ spice_marshaller_add_uint8(m, src2->flags);
+ spice_marshaller_add_uint32(m, src2->count);
+ points__element = src2->points;
+ for (j = 0; j < src2->count; j++) {
+ SpicePointFix *src3;
+ src3 = (SpicePointFix *)points__element;
+
+ spice_marshaller_add_int32(m, src3->x);
+ spice_marshaller_add_int32(m, src3->y);
+ points__element++;
+ }
+ segments__element++;
+ }
+}
+
+SPICE_GNUC_UNUSED static void spice_marshall_array_int32(SpiceMarshaller *m, int32_t *ptr, unsigned count)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ uint32_t i;
+
+ for (i = 0; i < count; i++) {
+ spice_marshaller_add_int32(m, *ptr++);
+ }
+}
+
+void spice_marshall_Stroke(SpiceMarshaller *m, SpiceStroke *ptr, SpiceMarshaller **style_out, SpiceMarshaller **pat_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceStroke *src;
+ *style_out = NULL;
+ *pat_out = NULL;
+
+ src = (SpiceStroke *)ptr;
+
+ m2 = spice_marshaller_get_ptr_submarshaller(m, 0);
+ spice_marshall_Path(m2, src->path);
+ /* attr */ {
+ spice_marshaller_add_uint8(m, src->attr.flags);
+ if ((src->attr.flags & SPICE_LINE_FLAGS_STYLED)) {
+ spice_marshaller_add_uint8(m, src->attr.style_nseg);
+ }
+ if ((src->attr.flags & SPICE_LINE_FLAGS_STYLED)) {
+ *style_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+ }
+ /* brush */ {
+ spice_marshaller_add_uint8(m, src->brush.type);
+ if (src->brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ spice_marshaller_add_uint32(m, src->brush.u.color);
+ } else if (src->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ *pat_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->brush.u.pattern.pos.x);
+ spice_marshaller_add_int32(m, src->brush.u.pattern.pos.y);
+ }
+ }
+ }
+ spice_marshaller_add_uint16(m, src->fore_mode);
+ spice_marshaller_add_uint16(m, src->back_mode);
+}
+void spice_marshall_Text(SpiceMarshaller *m, SpiceText *ptr, SpiceMarshaller **fore_brush_pat_out, SpiceMarshaller **back_brush_pat_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceText *src;
+ *fore_brush_pat_out = NULL;
+ *back_brush_pat_out = NULL;
+
+ src = (SpiceText *)ptr;
+
+ m2 = spice_marshaller_get_ptr_submarshaller(m, 0);
+ spice_marshall_String(m2, src->str);
+ /* back_area */ {
+ spice_marshaller_add_int32(m, src->back_area.top);
+ spice_marshaller_add_int32(m, src->back_area.left);
+ spice_marshaller_add_int32(m, src->back_area.bottom);
+ spice_marshaller_add_int32(m, src->back_area.right);
+ }
+ /* fore_brush */ {
+ spice_marshaller_add_uint8(m, src->fore_brush.type);
+ if (src->fore_brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ spice_marshaller_add_uint32(m, src->fore_brush.u.color);
+ } else if (src->fore_brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ *fore_brush_pat_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->fore_brush.u.pattern.pos.x);
+ spice_marshaller_add_int32(m, src->fore_brush.u.pattern.pos.y);
+ }
+ }
+ }
+ /* back_brush */ {
+ spice_marshaller_add_uint8(m, src->back_brush.type);
+ if (src->back_brush.type == SPICE_BRUSH_TYPE_SOLID) {
+ spice_marshaller_add_uint32(m, src->back_brush.u.color);
+ } else if (src->back_brush.type == SPICE_BRUSH_TYPE_PATTERN) {
+ *back_brush_pat_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* pos */ {
+ spice_marshaller_add_int32(m, src->back_brush.u.pattern.pos.x);
+ spice_marshaller_add_int32(m, src->back_brush.u.pattern.pos.y);
+ }
+ }
+ }
+ spice_marshaller_add_uint16(m, src->fore_mode);
+ spice_marshaller_add_uint16(m, src->back_mode);
+}
+void spice_marshall_Transparent(SpiceMarshaller *m, SpiceTransparent *ptr, SpiceMarshaller **src_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceTransparent *src;
+ *src_bitmap_out = NULL;
+
+ src = (SpiceTransparent *)ptr;
+
+ *src_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* src_area */ {
+ spice_marshaller_add_int32(m, src->src_area.top);
+ spice_marshaller_add_int32(m, src->src_area.left);
+ spice_marshaller_add_int32(m, src->src_area.bottom);
+ spice_marshaller_add_int32(m, src->src_area.right);
+ }
+ spice_marshaller_add_uint32(m, src->src_color);
+ spice_marshaller_add_uint32(m, src->true_color);
+}
+void spice_marshall_AlphaBlend(SpiceMarshaller *m, SpiceAlphaBlend *ptr, SpiceMarshaller **src_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceAlphaBlend *src;
+ *src_bitmap_out = NULL;
+
+ src = (SpiceAlphaBlend *)ptr;
+
+ spice_marshaller_add_uint8(m, src->alpha_flags);
+ spice_marshaller_add_uint8(m, src->alpha);
+ *src_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ /* src_area */ {
+ spice_marshaller_add_int32(m, src->src_area.top);
+ spice_marshaller_add_int32(m, src->src_area.left);
+ spice_marshaller_add_int32(m, src->src_area.bottom);
+ spice_marshaller_add_int32(m, src->src_area.right);
+ }
+}
+void spice_marshall_Composite(SpiceMarshaller *m, SpiceComposite *ptr, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **mask_bitmap_out)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceComposite *src;
+ *src_bitmap_out = NULL;
+ *mask_bitmap_out = NULL;
+
+ src = (SpiceComposite *)ptr;
+
+ spice_marshaller_add_uint32(m, src->flags);
+ *src_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ if ((src->flags & SPICE_COMPOSITE_HAS_MASK)) {
+ *mask_bitmap_out = spice_marshaller_get_ptr_submarshaller(m, 0);
+ }
+ if ((src->flags & SPICE_COMPOSITE_HAS_SRC_TRANSFORM)) {
+ spice_marshaller_add_uint32(m, src->src_transform.t00);
+ spice_marshaller_add_uint32(m, src->src_transform.t01);
+ spice_marshaller_add_uint32(m, src->src_transform.t02);
+ spice_marshaller_add_uint32(m, src->src_transform.t10);
+ spice_marshaller_add_uint32(m, src->src_transform.t11);
+ spice_marshaller_add_uint32(m, src->src_transform.t12);
+ }
+ if ((src->flags & SPICE_COMPOSITE_HAS_MASK_TRANSFORM)) {
+ spice_marshaller_add_uint32(m, src->mask_transform.t00);
+ spice_marshaller_add_uint32(m, src->mask_transform.t01);
+ spice_marshaller_add_uint32(m, src->mask_transform.t02);
+ spice_marshaller_add_uint32(m, src->mask_transform.t10);
+ spice_marshaller_add_uint32(m, src->mask_transform.t11);
+ spice_marshaller_add_uint32(m, src->mask_transform.t12);
+ }
+ /* src_origin */ {
+ spice_marshaller_add_int16(m, src->src_origin.x);
+ spice_marshaller_add_int16(m, src->src_origin.y);
+ }
+ /* mask_origin */ {
+ spice_marshaller_add_int16(m, src->mask_origin.x);
+ spice_marshaller_add_int16(m, src->mask_origin.y);
+ }
+}
--- /dev/null
+/* this is a file autogenerated by spice_codegen.py */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "common/messages.h"
+#include <spice/protocol.h>
+#include "common/marshaller.h"
+
+#ifndef _H_GENERATED_SERVER_MARSHALLERS
+#define _H_GENERATED_SERVER_MARSHALLERS
+
+SPICE_BEGIN_DECLS
+
+void spice_marshall_msg_migrate(SpiceMarshaller *m, SpiceMsgMigrate *msg);
+void spice_marshall_SpiceMsgData(SpiceMarshaller *m, SpiceMsgData *msg);
+void spice_marshall_msg_set_ack(SpiceMarshaller *m, SpiceMsgSetAck *msg);
+void spice_marshall_msg_ping(SpiceMarshaller *m, SpiceMsgPing *msg);
+void spice_marshall_msg_wait_for_channels(SpiceMarshaller *m, SpiceMsgWaitForChannels *msg);
+void spice_marshall_msg_disconnecting(SpiceMarshaller *m, SpiceMsgDisconnect *msg);
+void spice_marshall_msg_notify(SpiceMarshaller *m, SpiceMsgNotify *msg);
+void spice_marshall_SpiceMsgEmpty(SpiceMarshaller *m, SpiceMsgEmpty *msg);
+void spice_marshall_msg_main_migrate_begin(SpiceMarshaller *m, SpiceMsgMainMigrationBegin *msg);
+void spice_marshall_msg_main_init(SpiceMarshaller *m, SpiceMsgMainInit *msg);
+void spice_marshall_msg_main_channels_list(SpiceMarshaller *m, SpiceMsgChannels *msg);
+void spice_marshall_msg_main_mouse_mode(SpiceMarshaller *m, SpiceMsgMainMouseMode *msg);
+void spice_marshall_msg_main_multi_media_time(SpiceMarshaller *m, SpiceMsgMainMultiMediaTime *msg);
+void spice_marshall_msg_main_agent_disconnected(SpiceMarshaller *m, SpiceMsgMainAgentDisconnect *msg);
+void spice_marshall_msg_main_agent_token(SpiceMarshaller *m, SpiceMsgMainAgentTokens *msg);
+void spice_marshall_msg_main_migrate_switch_host(SpiceMarshaller *m, SpiceMsgMainMigrationSwitchHost *msg);
+void spice_marshall_msg_main_name(SpiceMarshaller *m, SpiceMsgMainName *msg);
+void spice_marshall_msg_main_uuid(SpiceMarshaller *m, SpiceMsgMainUuid *msg);
+void spice_marshall_msg_main_agent_connected_tokens(SpiceMarshaller *m, SpiceMsgMainAgentConnectedTokens *msg);
+void spice_marshall_msg_main_migrate_begin_seamless(SpiceMarshaller *m, SpiceMsgMainMigrateBeginSeamless *msg);
+void spice_marshall_msg_display_mode(SpiceMarshaller *m, SpiceMsgDisplayMode *msg);
+void spice_marshall_msg_display_copy_bits(SpiceMarshaller *m, SpiceMsgDisplayCopyBits *msg);
+void spice_marshall_msg_display_inval_list(SpiceMarshaller *m, SpiceResourceList *msg);
+void spice_marshall_msg_display_inval_all_pixmaps(SpiceMarshaller *m, SpiceMsgWaitForChannels *msg);
+void spice_marshall_msg_display_inval_palette(SpiceMarshaller *m, SpiceMsgDisplayInvalOne *msg);
+void spice_marshall_msg_display_stream_create(SpiceMarshaller *m, SpiceMsgDisplayStreamCreate *msg);
+void spice_marshall_msg_display_stream_data(SpiceMarshaller *m, SpiceMsgDisplayStreamData *msg);
+void spice_marshall_msg_display_stream_clip(SpiceMarshaller *m, SpiceMsgDisplayStreamClip *msg);
+void spice_marshall_msg_display_stream_destroy(SpiceMarshaller *m, SpiceMsgDisplayStreamDestroy *msg);
+void spice_marshall_msg_display_draw_fill(SpiceMarshaller *m, SpiceMsgDisplayDrawFill *msg, SpiceMarshaller **brush_pat_out, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_msg_display_draw_opaque(SpiceMarshaller *m, SpiceMsgDisplayDrawOpaque *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **pat_out, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_msg_display_draw_copy(SpiceMarshaller *m, SpiceMsgDisplayDrawCopy *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_Image(SpiceMarshaller *m, SpiceImage *msg, SpiceMarshaller **bitmap_palette_out, SpiceMarshaller **lzplt_palette_out);
+void spice_marshall_Palette(SpiceMarshaller *m, SpicePalette *msg);
+void spice_marshall_msg_display_draw_blend(SpiceMarshaller *m, SpiceMsgDisplayDrawBlend *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_msg_display_draw_blackness(SpiceMarshaller *m, SpiceMsgDisplayDrawBlackness *msg, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_msg_display_draw_whiteness(SpiceMarshaller *m, SpiceMsgDisplayDrawWhiteness *msg, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_msg_display_draw_invers(SpiceMarshaller *m, SpiceMsgDisplayDrawInvers *msg, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_msg_display_draw_rop3(SpiceMarshaller *m, SpiceMsgDisplayDrawRop3 *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **pat_out, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_msg_display_draw_stroke(SpiceMarshaller *m, SpiceMsgDisplayDrawStroke *msg, SpiceMarshaller **style_out, SpiceMarshaller **pat_out);
+void spice_marshall_msg_display_draw_text(SpiceMarshaller *m, SpiceMsgDisplayDrawText *msg, SpiceMarshaller **fore_brush_pat_out, SpiceMarshaller **back_brush_pat_out);
+void spice_marshall_msg_display_draw_transparent(SpiceMarshaller *m, SpiceMsgDisplayDrawTransparent *msg, SpiceMarshaller **src_bitmap_out);
+void spice_marshall_msg_display_draw_alpha_blend(SpiceMarshaller *m, SpiceMsgDisplayDrawAlphaBlend *msg, SpiceMarshaller **src_bitmap_out);
+void spice_marshall_msg_display_surface_create(SpiceMarshaller *m, SpiceMsgSurfaceCreate *msg);
+void spice_marshall_msg_display_surface_destroy(SpiceMarshaller *m, SpiceMsgSurfaceDestroy *msg);
+void spice_marshall_msg_display_stream_data_sized(SpiceMarshaller *m, SpiceMsgDisplayStreamDataSized *msg);
+void spice_marshall_msg_display_monitors_config(SpiceMarshaller *m, SpiceMsgDisplayMonitorsConfig *msg);
+void spice_marshall_msg_display_draw_composite(SpiceMarshaller *m, SpiceMsgDisplayDrawComposite *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_msg_display_stream_activate_report(SpiceMarshaller *m, SpiceMsgDisplayStreamActivateReport *msg);
+void spice_marshall_msg_display_gl_scanout_unix(SpiceMarshaller *m, SpiceMsgDisplayGlScanoutUnix *msg);
+void spice_marshall_msg_display_gl_draw(SpiceMarshaller *m, SpiceMsgDisplayGlDraw *msg);
+void spice_marshall_msg_inputs_init(SpiceMarshaller *m, SpiceMsgInputsInit *msg);
+void spice_marshall_msg_inputs_key_modifiers(SpiceMarshaller *m, SpiceMsgInputsKeyModifiers *msg);
+void spice_marshall_msg_cursor_init(SpiceMarshaller *m, SpiceMsgCursorInit *msg);
+void spice_marshall_msg_cursor_set(SpiceMarshaller *m, SpiceMsgCursorSet *msg);
+void spice_marshall_msg_cursor_move(SpiceMarshaller *m, SpiceMsgCursorMove *msg);
+void spice_marshall_msg_cursor_trail(SpiceMarshaller *m, SpiceMsgCursorTrail *msg);
+void spice_marshall_msg_cursor_inval_one(SpiceMarshaller *m, SpiceMsgDisplayInvalOne *msg);
+void spice_marshall_msg_playback_data(SpiceMarshaller *m, SpiceMsgPlaybackPacket *msg);
+void spice_marshall_msg_playback_mode(SpiceMarshaller *m, SpiceMsgPlaybackMode *msg);
+void spice_marshall_msg_playback_start(SpiceMarshaller *m, SpiceMsgPlaybackStart *msg);
+void spice_marshall_SpiceMsgAudioVolume(SpiceMarshaller *m, SpiceMsgAudioVolume *msg);
+void spice_marshall_SpiceMsgAudioMute(SpiceMarshaller *m, SpiceMsgAudioMute *msg);
+void spice_marshall_msg_playback_latency(SpiceMarshaller *m, SpiceMsgPlaybackLatency *msg);
+void spice_marshall_msg_record_start(SpiceMarshaller *m, SpiceMsgRecordStart *msg);
+void spice_marshall_msg_tunnel_init(SpiceMarshaller *m, SpiceMsgTunnelInit *msg);
+void spice_marshall_msg_tunnel_service_ip_map(SpiceMarshaller *m, SpiceMsgTunnelServiceIpMap *msg);
+void spice_marshall_msg_tunnel_socket_open(SpiceMarshaller *m, SpiceMsgTunnelSocketOpen *msg);
+void spice_marshall_msg_tunnel_socket_fin(SpiceMarshaller *m, SpiceMsgTunnelSocketFin *msg);
+void spice_marshall_msg_tunnel_socket_close(SpiceMarshaller *m, SpiceMsgTunnelSocketClose *msg);
+void spice_marshall_msg_tunnel_socket_data(SpiceMarshaller *m, SpiceMsgTunnelSocketData *msg);
+void spice_marshall_msg_tunnel_socket_closed_ack(SpiceMarshaller *m, SpiceMsgTunnelSocketClosedAck *msg);
+void spice_marshall_msg_tunnel_socket_token(SpiceMarshaller *m, SpiceMsgTunnelSocketTokens *msg);
+#ifdef USE_SMARTCARD
+void spice_marshall_msg_smartcard_data(SpiceMarshaller *m, SpiceMsgSmartcard *msg);
+#endif /* USE_SMARTCARD */
+void spice_marshall_SpiceMsgCompressedData(SpiceMarshaller *m, SpiceMsgCompressedData *msg);
+void spice_marshall_msg_port_init(SpiceMarshaller *m, SpiceMsgPortInit *msg);
+void spice_marshall_msg_port_event(SpiceMarshaller *m, SpiceMsgPortEvent *msg);
+void spice_marshall_String(SpiceMarshaller *m, SpiceString *msg);
+void spice_marshall_Rect(SpiceMarshaller *m, SpiceRect *msg);
+void spice_marshall_Point(SpiceMarshaller *m, SpicePoint *msg);
+void spice_marshall_DisplayBase(SpiceMarshaller *m, SpiceMsgDisplayBase *msg);
+void spice_marshall_Fill(SpiceMarshaller *m, SpiceFill *msg, SpiceMarshaller **brush_pat_out, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_Opaque(SpiceMarshaller *m, SpiceOpaque *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **pat_out, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_Copy(SpiceMarshaller *m, SpiceCopy *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_Blend(SpiceMarshaller *m, SpiceCopy *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_Blackness(SpiceMarshaller *m, SpiceBlackness *msg, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_Whiteness(SpiceMarshaller *m, SpiceWhiteness *msg, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_Invers(SpiceMarshaller *m, SpiceInvers *msg, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_Rop3(SpiceMarshaller *m, SpiceRop3 *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **pat_out, SpiceMarshaller **mask_bitmap_out);
+void spice_marshall_Stroke(SpiceMarshaller *m, SpiceStroke *msg, SpiceMarshaller **style_out, SpiceMarshaller **pat_out);
+void spice_marshall_Path(SpiceMarshaller *m, SpicePath *msg);
+void spice_marshall_Text(SpiceMarshaller *m, SpiceText *msg, SpiceMarshaller **fore_brush_pat_out, SpiceMarshaller **back_brush_pat_out);
+void spice_marshall_Transparent(SpiceMarshaller *m, SpiceTransparent *msg, SpiceMarshaller **src_bitmap_out);
+void spice_marshall_AlphaBlend(SpiceMarshaller *m, SpiceAlphaBlend *msg, SpiceMarshaller **src_bitmap_out);
+void spice_marshall_Composite(SpiceMarshaller *m, SpiceComposite *msg, SpiceMarshaller **src_bitmap_out, SpiceMarshaller **mask_bitmap_out);
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/***********************************************************
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <spice/macros.h>
+#ifdef _XOPEN_SOURCE
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+#include "lines.h"
+#include "mem.h"
+
+#define xalloc(i) spice_malloc(i)
+#define xrealloc(a,b) spice_realloc(a,b)
+#define xfree(i) free(i)
+
+typedef unsigned int CARD32;
+typedef int Boolean;
+typedef pixman_rectangle32_t xRectangle;
+typedef SpicePoint DDXPointRec;
+typedef DDXPointRec *DDXPointPtr;
+typedef struct lineGC *GCPtr;
+
+/* largest positive value that can fit into a component of a point.
+ * Assumes that the point structure is {type x, y;} where type is
+ * a signed type.
+ */
+#define MAX_COORDINATE 2147483647
+#define MIN_COORDINATE -2147483647
+
+#define miZeroLine spice_canvas_zero_line
+#define miZeroDashLine spice_canvas_zero_dash_line
+#define miWideDash spice_canvas_wide_dash_line
+#define miWideLine spice_canvas_wide_line
+
+static inline int ICEIL (double x)
+{
+ int _cTmp = (int)x;
+ return ((x == _cTmp) || (x < 0.0)) ? _cTmp : _cTmp + 1;
+}
+
+typedef struct {
+ int count; /* number of spans */
+ DDXPointPtr points; /* pointer to list of start points */
+ int *widths; /* pointer to list of widths */
+} Spans;
+
+typedef struct {
+ int size; /* Total number of *Spans allocated */
+ int count; /* Number of *Spans actually in group */
+ Spans *group; /* List of Spans */
+ int ymin, ymax; /* Min, max y values encountered */
+} SpanGroup;
+
+/* Initialize SpanGroup. MUST BE DONE before use. */
+static void miInitSpanGroup (SpanGroup * /*spanGroup */
+ );
+
+/* Add a Spans to a SpanGroup. The spans MUST BE in y-sorted order */
+static void miAppendSpans (SpanGroup * /*spanGroup */ ,
+ SpanGroup * /*otherGroup */ ,
+ Spans * /*spans */
+ );
+
+/* Paint a span group, insuring that each pixel is painted at most once */
+static void miFillUniqueSpanGroup (GCPtr /*pGC */ ,
+ SpanGroup * /*spanGroup */ ,
+ Boolean /* foreground */
+ );
+
+/* Free up data in a span group. MUST BE DONE or you'll suffer memory leaks */
+static void miFreeSpanGroup (SpanGroup * /*spanGroup */
+ );
+
+/* Rops which must use span groups */
+#define miSpansCarefulRop(rop) (((rop) & 0xc) == 0x8 || ((rop) & 0x3) == 0x2)
+#define miSpansEasyRop(rop) (!miSpansCarefulRop(rop))
+
+/*
+ * Public definitions used for configuring basic pixelization aspects
+ * of the sample implementation line-drawing routines provided in
+ * {mfb,mi,cfb*} at run-time.
+ */
+
+#define XDECREASING 4
+#define YDECREASING 2
+#define YMAJOR 1
+
+#define OCTANT1 (1 << (YDECREASING))
+#define OCTANT2 (1 << (YDECREASING|YMAJOR))
+#define OCTANT3 (1 << (XDECREASING|YDECREASING|YMAJOR))
+#define OCTANT4 (1 << (XDECREASING|YDECREASING))
+#define OCTANT5 (1 << (XDECREASING))
+#define OCTANT6 (1 << (XDECREASING|YMAJOR))
+#define OCTANT7 (1 << (YMAJOR))
+#define OCTANT8 (1 << (0))
+
+#define XMAJOROCTANTS (OCTANT1 | OCTANT4 | OCTANT5 | OCTANT8)
+
+#define DEFAULTZEROLINEBIAS (OCTANT2 | OCTANT3 | OCTANT4 | OCTANT5)
+
+/*
+ * Devices can configure the rendering of routines in mi, mfb, and cfb*
+ * by specifying a thin line bias to be applied to a particular screen
+ * using the following function. The bias parameter is an OR'ing of
+ * the appropriate OCTANT constants defined above to indicate which
+ * octants to bias a line to prefer an axial step when the Bresenham
+ * error term is exactly zero. The octants are mapped as follows:
+ *
+ * \ | /
+ * \ 3 | 2 /
+ * \ | /
+ * 4 \ | / 1
+ * \|/
+ * -----------
+ * /|\
+ * 5 / | \ 8
+ * / | \
+ * / 6 | 7 \
+ * / | \
+ *
+ * For more information, see "Ambiguities in Incremental Line Rastering,"
+ * Jack E. Bresenham, IEEE CG&A, May 1987.
+ */
+
+/*
+ * Private definitions needed for drawing thin (zero width) lines
+ * Used by the mi, mfb, and all cfb* components.
+ */
+
+#define X_AXIS 0
+#define Y_AXIS 1
+
+#define OUT_LEFT 0x08
+#define OUT_RIGHT 0x04
+#define OUT_ABOVE 0x02
+#define OUT_BELOW 0x01
+
+#define OUTCODES(_result, _x, _y, _pbox) \
+ if ( (_x) < (_pbox)->x1) (_result) |= OUT_LEFT; \
+ else if ( (_x) >= (_pbox)->x2) (_result) |= OUT_RIGHT; \
+ if ( (_y) < (_pbox)->y1) (_result) |= OUT_ABOVE; \
+ else if ( (_y) >= (_pbox)->y2) (_result) |= OUT_BELOW;
+
+#define MIOUTCODES(outcode, x, y, xmin, ymin, xmax, ymax) \
+{\
+ if (x < xmin) outcode |= OUT_LEFT;\
+ if (x > xmax) outcode |= OUT_RIGHT;\
+ if (y < ymin) outcode |= OUT_ABOVE;\
+ if (y > ymax) outcode |= OUT_BELOW;\
+}
+
+#define SWAPINT(i, j) \
+{ int _t = i; i = j; j = _t; }
+
+#define SWAPPT(i, j) \
+{ DDXPointRec _t; _t = i; i = j; j = _t; }
+
+#define SWAPINT_PAIR(x1, y1, x2, y2)\
+{ int t = x1; x1 = x2; x2 = t;\
+ t = y1; y1 = y2; y2 = t;\
+}
+
+#define miGetZeroLineBias(_pScreen) (DEFAULTZEROLINEBIAS)
+
+#define CalcLineDeltas(_x1,_y1,_x2,_y2,_adx,_ady,_sx,_sy,_SX,_SY,_octant) \
+ (_octant) = 0; \
+ (_sx) = (_SX); \
+ if (((_adx) = (_x2) - (_x1)) < 0) { \
+ (_adx) = -(_adx); \
+ (_sx = -(_sx)); \
+ (_octant) |= XDECREASING; \
+ } \
+ (_sy) = (_SY); \
+ if (((_ady) = (_y2) - (_y1)) < 0) { \
+ (_ady) = -(_ady); \
+ (_sy = -(_sy)); \
+ (_octant) |= YDECREASING; \
+ }
+
+#define SetYMajorOctant(_octant) ((_octant) |= YMAJOR)
+
+#define FIXUP_ERROR(_e, _octant, _bias) \
+ (_e) -= (((_bias) >> (_octant)) & 1)
+
+#define IsXMajorOctant(_octant) (!((_octant) & YMAJOR))
+#define IsYMajorOctant(_octant) ((_octant) & YMAJOR)
+#define IsXDecreasingOctant(_octant) ((_octant) & XDECREASING)
+#define IsYDecreasingOctant(_octant) ((_octant) & YDECREASING)
+
+static int miZeroClipLine (int /*xmin */ ,
+ int /*ymin */ ,
+ int /*xmax */ ,
+ int /*ymax */ ,
+ int * /*new_x1 */ ,
+ int * /*new_y1 */ ,
+ int * /*new_x2 */ ,
+ int * /*new_y2 */ ,
+ unsigned int /*adx */ ,
+ unsigned int /*ady */ ,
+ int * /*pt1_clipped */ ,
+ int * /*pt2_clipped */ ,
+ int /*octant */ ,
+ unsigned int /*bias */ ,
+ int /*oc1 */ ,
+ int /*oc2 */
+ );
+
+/*
+ * interface data to span-merging polygon filler
+ */
+
+typedef struct _SpanData {
+ SpanGroup fgGroup, bgGroup;
+} SpanDataRec, *SpanDataPtr;
+
+#define AppendSpanGroup(pGC, foreground, spanPtr, spanData) { \
+ SpanGroup *group, *othergroup = NULL; \
+ if (foreground) \
+ { \
+ group = &spanData->fgGroup; \
+ if (pGC->lineStyle == LineDoubleDash) \
+ othergroup = &spanData->bgGroup; \
+ } \
+ else \
+ { \
+ group = &spanData->bgGroup; \
+ othergroup = &spanData->fgGroup; \
+ } \
+ miAppendSpans (group, othergroup, spanPtr); \
+}
+
+/*
+ * Polygon edge description for integer wide-line routines
+ */
+
+typedef struct _PolyEdge {
+ int height; /* number of scanlines to process */
+ int x; /* starting x coordinate */
+ int stepx; /* fixed integral dx */
+ int signdx; /* variable dx sign */
+ int e; /* initial error term */
+ int dy;
+ int dx;
+} PolyEdgeRec, *PolyEdgePtr;
+
+#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - miter limit constant */
+
+/*
+ * types for general polygon routines
+ */
+
+typedef struct _PolyVertex {
+ double x, y;
+} PolyVertexRec, *PolyVertexPtr;
+
+typedef struct _PolySlope {
+ int dx, dy;
+ double k; /* x0 * dy - y0 * dx */
+} PolySlopeRec, *PolySlopePtr;
+
+/*
+ * Line face description for caps/joins
+ */
+
+typedef struct _LineFace {
+ double xa, ya;
+ int dx, dy;
+ int x, y;
+ double k;
+} LineFaceRec, *LineFacePtr;
+
+/*
+ * macros for polygon fillers
+ */
+
+#define MIPOLYRELOADLEFT if (!left_height && left_count) { \
+ left_height = left->height; \
+ left_x = left->x; \
+ left_stepx = left->stepx; \
+ left_signdx = left->signdx; \
+ left_e = left->e; \
+ left_dy = left->dy; \
+ left_dx = left->dx; \
+ --left_count; \
+ ++left; \
+ }
+
+#define MIPOLYRELOADRIGHT if (!right_height && right_count) { \
+ right_height = right->height; \
+ right_x = right->x; \
+ right_stepx = right->stepx; \
+ right_signdx = right->signdx; \
+ right_e = right->e; \
+ right_dy = right->dy; \
+ right_dx = right->dx; \
+ --right_count; \
+ ++right; \
+ }
+
+#define MIPOLYSTEPLEFT left_x += left_stepx; \
+ left_e += left_dx; \
+ if (left_e > 0) \
+ { \
+ left_x += left_signdx; \
+ left_e -= left_dy; \
+ }
+
+#define MIPOLYSTEPRIGHT right_x += right_stepx; \
+ right_e += right_dx; \
+ if (right_e > 0) \
+ { \
+ right_x += right_signdx; \
+ right_e -= right_dy; \
+ }
+
+static void miRoundJoinClip (LineFacePtr /*pLeft */ ,
+ LineFacePtr /*pRight */ ,
+ PolyEdgePtr /*edge1 */ ,
+ PolyEdgePtr /*edge2 */ ,
+ int * /*y1 */ ,
+ int * /*y2 */ ,
+ Boolean * /*left1 */ ,
+ Boolean * /*left2 */
+ );
+
+static int miRoundCapClip (LineFacePtr /*face */ ,
+ Boolean /*isInt */ ,
+ PolyEdgePtr /*edge */ ,
+ Boolean * /*leftEdge */
+ );
+
+static int miPolyBuildEdge (double x0, double y0, double k, int dx, int dy,
+ int xi, int yi, int left, PolyEdgePtr edge);
+static int miPolyBuildPoly (PolyVertexPtr vertices, PolySlopePtr slopes,
+ int count, int xi, int yi, PolyEdgePtr left,
+ PolyEdgePtr right, int *pnleft, int *pnright, int *h);
+
+
+static void
+miStepDash (int dist, /* distance to step */
+ int *pDashIndex, /* current dash */
+ unsigned char *pDash, /* dash list */
+ int numInDashList, /* total length of dash list */
+ int *pDashOffset /* offset into current dash */
+ )
+{
+ int dashIndex, dashOffset;
+ int totallen;
+ int i;
+
+ dashIndex = *pDashIndex;
+ dashOffset = *pDashOffset;
+ if (dist < pDash[dashIndex] - dashOffset) {
+ *pDashOffset = dashOffset + dist;
+ return;
+ }
+ dist -= pDash[dashIndex] - dashOffset;
+ if (++dashIndex == numInDashList)
+ dashIndex = 0;
+ totallen = 0;
+ for (i = 0; i < numInDashList; i++)
+ totallen += pDash[i];
+ if (totallen > 0 && totallen <= dist)
+ dist = dist % totallen;
+ while (dist >= pDash[dashIndex]) {
+ dist -= pDash[dashIndex];
+ if (++dashIndex == numInDashList)
+ dashIndex = 0;
+ }
+ *pDashIndex = dashIndex;
+ *pDashOffset = dist;
+}
+
+/*
+
+These routines maintain lists of Spans, in order to implement the
+``touch-each-pixel-once'' rules of wide lines and arcs.
+
+Written by Joel McCormack, Summer 1989.
+
+*/
+
+
+static void
+miInitSpanGroup (SpanGroup * spanGroup)
+{
+ spanGroup->size = 0;
+ spanGroup->count = 0;
+ spanGroup->group = NULL;
+ spanGroup->ymin = MAX_COORDINATE;
+ spanGroup->ymax = MIN_COORDINATE;
+} /* InitSpanGroup */
+
+#define YMIN(spans) (spans->points[0].y)
+#define YMAX(spans) (spans->points[spans->count-1].y)
+
+static void
+miSubtractSpans (SpanGroup * spanGroup, Spans * sub)
+{
+ int i, subCount, spansCount;
+ int ymin, ymax, xmin, xmax;
+ Spans *spans;
+ DDXPointPtr subPt, spansPt;
+ int *subWid, *spansWid;
+ int extra;
+
+ ymin = YMIN (sub);
+ ymax = YMAX (sub);
+ spans = spanGroup->group;
+ for (i = spanGroup->count; i; i--, spans++) {
+ if (YMIN (spans) <= ymax && ymin <= YMAX (spans)) {
+ subCount = sub->count;
+ subPt = sub->points;
+ subWid = sub->widths;
+ spansCount = spans->count;
+ spansPt = spans->points;
+ spansWid = spans->widths;
+ extra = 0;
+ for (;;) {
+ while (spansCount && spansPt->y < subPt->y) {
+ spansPt++;
+ spansWid++;
+ spansCount--;
+ }
+ if (!spansCount)
+ break;
+ while (subCount && subPt->y < spansPt->y) {
+ subPt++;
+ subWid++;
+ subCount--;
+ }
+ if (!subCount)
+ break;
+ if (subPt->y == spansPt->y) {
+ xmin = subPt->x;
+ xmax = xmin + *subWid;
+ if (xmin >= spansPt->x + *spansWid || spansPt->x >= xmax) {
+ ;
+ } else if (xmin <= spansPt->x) {
+ if (xmax >= spansPt->x + *spansWid) {
+ memmove (spansPt, spansPt + 1, sizeof *spansPt * (spansCount - 1));
+ memmove (spansWid, spansWid + 1, sizeof *spansWid * (spansCount - 1));
+ spansPt--;
+ spansWid--;
+ spans->count--;
+ extra++;
+ } else {
+ *spansWid = *spansWid - (xmax - spansPt->x);
+ spansPt->x = xmax;
+ }
+ } else {
+ if (xmax >= spansPt->x + *spansWid) {
+ *spansWid = xmin - spansPt->x;
+ } else {
+ if (!extra) {
+ DDXPointPtr newPt;
+ int *newwid;
+
+#define EXTRA 8
+ newPt = xrealloc (spans->points,
+ (spans->count +
+ EXTRA) * sizeof (DDXPointRec));
+ if (!newPt)
+ break;
+ spansPt = newPt + (spansPt - spans->points);
+ spans->points = newPt;
+ newwid = xrealloc (spans->widths,
+ (spans->count + EXTRA) * sizeof (int));
+ if (!newwid)
+ break;
+ spansWid = newwid + (spansWid - spans->widths);
+ spans->widths = newwid;
+ extra = EXTRA;
+ }
+ memmove (spansPt + 1, spansPt, sizeof *spansPt * (spansCount));
+ memmove (spansWid + 1, spansWid, sizeof *spansWid * (spansCount));
+ spans->count++;
+ extra--;
+ *spansWid = xmin - spansPt->x;
+ spansWid++;
+ spansPt++;
+ *spansWid = *spansWid - (xmax - spansPt->x);
+ spansPt->x = xmax;
+ }
+ }
+ }
+ spansPt++;
+ spansWid++;
+ spansCount--;
+ }
+ }
+ }
+}
+
+static void
+miAppendSpans (SpanGroup * spanGroup, SpanGroup * otherGroup, Spans * spans)
+{
+ int ymin, ymax;
+ int spansCount;
+
+ spansCount = spans->count;
+ if (spansCount > 0) {
+ if (spanGroup->size == spanGroup->count) {
+ spanGroup->size = (spanGroup->size + 8) * 2;
+ spanGroup->group =
+ xrealloc (spanGroup->group, sizeof (Spans) * spanGroup->size);
+ }
+
+ spanGroup->group[spanGroup->count] = *spans;
+ (spanGroup->count)++;
+ ymin = spans->points[0].y;
+ if (ymin < spanGroup->ymin)
+ spanGroup->ymin = ymin;
+ ymax = spans->points[spansCount - 1].y;
+ if (ymax > spanGroup->ymax)
+ spanGroup->ymax = ymax;
+ if (otherGroup && otherGroup->ymin < ymax && ymin < otherGroup->ymax) {
+ miSubtractSpans (otherGroup, spans);
+ }
+ } else {
+ xfree (spans->points);
+ xfree (spans->widths);
+ }
+} /* AppendSpans */
+
+static void
+miFreeSpanGroup (SpanGroup * spanGroup)
+{
+ xfree (spanGroup->group);
+}
+
+static void
+QuickSortSpansX (DDXPointRec points[], int widths[], int numSpans)
+{
+ int x;
+ int i, j, m;
+ DDXPointPtr r;
+
+/* Always called with numSpans > 1 */
+/* Sorts only by x, as all y should be the same */
+
+#define ExchangeSpans(a, b) \
+{ \
+ DDXPointRec tpt; \
+ int tw; \
+ \
+ tpt = points[a]; points[a] = points[b]; points[b] = tpt; \
+ tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
+}
+
+ do {
+ if (numSpans < 9) {
+ /* Do insertion sort */
+ int xprev;
+
+ xprev = points[0].x;
+ i = 1;
+ do { /* while i != numSpans */
+ x = points[i].x;
+ if (xprev > x) {
+ /* points[i] is out of order. Move into proper location. */
+ DDXPointRec tpt;
+ int tw, k;
+
+ for (j = 0; x >= points[j].x; j++) {
+ }
+ tpt = points[i];
+ tw = widths[i];
+ for (k = i; k != j; k--) {
+ points[k] = points[k - 1];
+ widths[k] = widths[k - 1];
+ }
+ points[j] = tpt;
+ widths[j] = tw;
+ x = points[i].x;
+ } /* if out of order */
+ xprev = x;
+ i++;
+ } while (i != numSpans);
+ return;
+ }
+
+ /* Choose partition element, stick in location 0 */
+ m = numSpans / 2;
+ if (points[m].x > points[0].x)
+ ExchangeSpans (m, 0);
+ if (points[m].x > points[numSpans - 1].x)
+ ExchangeSpans (m, numSpans - 1);
+ if (points[m].x > points[0].x)
+ ExchangeSpans (m, 0);
+ x = points[0].x;
+
+ /* Partition array */
+ i = 0;
+ j = numSpans;
+ do {
+ r = &(points[i]);
+ do {
+ r++;
+ i++;
+ } while (i != numSpans && r->x < x);
+ r = &(points[j]);
+ do {
+ r--;
+ j--;
+ } while (x < r->x);
+ if (i < j)
+ ExchangeSpans (i, j);
+ } while (i < j);
+
+ /* Move partition element back to middle */
+ ExchangeSpans (0, j);
+
+ /* Recurse */
+ if (numSpans - j - 1 > 1)
+ QuickSortSpansX (&points[j + 1], &widths[j + 1], numSpans - j - 1);
+ numSpans = j;
+ } while (numSpans > 1);
+} /* QuickSortSpans */
+
+
+static int
+UniquifySpansX (Spans * spans, DDXPointRec * newPoints, int *newWidths)
+{
+ int newx1, newx2, oldpt, i, y;
+ DDXPointRec *oldPoints;
+ int *oldWidths;
+ int *startNewWidths;
+
+/* Always called with numSpans > 1 */
+/* Uniquify the spans, and stash them into newPoints and newWidths. Return the
+ number of unique spans. */
+
+
+ startNewWidths = newWidths;
+
+ oldPoints = spans->points;
+ oldWidths = spans->widths;
+
+ y = oldPoints->y;
+ newx1 = oldPoints->x;
+ newx2 = newx1 + *oldWidths;
+
+ for (i = spans->count - 1; i != 0; i--) {
+ oldPoints++;
+ oldWidths++;
+ oldpt = oldPoints->x;
+ if (oldpt > newx2) {
+ /* Write current span, start a new one */
+ newPoints->x = newx1;
+ newPoints->y = y;
+ *newWidths = newx2 - newx1;
+ newPoints++;
+ newWidths++;
+ newx1 = oldpt;
+ newx2 = oldpt + *oldWidths;
+ } else {
+ /* extend current span, if old extends beyond new */
+ oldpt = oldpt + *oldWidths;
+ if (oldpt > newx2)
+ newx2 = oldpt;
+ }
+ } /* for */
+
+ /* Write final span */
+ newPoints->x = newx1;
+ *newWidths = newx2 - newx1;
+ newPoints->y = y;
+
+ return (newWidths - startNewWidths) + 1;
+} /* UniquifySpansX */
+
+static void
+miDisposeSpanGroup (SpanGroup * spanGroup)
+{
+ int i;
+ Spans *spans;
+
+ for (i = 0; i < spanGroup->count; i++) {
+ spans = spanGroup->group + i;
+ xfree (spans->points);
+ xfree (spans->widths);
+ }
+}
+
+static void
+miFillUniqueSpanGroup (GCPtr pGC, SpanGroup * spanGroup, Boolean foreground)
+{
+ int i;
+ Spans *spans;
+ Spans *yspans;
+ int *ysizes;
+ int ymin, ylength;
+
+ /* Outgoing spans for one big call to FillSpans */
+ DDXPointPtr points;
+ int *widths;
+ int count;
+
+ if (spanGroup->count == 0)
+ return;
+
+ if (spanGroup->count == 1) {
+ /* Already should be sorted, unique */
+ spans = spanGroup->group;
+ (*pGC->ops->FillSpans)
+ (pGC, spans->count, spans->points, spans->widths, TRUE, foreground);
+ xfree (spans->points);
+ xfree (spans->widths);
+ } else {
+ /* Yuck. Gross. Radix sort into y buckets, then sort x and uniquify */
+ /* This seems to be the fastest thing to do. I've tried sorting on
+ both x and y at the same time rather than creating into all those
+ y buckets, but it was somewhat slower. */
+
+ ymin = spanGroup->ymin;
+ ylength = spanGroup->ymax - ymin + 1;
+
+ /* Allocate Spans for y buckets */
+ yspans = (Spans*)xalloc (ylength * sizeof (Spans));
+ ysizes = (int *)xalloc (ylength * sizeof (int));
+
+ if (!yspans || !ysizes) {
+ xfree (yspans);
+ xfree (ysizes);
+ miDisposeSpanGroup (spanGroup);
+ return;
+ }
+
+ for (i = 0; i != ylength; i++) {
+ ysizes[i] = 0;
+ yspans[i].count = 0;
+ yspans[i].points = NULL;
+ yspans[i].widths = NULL;
+ }
+
+ /* Go through every single span and put it into the correct bucket */
+ count = 0;
+ for (i = 0, spans = spanGroup->group; i != spanGroup->count; i++, spans++) {
+ int index;
+ int j;
+
+ for (j = 0, points = spans->points, widths = spans->widths;
+ j != spans->count; j++, points++, widths++) {
+ index = points->y - ymin;
+ if (index >= 0 && index < ylength) {
+ Spans *newspans = &(yspans[index]);
+ if (newspans->count == ysizes[index]) {
+ DDXPointPtr newpoints;
+ int *newwidths;
+ ysizes[index] = (ysizes[index] + 8) * 2;
+ newpoints = xrealloc (newspans->points,
+ ysizes[index] * sizeof (DDXPointRec));
+ newwidths = xrealloc (newspans->widths,
+ ysizes[index] * sizeof (int));
+ if (!newpoints || !newwidths) {
+ for (i = 0; i < ylength; i++) {
+ xfree (yspans[i].points);
+ xfree (yspans[i].widths);
+ }
+ xfree (yspans);
+ xfree (ysizes);
+ xfree (newpoints);
+ xfree (newwidths);
+ miDisposeSpanGroup (spanGroup);
+ return;
+ }
+ newspans->points = newpoints;
+ newspans->widths = newwidths;
+ }
+ newspans->points[newspans->count] = *points;
+ newspans->widths[newspans->count] = *widths;
+ (newspans->count)++;
+ } /* if y value of span in range */
+ } /* for j through spans */
+ count += spans->count;
+ xfree (spans->points);
+ spans->points = NULL;
+ xfree (spans->widths);
+ spans->widths = NULL;
+ } /* for i thorough Spans */
+
+ /* Now sort by x and uniquify each bucket into the final array */
+ points = (DDXPointRec*)xalloc (count * sizeof (DDXPointRec));
+ widths = (int *)xalloc (count * sizeof (int));
+ if (!points || !widths) {
+ for (i = 0; i < ylength; i++) {
+ xfree (yspans[i].points);
+ xfree (yspans[i].widths);
+ }
+ xfree (yspans);
+ xfree (ysizes);
+ xfree (points);
+ xfree (widths);
+ return;
+ }
+ count = 0;
+ for (i = 0; i != ylength; i++) {
+ int ycount = yspans[i].count;
+ if (ycount > 0) {
+ if (ycount > 1) {
+ QuickSortSpansX (yspans[i].points, yspans[i].widths, ycount);
+ count += UniquifySpansX (&(yspans[i]), &(points[count]), &(widths[count]));
+ } else {
+ points[count] = yspans[i].points[0];
+ widths[count] = yspans[i].widths[0];
+ count++;
+ }
+ xfree (yspans[i].points);
+ xfree (yspans[i].widths);
+ }
+ }
+
+ (*pGC->ops->FillSpans) (pGC, count, points, widths, TRUE, foreground);
+ xfree (points);
+ xfree (widths);
+ xfree (yspans);
+ xfree (ysizes); /* use (DE)xalloc for these? */
+ }
+
+ spanGroup->count = 0;
+ spanGroup->ymin = MAX_COORDINATE;
+ spanGroup->ymax = MIN_COORDINATE;
+}
+
+/*
+
+The bresenham error equation used in the mi/mfb/cfb line routines is:
+
+ e = error
+ dx = difference in raw X coordinates
+ dy = difference in raw Y coordinates
+ M = # of steps in X direction
+ N = # of steps in Y direction
+ B = 0 to prefer diagonal steps in a given octant,
+ 1 to prefer axial steps in a given octant
+
+ For X major lines:
+ e = 2Mdy - 2Ndx - dx - B
+ -2dx <= e < 0
+
+ For Y major lines:
+ e = 2Ndx - 2Mdy - dy - B
+ -2dy <= e < 0
+
+At the start of the line, we have taken 0 X steps and 0 Y steps,
+so M = 0 and N = 0:
+
+ X major e = 2Mdy - 2Ndx - dx - B
+ = -dx - B
+
+ Y major e = 2Ndx - 2Mdy - dy - B
+ = -dy - B
+
+At the end of the line, we have taken dx X steps and dy Y steps,
+so M = dx and N = dy:
+
+ X major e = 2Mdy - 2Ndx - dx - B
+ = 2dxdy - 2dydx - dx - B
+ = -dx - B
+ Y major e = 2Ndx - 2Mdy - dy - B
+ = 2dydx - 2dxdy - dy - B
+ = -dy - B
+
+Thus, the error term is the same at the start and end of the line.
+
+Let us consider clipping an X coordinate. There are 4 cases which
+represent the two independent cases of clipping the start vs. the
+end of the line and an X major vs. a Y major line. In any of these
+cases, we know the number of X steps (M) and we wish to find the
+number of Y steps (N). Thus, we will solve our error term equation.
+If we are clipping the start of the line, we will find the smallest
+N that satisfies our error term inequality. If we are clipping the
+end of the line, we will find the largest number of Y steps that
+satisfies the inequality. In that case, since we are representing
+the Y steps as (dy - N), we will actually want to solve for the
+smallest N in that equation.
+
+Case 1: X major, starting X coordinate moved by M steps
+
+ -2dx <= 2Mdy - 2Ndx - dx - B < 0
+ 2Ndx <= 2Mdy - dx - B + 2dx 2Ndx > 2Mdy - dx - B
+ 2Ndx <= 2Mdy + dx - B N > (2Mdy - dx - B) / 2dx
+ N <= (2Mdy + dx - B) / 2dx
+
+Since we are trying to find the smallest N that satisfies these
+equations, we should use the > inequality to find the smallest:
+
+ N = floor((2Mdy - dx - B) / 2dx) + 1
+ = floor((2Mdy - dx - B + 2dx) / 2dx)
+ = floor((2Mdy + dx - B) / 2dx)
+
+Case 1b: X major, ending X coordinate moved to M steps
+
+Same derivations as Case 1, but we want the largest N that satisfies
+the equations, so we use the <= inequality:
+
+ N = floor((2Mdy + dx - B) / 2dx)
+
+Case 2: X major, ending X coordinate moved by M steps
+
+ -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
+ -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
+ -2dx <= 2Ndx - 2Mdy - dx - B < 0
+ 2Ndx >= 2Mdy + dx + B - 2dx 2Ndx < 2Mdy + dx + B
+ 2Ndx >= 2Mdy - dx + B N < (2Mdy + dx + B) / 2dx
+ N >= (2Mdy - dx + B) / 2dx
+
+Since we are trying to find the highest number of Y steps that
+satisfies these equations, we need to find the smallest N, so
+we should use the >= inequality to find the smallest:
+
+ N = ceiling((2Mdy - dx + B) / 2dx)
+ = floor((2Mdy - dx + B + 2dx - 1) / 2dx)
+ = floor((2Mdy + dx + B - 1) / 2dx)
+
+Case 2b: X major, starting X coordinate moved to M steps from end
+
+Same derivations as Case 2, but we want the smallest number of Y
+steps, so we want the highest N, so we use the < inequality:
+
+ N = ceiling((2Mdy + dx + B) / 2dx) - 1
+ = floor((2Mdy + dx + B + 2dx - 1) / 2dx) - 1
+ = floor((2Mdy + dx + B + 2dx - 1 - 2dx) / 2dx)
+ = floor((2Mdy + dx + B - 1) / 2dx)
+
+Case 3: Y major, starting X coordinate moved by M steps
+
+ -2dy <= 2Ndx - 2Mdy - dy - B < 0
+ 2Ndx >= 2Mdy + dy + B - 2dy 2Ndx < 2Mdy + dy + B
+ 2Ndx >= 2Mdy - dy + B N < (2Mdy + dy + B) / 2dx
+ N >= (2Mdy - dy + B) / 2dx
+
+Since we are trying to find the smallest N that satisfies these
+equations, we should use the >= inequality to find the smallest:
+
+ N = ceiling((2Mdy - dy + B) / 2dx)
+ = floor((2Mdy - dy + B + 2dx - 1) / 2dx)
+ = floor((2Mdy - dy + B - 1) / 2dx) + 1
+
+Case 3b: Y major, ending X coordinate moved to M steps
+
+Same derivations as Case 3, but we want the largest N that satisfies
+the equations, so we use the < inequality:
+
+ N = ceiling((2Mdy + dy + B) / 2dx) - 1
+ = floor((2Mdy + dy + B + 2dx - 1) / 2dx) - 1
+ = floor((2Mdy + dy + B + 2dx - 1 - 2dx) / 2dx)
+ = floor((2Mdy + dy + B - 1) / 2dx)
+
+Case 4: Y major, ending X coordinate moved by M steps
+
+ -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
+ -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
+ -2dy <= 2Mdy - 2Ndx - dy - B < 0
+ 2Ndx <= 2Mdy - dy - B + 2dy 2Ndx > 2Mdy - dy - B
+ 2Ndx <= 2Mdy + dy - B N > (2Mdy - dy - B) / 2dx
+ N <= (2Mdy + dy - B) / 2dx
+
+Since we are trying to find the highest number of Y steps that
+satisfies these equations, we need to find the smallest N, so
+we should use the > inequality to find the smallest:
+
+ N = floor((2Mdy - dy - B) / 2dx) + 1
+
+Case 4b: Y major, starting X coordinate moved to M steps from end
+
+Same analysis as Case 4, but we want the smallest number of Y steps
+which means the largest N, so we use the <= inequality:
+
+ N = floor((2Mdy + dy - B) / 2dx)
+
+Now let's try the Y coordinates, we have the same 4 cases.
+
+Case 5: X major, starting Y coordinate moved by N steps
+
+ -2dx <= 2Mdy - 2Ndx - dx - B < 0
+ 2Mdy >= 2Ndx + dx + B - 2dx 2Mdy < 2Ndx + dx + B
+ 2Mdy >= 2Ndx - dx + B M < (2Ndx + dx + B) / 2dy
+ M >= (2Ndx - dx + B) / 2dy
+
+Since we are trying to find the smallest M, we use the >= inequality:
+
+ M = ceiling((2Ndx - dx + B) / 2dy)
+ = floor((2Ndx - dx + B + 2dy - 1) / 2dy)
+ = floor((2Ndx - dx + B - 1) / 2dy) + 1
+
+Case 5b: X major, ending Y coordinate moved to N steps
+
+Same derivations as Case 5, but we want the largest M that satisfies
+the equations, so we use the < inequality:
+
+ M = ceiling((2Ndx + dx + B) / 2dy) - 1
+ = floor((2Ndx + dx + B + 2dy - 1) / 2dy) - 1
+ = floor((2Ndx + dx + B + 2dy - 1 - 2dy) / 2dy)
+ = floor((2Ndx + dx + B - 1) / 2dy)
+
+Case 6: X major, ending Y coordinate moved by N steps
+
+ -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
+ -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
+ -2dx <= 2Ndx - 2Mdy - dx - B < 0
+ 2Mdy <= 2Ndx - dx - B + 2dx 2Mdy > 2Ndx - dx - B
+ 2Mdy <= 2Ndx + dx - B M > (2Ndx - dx - B) / 2dy
+ M <= (2Ndx + dx - B) / 2dy
+
+Largest # of X steps means smallest M, so use the > inequality:
+
+ M = floor((2Ndx - dx - B) / 2dy) + 1
+
+Case 6b: X major, starting Y coordinate moved to N steps from end
+
+Same derivations as Case 6, but we want the smallest # of X steps
+which means the largest M, so use the <= inequality:
+
+ M = floor((2Ndx + dx - B) / 2dy)
+
+Case 7: Y major, starting Y coordinate moved by N steps
+
+ -2dy <= 2Ndx - 2Mdy - dy - B < 0
+ 2Mdy <= 2Ndx - dy - B + 2dy 2Mdy > 2Ndx - dy - B
+ 2Mdy <= 2Ndx + dy - B M > (2Ndx - dy - B) / 2dy
+ M <= (2Ndx + dy - B) / 2dy
+
+To find the smallest M, use the > inequality:
+
+ M = floor((2Ndx - dy - B) / 2dy) + 1
+ = floor((2Ndx - dy - B + 2dy) / 2dy)
+ = floor((2Ndx + dy - B) / 2dy)
+
+Case 7b: Y major, ending Y coordinate moved to N steps
+
+Same derivations as Case 7, but we want the largest M that satisfies
+the equations, so use the <= inequality:
+
+ M = floor((2Ndx + dy - B) / 2dy)
+
+Case 8: Y major, ending Y coordinate moved by N steps
+
+ -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
+ -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
+ -2dy <= 2Mdy - 2Ndx - dy - B < 0
+ 2Mdy >= 2Ndx + dy + B - 2dy 2Mdy < 2Ndx + dy + B
+ 2Mdy >= 2Ndx - dy + B M < (2Ndx + dy + B) / 2dy
+ M >= (2Ndx - dy + B) / 2dy
+
+To find the highest X steps, find the smallest M, use the >= inequality:
+
+ M = ceiling((2Ndx - dy + B) / 2dy)
+ = floor((2Ndx - dy + B + 2dy - 1) / 2dy)
+ = floor((2Ndx + dy + B - 1) / 2dy)
+
+Case 8b: Y major, starting Y coordinate moved to N steps from the end
+
+Same derivations as Case 8, but we want to find the smallest # of X
+steps which means the largest M, so we use the < inequality:
+
+ M = ceiling((2Ndx + dy + B) / 2dy) - 1
+ = floor((2Ndx + dy + B + 2dy - 1) / 2dy) - 1
+ = floor((2Ndx + dy + B + 2dy - 1 - 2dy) / 2dy)
+ = floor((2Ndx + dy + B - 1) / 2dy)
+
+So, our equations are:
+
+ 1: X major move x1 to x1+M floor((2Mdy + dx - B) / 2dx)
+ 1b: X major move x2 to x1+M floor((2Mdy + dx - B) / 2dx)
+ 2: X major move x2 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
+ 2b: X major move x1 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
+
+ 3: Y major move x1 to x1+M floor((2Mdy - dy + B - 1) / 2dx) + 1
+ 3b: Y major move x2 to x1+M floor((2Mdy + dy + B - 1) / 2dx)
+ 4: Y major move x2 to x2-M floor((2Mdy - dy - B) / 2dx) + 1
+ 4b: Y major move x1 to x2-M floor((2Mdy + dy - B) / 2dx)
+
+ 5: X major move y1 to y1+N floor((2Ndx - dx + B - 1) / 2dy) + 1
+ 5b: X major move y2 to y1+N floor((2Ndx + dx + B - 1) / 2dy)
+ 6: X major move y2 to y2-N floor((2Ndx - dx - B) / 2dy) + 1
+ 6b: X major move y1 to y2-N floor((2Ndx + dx - B) / 2dy)
+
+ 7: Y major move y1 to y1+N floor((2Ndx + dy - B) / 2dy)
+ 7b: Y major move y2 to y1+N floor((2Ndx + dy - B) / 2dy)
+ 8: Y major move y2 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
+ 8b: Y major move y1 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
+
+We have the following constraints on all of the above terms:
+
+ 0 < M,N <= 2^15 2^15 can be imposed by miZeroClipLine
+ 0 <= dx/dy <= 2^16 - 1
+ 0 <= B <= 1
+
+The floor in all of the above equations can be accomplished with a
+simple C divide operation provided that both numerator and denominator
+are positive.
+
+Since dx,dy >= 0 and since moving an X coordinate implies that dx != 0
+and moving a Y coordinate implies dy != 0, we know that the denominators
+are all > 0.
+
+For all lines, (-B) and (B-1) are both either 0 or -1, depending on the
+bias. Thus, we have to show that the 2MNdxy +/- dxy terms are all >= 1
+or > 0 to prove that the numerators are positive (or zero).
+
+For X Major lines we know that dx > 0 and since 2Mdy is >= 0 due to the
+constraints, the first four equations all have numerators >= 0.
+
+For the second four equations, M > 0, so 2Mdy >= 2dy so (2Mdy - dy) >= dy
+So (2Mdy - dy) > 0, since they are Y major lines. Also, (2Mdy + dy) >= 3dy
+or (2Mdy + dy) > 0. So all of their numerators are >= 0.
+
+For the third set of four equations, N > 0, so 2Ndx >= 2dx so (2Ndx - dx)
+>= dx > 0. Similarly (2Ndx + dx) >= 3dx > 0. So all numerators >= 0.
+
+For the fourth set of equations, dy > 0 and 2Ndx >= 0, so all numerators
+are > 0.
+
+To consider overflow, consider the case of 2 * M,N * dx,dy + dx,dy. This
+is bounded <= 2 * 2^15 * (2^16 - 1) + (2^16 - 1)
+ <= 2^16 * (2^16 - 1) + (2^16 - 1)
+ <= 2^32 - 2^16 + 2^16 - 1
+ <= 2^32 - 1
+Since the (-B) and (B-1) terms are all 0 or -1, the maximum value of
+the numerator is therefore (2^32 - 1), which does not overflow an unsigned
+32 bit variable.
+
+*/
+
+/* Bit codes for the terms of the 16 clipping equations defined below. */
+
+#define T_2NDX (1 << 0)
+#define T_2MDY (0) /* implicit term */
+#define T_DXNOTY (1 << 1)
+#define T_DYNOTX (0) /* implicit term */
+#define T_SUBDXORY (1 << 2)
+#define T_ADDDX (T_DXNOTY) /* composite term */
+#define T_SUBDX (T_DXNOTY | T_SUBDXORY) /* composite term */
+#define T_ADDDY (T_DYNOTX) /* composite term */
+#define T_SUBDY (T_DYNOTX | T_SUBDXORY) /* composite term */
+#define T_BIASSUBONE (1 << 3)
+#define T_SUBBIAS (0) /* implicit term */
+#define T_DIV2DX (1 << 4)
+#define T_DIV2DY (0) /* implicit term */
+#define T_ADDONE (1 << 5)
+
+/* Bit masks defining the 16 equations used in miZeroClipLine. */
+
+#define EQN1 (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
+#define EQN1B (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
+#define EQN2 (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
+#define EQN2B (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
+
+#define EQN3 (T_2MDY | T_SUBDY | T_BIASSUBONE | T_DIV2DX | T_ADDONE)
+#define EQN3B (T_2MDY | T_ADDDY | T_BIASSUBONE | T_DIV2DX)
+#define EQN4 (T_2MDY | T_SUBDY | T_SUBBIAS | T_DIV2DX | T_ADDONE)
+#define EQN4B (T_2MDY | T_ADDDY | T_SUBBIAS | T_DIV2DX)
+
+#define EQN5 (T_2NDX | T_SUBDX | T_BIASSUBONE | T_DIV2DY | T_ADDONE)
+#define EQN5B (T_2NDX | T_ADDDX | T_BIASSUBONE | T_DIV2DY)
+#define EQN6 (T_2NDX | T_SUBDX | T_SUBBIAS | T_DIV2DY | T_ADDONE)
+#define EQN6B (T_2NDX | T_ADDDX | T_SUBBIAS | T_DIV2DY)
+
+#define EQN7 (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
+#define EQN7B (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
+#define EQN8 (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
+#define EQN8B (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
+
+/* miZeroClipLine
+ *
+ * returns: 1 for partially clipped line
+ * -1 for completely clipped line
+ *
+ */
+static int
+miZeroClipLine (int xmin, int ymin, int xmax, int ymax,
+ int *new_x1, int *new_y1, int *new_x2, int *new_y2,
+ unsigned int adx, unsigned int ady,
+ int *pt1_clipped, int *pt2_clipped, int octant, unsigned int bias, int oc1, int oc2)
+{
+ int swapped = 0;
+ int clipDone = 0;
+ CARD32 utmp = 0;
+ int clip1, clip2;
+ int x1, y1, x2, y2;
+ int x1_orig, y1_orig, x2_orig, y2_orig;
+ int xmajor;
+ int negslope = 0, anchorval = 0;
+ unsigned int eqn = 0;
+
+ x1 = x1_orig = *new_x1;
+ y1 = y1_orig = *new_y1;
+ x2 = x2_orig = *new_x2;
+ y2 = y2_orig = *new_y2;
+
+ clip1 = 0;
+ clip2 = 0;
+
+ xmajor = IsXMajorOctant (octant);
+ bias = ((bias >> octant) & 1);
+
+ while (1) {
+ if ((oc1 & oc2) != 0) { /* trivial reject */
+ clipDone = -1;
+ clip1 = oc1;
+ clip2 = oc2;
+ break;
+ } else if ((oc1 | oc2) == 0) { /* trivial accept */
+ clipDone = 1;
+ if (swapped) {
+ SWAPINT_PAIR (x1, y1, x2, y2);
+ SWAPINT (clip1, clip2);
+ }
+ break;
+ } else { /* have to clip */
+
+ /* only clip one point at a time */
+ if (oc1 == 0) {
+ SWAPINT_PAIR (x1, y1, x2, y2);
+ SWAPINT_PAIR (x1_orig, y1_orig, x2_orig, y2_orig);
+ SWAPINT (oc1, oc2);
+ SWAPINT (clip1, clip2);
+ swapped = !swapped;
+ }
+
+ clip1 |= oc1;
+ if (oc1 & OUT_LEFT) {
+ negslope = IsYDecreasingOctant (octant);
+ utmp = xmin - x1_orig;
+ if (utmp <= 32767) { /* clip based on near endpt */
+ if (xmajor)
+ eqn = (swapped) ? EQN2 : EQN1;
+ else
+ eqn = (swapped) ? EQN4 : EQN3;
+ anchorval = y1_orig;
+ } else { /* clip based on far endpt */
+
+ utmp = x2_orig - xmin;
+ if (xmajor)
+ eqn = (swapped) ? EQN1B : EQN2B;
+ else
+ eqn = (swapped) ? EQN3B : EQN4B;
+ anchorval = y2_orig;
+ negslope = !negslope;
+ }
+ x1 = xmin;
+ } else if (oc1 & OUT_ABOVE) {
+ negslope = IsXDecreasingOctant (octant);
+ utmp = ymin - y1_orig;
+ if (utmp <= 32767) { /* clip based on near endpt */
+ if (xmajor)
+ eqn = (swapped) ? EQN6 : EQN5;
+ else
+ eqn = (swapped) ? EQN8 : EQN7;
+ anchorval = x1_orig;
+ } else { /* clip based on far endpt */
+
+ utmp = y2_orig - ymin;
+ if (xmajor)
+ eqn = (swapped) ? EQN5B : EQN6B;
+ else
+ eqn = (swapped) ? EQN7B : EQN8B;
+ anchorval = x2_orig;
+ negslope = !negslope;
+ }
+ y1 = ymin;
+ } else if (oc1 & OUT_RIGHT) {
+ negslope = IsYDecreasingOctant (octant);
+ utmp = x1_orig - xmax;
+ if (utmp <= 32767) { /* clip based on near endpt */
+ if (xmajor)
+ eqn = (swapped) ? EQN2 : EQN1;
+ else
+ eqn = (swapped) ? EQN4 : EQN3;
+ anchorval = y1_orig;
+ } else { /* clip based on far endpt */
+
+ /*
+ * Technically since the equations can handle
+ * utmp == 32768, this overflow code isn't
+ * needed since X11 protocol can't generate
+ * a line which goes more than 32768 pixels
+ * to the right of a clip rectangle.
+ */
+ utmp = xmax - x2_orig;
+ if (xmajor)
+ eqn = (swapped) ? EQN1B : EQN2B;
+ else
+ eqn = (swapped) ? EQN3B : EQN4B;
+ anchorval = y2_orig;
+ negslope = !negslope;
+ }
+ x1 = xmax;
+ } else if (oc1 & OUT_BELOW) {
+ negslope = IsXDecreasingOctant (octant);
+ utmp = y1_orig - ymax;
+ if (utmp <= 32767) { /* clip based on near endpt */
+ if (xmajor)
+ eqn = (swapped) ? EQN6 : EQN5;
+ else
+ eqn = (swapped) ? EQN8 : EQN7;
+ anchorval = x1_orig;
+ } else { /* clip based on far endpt */
+
+ /*
+ * Technically since the equations can handle
+ * utmp == 32768, this overflow code isn't
+ * needed since X11 protocol can't generate
+ * a line which goes more than 32768 pixels
+ * below the bottom of a clip rectangle.
+ */
+ utmp = ymax - y2_orig;
+ if (xmajor)
+ eqn = (swapped) ? EQN5B : EQN6B;
+ else
+ eqn = (swapped) ? EQN7B : EQN8B;
+ anchorval = x2_orig;
+ negslope = !negslope;
+ }
+ y1 = ymax;
+ }
+
+ if (swapped)
+ negslope = !negslope;
+
+ utmp <<= 1; /* utmp = 2N or 2M */
+ if (eqn & T_2NDX)
+ utmp = (utmp * adx);
+ else /* (eqn & T_2MDY) */
+ utmp = (utmp * ady);
+ if (eqn & T_DXNOTY)
+ if (eqn & T_SUBDXORY)
+ utmp -= adx;
+ else
+ utmp += adx;
+ else /* (eqn & T_DYNOTX) */ if (eqn & T_SUBDXORY)
+ utmp -= ady;
+ else
+ utmp += ady;
+ if (eqn & T_BIASSUBONE)
+ utmp += bias - 1;
+ else /* (eqn & T_SUBBIAS) */
+ utmp -= bias;
+ if (eqn & T_DIV2DX)
+ utmp /= (adx << 1);
+ else /* (eqn & T_DIV2DY) */
+ utmp /= (ady << 1);
+ if (eqn & T_ADDONE)
+ utmp++;
+
+ if (negslope)
+ utmp = (uint32_t)(-(int32_t)utmp);
+
+ if (eqn & T_2NDX) /* We are calculating X steps */
+ x1 = anchorval + utmp;
+ else /* else, Y steps */
+ y1 = anchorval + utmp;
+
+ oc1 = 0;
+ MIOUTCODES (oc1, x1, y1, xmin, ymin, xmax, ymax);
+ }
+ }
+
+ *new_x1 = x1;
+ *new_y1 = y1;
+ *new_x2 = x2;
+ *new_y2 = y2;
+
+ *pt1_clipped = clip1;
+ *pt2_clipped = clip2;
+
+ return clipDone;
+}
+
+/* Draw lineSolid, fillStyle-independent zero width lines.
+ *
+ * Must keep X and Y coordinates in "ints" at least until after they're
+ * translated and clipped to accomodate CoordModePrevious lines with very
+ * large coordinates.
+ *
+ * Draws the same pixels regardless of sign(dx) or sign(dy).
+ *
+ * Ken Whaley
+ *
+ */
+
+#define MI_OUTPUT_POINT(xx, yy)\
+{\
+ if ( !new_span && yy == current_y)\
+ {\
+ if (xx < spans->x)\
+ spans->x = xx;\
+ ++*widths;\
+ }\
+ else\
+ {\
+ ++Nspans;\
+ ++spans;\
+ ++widths;\
+ spans->x = xx;\
+ spans->y = yy;\
+ *widths = 1;\
+ current_y = yy;\
+ new_span = FALSE;\
+ }\
+}
+
+void
+miZeroLine (GCPtr pGC, int mode, /* Origin or Previous */
+ int npt, /* number of points */
+ DDXPointPtr pptInit)
+{
+ int Nspans, current_y = 0;
+ DDXPointPtr ppt;
+ DDXPointPtr pspanInit, spans;
+ int *pwidthInit, *widths, list_len;
+ int xleft, ytop, xright, ybottom;
+ int new_x1, new_y1, new_x2, new_y2;
+ int x = 0, y = 0, x1, y1, x2, y2, xstart, ystart;
+ int oc1, oc2;
+ int result;
+ int pt1_clipped, pt2_clipped = 0;
+ Boolean new_span;
+ int signdx, signdy;
+ int clipdx, clipdy;
+ int width, height;
+ int adx, ady;
+ int octant;
+ unsigned int bias = miGetZeroLineBias (screen);
+ int e, e1, e2, e3; /* Bresenham error terms */
+ int length; /* length of lines == # of pixels on major axis */
+
+ xleft = 0;
+ ytop = 0;
+ xright = pGC->width - 1;
+ ybottom = pGC->height - 1;
+
+ /* it doesn't matter whether we're in drawable or screen coordinates,
+ * FillSpans simply cannot take starting coordinates outside of the
+ * range of a DDXPointRec component.
+ */
+ if (xright > MAX_COORDINATE)
+ xright = MAX_COORDINATE;
+ if (ybottom > MAX_COORDINATE)
+ ybottom = MAX_COORDINATE;
+
+ /* since we're clipping to the drawable's boundaries & coordinate
+ * space boundaries, we're guaranteed that the larger of width/height
+ * is the longest span we'll need to output
+ */
+ width = xright - xleft + 1;
+ height = ybottom - ytop + 1;
+ list_len = (height >= width) ? height : width;
+ pspanInit = (DDXPointRec *)xalloc (list_len * sizeof (DDXPointRec));
+ pwidthInit = (int *)xalloc (list_len * sizeof (int));
+ if (!pspanInit || !pwidthInit)
+ goto out;
+
+ Nspans = 0;
+ new_span = TRUE;
+ spans = pspanInit - 1;
+ widths = pwidthInit - 1;
+ ppt = pptInit;
+
+ xstart = ppt->x;
+ ystart = ppt->y;
+
+ /* x2, y2, oc2 copied to x1, y1, oc1 at top of loop to simplify
+ * iteration logic
+ */
+ x2 = xstart;
+ y2 = ystart;
+ oc2 = 0;
+ MIOUTCODES (oc2, x2, y2, xleft, ytop, xright, ybottom);
+
+ while (--npt > 0) {
+ if (Nspans > 0)
+ (*pGC->ops->FillSpans) (pGC, Nspans, pspanInit, pwidthInit, FALSE, TRUE);
+ Nspans = 0;
+ new_span = TRUE;
+ spans = pspanInit - 1;
+ widths = pwidthInit - 1;
+
+ x1 = x2;
+ y1 = y2;
+ oc1 = oc2;
+ ++ppt;
+
+ x2 = ppt->x;
+ y2 = ppt->y;
+ if (mode == CoordModePrevious) {
+ x2 += x1;
+ y2 += y1;
+ }
+
+ oc2 = 0;
+ MIOUTCODES (oc2, x2, y2, xleft, ytop, xright, ybottom);
+
+ CalcLineDeltas (x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
+
+ if (adx > ady) {
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ length = adx; /* don't draw endpoint in main loop */
+
+ FIXUP_ERROR (e, octant, bias);
+
+ new_x1 = x1;
+ new_y1 = y1;
+ new_x2 = x2;
+ new_y2 = y2;
+ pt1_clipped = 0;
+ pt2_clipped = 0;
+
+ if ((oc1 | oc2) != 0) {
+ result = miZeroClipLine (xleft, ytop, xright, ybottom,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady,
+ &pt1_clipped, &pt2_clipped, octant, bias, oc1, oc2);
+ if (result == -1)
+ continue;
+
+ length = abs (new_x2 - new_x1);
+
+ /* if we've clipped the endpoint, always draw the full length
+ * of the segment, because then the capstyle doesn't matter
+ */
+ if (pt2_clipped)
+ length++;
+
+ if (pt1_clipped) {
+ /* must calculate new error terms */
+ clipdx = abs (new_x1 - x1);
+ clipdy = abs (new_y1 - y1);
+ e += (clipdy * e2) + ((clipdx - clipdy) * e1);
+ }
+ }
+
+ /* draw the segment */
+
+ x = new_x1;
+ y = new_y1;
+
+ e3 = e2 - e1;
+ e = e - e1;
+
+ while (length--) {
+ MI_OUTPUT_POINT (x, y);
+ e += e1;
+ if (e >= 0) {
+ y += signdy;
+ e += e3;
+ }
+ x += signdx;
+ }
+ } else { /* Y major line */
+
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ length = ady; /* don't draw endpoint in main loop */
+
+ SetYMajorOctant (octant);
+ FIXUP_ERROR (e, octant, bias);
+
+ new_x1 = x1;
+ new_y1 = y1;
+ new_x2 = x2;
+ new_y2 = y2;
+ pt1_clipped = 0;
+ pt2_clipped = 0;
+
+ if ((oc1 | oc2) != 0) {
+ result = miZeroClipLine (xleft, ytop, xright, ybottom,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady,
+ &pt1_clipped, &pt2_clipped, octant, bias, oc1, oc2);
+ if (result == -1)
+ continue;
+
+ length = abs (new_y2 - new_y1);
+
+ /* if we've clipped the endpoint, always draw the full length
+ * of the segment, because then the capstyle doesn't matter
+ */
+ if (pt2_clipped)
+ length++;
+
+ if (pt1_clipped) {
+ /* must calculate new error terms */
+ clipdx = abs (new_x1 - x1);
+ clipdy = abs (new_y1 - y1);
+ e += (clipdx * e2) + ((clipdy - clipdx) * e1);
+ }
+ }
+
+ /* draw the segment */
+
+ x = new_x1;
+ y = new_y1;
+
+ e3 = e2 - e1;
+ e = e - e1;
+
+ while (length--) {
+ MI_OUTPUT_POINT (x, y);
+ e += e1;
+ if (e >= 0) {
+ x += signdx;
+ e += e3;
+ }
+ y += signdy;
+ }
+ }
+ }
+
+ /* only do the capnotlast check on the last segment
+ * and only if the endpoint wasn't clipped. And then, if the last
+ * point is the same as the first point, do not draw it, unless the
+ * line is degenerate
+ */
+ if ((!pt2_clipped) && (pGC->capStyle != CapNotLast) &&
+ (((xstart != x2) || (ystart != y2)) || (ppt == pptInit + 1))) {
+ MI_OUTPUT_POINT (x, y);
+ }
+
+ if (Nspans > 0)
+ (*pGC->ops->FillSpans) (pGC, Nspans, pspanInit, pwidthInit, FALSE, TRUE);
+
+out:
+ xfree (pwidthInit);
+ xfree (pspanInit);
+}
+
+void
+miZeroDashLine (GCPtr pgc, int mode, int nptInit, /* number of points in polyline */
+ DDXPointRec * pptInit /* points in the polyline */
+ )
+{
+ /* XXX kludge until real zero-width dash code is written */
+ pgc->lineWidth = 1;
+ miWideDash (pgc, mode, nptInit, pptInit);
+ pgc->lineWidth = 0;
+}
+
+static void miLineArc (GCPtr pGC,
+ Boolean foreground, SpanDataPtr spanData,
+ LineFacePtr leftFace,
+ LineFacePtr rightFace, double xorg, double yorg, Boolean isInt);
+
+
+/*
+ * spans-based polygon filler
+ */
+
+static void
+miFillPolyHelper (GCPtr pGC, Boolean foreground,
+ SpanDataPtr spanData, int y, int overall_height,
+ PolyEdgePtr left, PolyEdgePtr right, int left_count, int right_count)
+{
+ int left_x = 0, left_e = 0;
+ int left_stepx = 0;
+ int left_signdx = 0;
+ int left_dy = 0, left_dx = 0;
+
+ int right_x = 0, right_e = 0;
+ int right_stepx = 0;
+ int right_signdx = 0;
+ int right_dy = 0, right_dx = 0;
+
+ int height = 0;
+ int left_height = 0, right_height = 0;
+
+ DDXPointPtr ppt;
+ DDXPointPtr pptInit = NULL;
+ int *pwidth;
+ int *pwidthInit = NULL;
+ int xorg;
+ Spans spanRec;
+
+ left_height = 0;
+ right_height = 0;
+
+ if (!spanData) {
+ pptInit = (DDXPointRec *)xalloc (overall_height * sizeof (*ppt));
+ if (!pptInit)
+ return;
+ pwidthInit = (int *)xalloc (overall_height * sizeof (*pwidth));
+ if (!pwidthInit) {
+ xfree (pptInit);
+ return;
+ }
+ ppt = pptInit;
+ pwidth = pwidthInit;
+ } else {
+ spanRec.points = (DDXPointRec *)xalloc (overall_height * sizeof (*ppt));
+ if (!spanRec.points)
+ return;
+ spanRec.widths = (int *)xalloc (overall_height * sizeof (int));
+ if (!spanRec.widths) {
+ xfree (spanRec.points);
+ return;
+ }
+ ppt = spanRec.points;
+ pwidth = spanRec.widths;
+ }
+
+ xorg = 0;
+ while ((left_count || left_height) && (right_count || right_height)) {
+ MIPOLYRELOADLEFT MIPOLYRELOADRIGHT height = left_height;
+ if (height > right_height)
+ height = right_height;
+
+ left_height -= height;
+ right_height -= height;
+
+ while (--height >= 0) {
+ if (right_x >= left_x) {
+ ppt->y = y;
+ ppt->x = left_x + xorg;
+ ppt++;
+ *pwidth++ = right_x - left_x + 1;
+ }
+ y++;
+
+ MIPOLYSTEPLEFT MIPOLYSTEPRIGHT}
+ }
+ if (!spanData) {
+ (*pGC->ops->FillSpans) (pGC, ppt - pptInit, pptInit, pwidthInit, TRUE, foreground);
+ xfree (pwidthInit);
+ xfree (pptInit);
+ } else {
+ spanRec.count = ppt - spanRec.points;
+ AppendSpanGroup (pGC, foreground, &spanRec, spanData)
+ }
+}
+
+static void
+miFillRectPolyHelper (GCPtr pGC, Boolean foreground, SpanDataPtr spanData, int x, int y, int w, int h)
+{
+ DDXPointPtr ppt;
+ int *pwidth;
+ Spans spanRec;
+ xRectangle rect;
+
+ if (!spanData) {
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ (*pGC->ops->FillRects) (pGC, 1, &rect, foreground);
+ } else {
+ spanRec.points = (DDXPointRec *)xalloc (h * sizeof (*ppt));
+ if (!spanRec.points)
+ return;
+ spanRec.widths = (int *)xalloc (h * sizeof (int));
+ if (!spanRec.widths) {
+ xfree (spanRec.points);
+ return;
+ }
+ ppt = spanRec.points;
+ pwidth = spanRec.widths;
+
+ while (h--) {
+ ppt->x = x;
+ ppt->y = y;
+ ppt++;
+ *pwidth++ = w;
+ y++;
+ }
+ spanRec.count = ppt - spanRec.points;
+ AppendSpanGroup (pGC, foreground, &spanRec, spanData)
+ }
+}
+
+static int
+miPolyBuildEdge (SPICE_GNUC_UNUSED double x0, double y0, double k, /* x0 * dy - y0 * dx */
+ int dx, int dy, int xi, int yi, int left, PolyEdgePtr edge)
+{
+ int x, y, e;
+ int xady;
+
+ if (dy < 0) {
+ dy = -dy;
+ dx = -dx;
+ k = -k;
+ }
+ y = ICEIL (y0);
+ xady = ICEIL (k) + y * dx;
+
+ if (xady <= 0)
+ x = -(-xady / dy) - 1;
+ else
+ x = (xady - 1) / dy;
+
+ e = xady - x * dy;
+
+ if (dx >= 0) {
+ edge->signdx = 1;
+ edge->stepx = dx / dy;
+ edge->dx = dx % dy;
+ } else {
+ edge->signdx = -1;
+ edge->stepx = -(-dx / dy);
+ edge->dx = -dx % dy;
+ e = dy - e + 1;
+ }
+ edge->dy = dy;
+ edge->x = x + left + xi;
+ edge->e = e - dy; /* bias to compare against 0 instead of dy */
+ return y + yi;
+}
+
+#define StepAround(v, incr, max) (((v) + (incr) < 0) ? (max - 1) : ((v) + (incr) == max) ? 0 : ((v) + (incr)))
+
+static int
+miPolyBuildPoly (PolyVertexPtr vertices,
+ PolySlopePtr slopes,
+ int count,
+ int xi,
+ int yi, PolyEdgePtr left, PolyEdgePtr right, int *pnleft, int *pnright, int *h)
+{
+ int top, bottom;
+ double miny, maxy;
+ int i;
+ int j;
+ int clockwise;
+ int slopeoff;
+ int s;
+ int nright, nleft;
+ int y, lasty = 0, bottomy, topy = 0;
+
+ /* find the top of the polygon */
+ maxy = miny = vertices[0].y;
+ bottom = top = 0;
+ for (i = 1; i < count; i++) {
+ if (vertices[i].y < miny) {
+ top = i;
+ miny = vertices[i].y;
+ }
+ if (vertices[i].y >= maxy) {
+ bottom = i;
+ maxy = vertices[i].y;
+ }
+ }
+ clockwise = 1;
+ slopeoff = 0;
+
+ i = top;
+ j = StepAround (top, -1, count);
+
+ if (slopes[j].dy * slopes[i].dx > slopes[i].dy * slopes[j].dx) {
+ clockwise = -1;
+ slopeoff = -1;
+ }
+
+ bottomy = ICEIL (maxy) + yi;
+
+ nright = 0;
+
+ s = StepAround (top, slopeoff, count);
+ i = top;
+ while (i != bottom) {
+ if (slopes[s].dy != 0) {
+ y = miPolyBuildEdge (vertices[i].x, vertices[i].y,
+ slopes[s].k,
+ slopes[s].dx, slopes[s].dy, xi, yi, 0, &right[nright]);
+ if (nright != 0)
+ right[nright - 1].height = y - lasty;
+ else
+ topy = y;
+ nright++;
+ lasty = y;
+ }
+
+ i = StepAround (i, clockwise, count);
+ s = StepAround (s, clockwise, count);
+ }
+ if (nright != 0)
+ right[nright - 1].height = bottomy - lasty;
+
+ if (slopeoff == 0)
+ slopeoff = -1;
+ else
+ slopeoff = 0;
+
+ nleft = 0;
+ s = StepAround (top, slopeoff, count);
+ i = top;
+ while (i != bottom) {
+ if (slopes[s].dy != 0) {
+ y = miPolyBuildEdge (vertices[i].x, vertices[i].y,
+ slopes[s].k, slopes[s].dx, slopes[s].dy, xi, yi, 1, &left[nleft]);
+
+ if (nleft != 0)
+ left[nleft - 1].height = y - lasty;
+ nleft++;
+ lasty = y;
+ }
+ i = StepAround (i, -clockwise, count);
+ s = StepAround (s, -clockwise, count);
+ }
+ if (nleft != 0)
+ left[nleft - 1].height = bottomy - lasty;
+ *pnleft = nleft;
+ *pnright = nright;
+ *h = bottomy - topy;
+ return topy;
+}
+
+static void
+miLineOnePoint (GCPtr pGC,
+ Boolean foreground,
+ SPICE_GNUC_UNUSED SpanDataPtr spanData,
+ int x,
+ int y)
+{
+ DDXPointRec pt;
+ int wid;
+
+ wid = 1;
+ pt.x = x;
+ pt.y = y;
+ (*pGC->ops->FillSpans) (pGC, 1, &pt, &wid, TRUE, foreground);
+}
+
+static void
+miLineJoin (GCPtr pGC, Boolean foreground, SpanDataPtr spanData, LineFacePtr pLeft, LineFacePtr pRight)
+{
+ double mx = 0, my = 0;
+ double denom = 0.0;
+ PolyVertexRec vertices[4];
+ PolySlopeRec slopes[4];
+ int edgecount;
+ PolyEdgeRec left[4], right[4];
+ int nleft, nright;
+ int y, height;
+ int swapslopes;
+ int joinStyle = pGC->joinStyle;
+ int lw = pGC->lineWidth;
+
+ if (lw == 1 && !spanData) {
+ /* See if one of the lines will draw the joining pixel */
+ if (pLeft->dx > 0 || (pLeft->dx == 0 && pLeft->dy > 0))
+ return;
+ if (pRight->dx > 0 || (pRight->dx == 0 && pRight->dy > 0))
+ return;
+ if (joinStyle != JoinRound) {
+ denom = -pLeft->dx * (double) pRight->dy + pRight->dx * (double) pLeft->dy;
+ if (denom == 0)
+ return; /* no join to draw */
+ }
+ if (joinStyle != JoinMiter) {
+ miLineOnePoint (pGC, foreground, spanData, pLeft->x, pLeft->y);
+ return;
+ }
+ } else {
+ if (joinStyle == JoinRound) {
+ miLineArc (pGC, foreground, spanData, pLeft, pRight, (double) 0.0, (double) 0.0, TRUE);
+ return;
+ }
+ denom = -pLeft->dx * (double) pRight->dy + pRight->dx * (double) pLeft->dy;
+ if (denom == 0.0)
+ return; /* no join to draw */
+ }
+
+ swapslopes = 0;
+ if (denom > 0) {
+ pLeft->xa = -pLeft->xa;
+ pLeft->ya = -pLeft->ya;
+ pLeft->dx = -pLeft->dx;
+ pLeft->dy = -pLeft->dy;
+ } else {
+ swapslopes = 1;
+ pRight->xa = -pRight->xa;
+ pRight->ya = -pRight->ya;
+ pRight->dx = -pRight->dx;
+ pRight->dy = -pRight->dy;
+ }
+
+ vertices[0].x = pRight->xa;
+ vertices[0].y = pRight->ya;
+ slopes[0].dx = -pRight->dy;
+ slopes[0].dy = pRight->dx;
+ slopes[0].k = 0;
+
+ vertices[1].x = 0;
+ vertices[1].y = 0;
+ slopes[1].dx = pLeft->dy;
+ slopes[1].dy = -pLeft->dx;
+ slopes[1].k = 0;
+
+ vertices[2].x = pLeft->xa;
+ vertices[2].y = pLeft->ya;
+
+ if (joinStyle == JoinMiter) {
+ my = (pLeft->dy * (pRight->xa * pRight->dy - pRight->ya * pRight->dx) -
+ pRight->dy * (pLeft->xa * pLeft->dy - pLeft->ya * pLeft->dx)) / denom;
+ if (pLeft->dy != 0) {
+ mx = pLeft->xa + (my - pLeft->ya) * (double) pLeft->dx / (double) pLeft->dy;
+ } else {
+ mx = pRight->xa + (my - pRight->ya) * (double) pRight->dx / (double) pRight->dy;
+ }
+ /* check miter limit */
+ if ((mx * mx + my * my) * 4 > SQSECANT * lw * lw)
+ joinStyle = JoinBevel;
+ }
+
+ if (joinStyle == JoinMiter) {
+ slopes[2].dx = pLeft->dx;
+ slopes[2].dy = pLeft->dy;
+ slopes[2].k = pLeft->k;
+ if (swapslopes) {
+ slopes[2].dx = -slopes[2].dx;
+ slopes[2].dy = -slopes[2].dy;
+ slopes[2].k = -slopes[2].k;
+ }
+ vertices[3].x = mx;
+ vertices[3].y = my;
+ slopes[3].dx = pRight->dx;
+ slopes[3].dy = pRight->dy;
+ slopes[3].k = pRight->k;
+ if (swapslopes) {
+ slopes[3].dx = -slopes[3].dx;
+ slopes[3].dy = -slopes[3].dy;
+ slopes[3].k = -slopes[3].k;
+ }
+ edgecount = 4;
+ } else {
+ double scale, dx, dy, adx, ady;
+
+ adx = dx = pRight->xa - pLeft->xa;
+ ady = dy = pRight->ya - pLeft->ya;
+ if (adx < 0)
+ adx = -adx;
+ if (ady < 0)
+ ady = -ady;
+ scale = ady;
+ if (adx > ady)
+ scale = adx;
+ slopes[2].dx = (int) ((dx * 65536) / scale);
+ slopes[2].dy = (int) ((dy * 65536) / scale);
+ slopes[2].k = ((pLeft->xa + pRight->xa) * slopes[2].dy -
+ (pLeft->ya + pRight->ya) * slopes[2].dx) / 2.0;
+ edgecount = 3;
+ }
+
+ y = miPolyBuildPoly (vertices, slopes, edgecount, pLeft->x, pLeft->y,
+ left, right, &nleft, &nright, &height);
+ miFillPolyHelper (pGC, foreground, spanData, y, height, left, right, nleft, nright);
+}
+
+static int
+miLineArcI (GCPtr pGC, int xorg, int yorg, DDXPointPtr points, int *widths)
+{
+ DDXPointPtr tpts, bpts;
+ int *twids, *bwids;
+ int x, y, e, ex, slw;
+
+ tpts = points;
+ twids = widths;
+ slw = pGC->lineWidth;
+ if (slw == 1) {
+ tpts->x = xorg;
+ tpts->y = yorg;
+ *twids = 1;
+ return 1;
+ }
+ bpts = tpts + slw;
+ bwids = twids + slw;
+ y = (slw >> 1) + 1;
+ if (slw & 1)
+ e = -((y << 2) + 3);
+ else
+ e = -(y << 3);
+ ex = -4;
+ x = 0;
+ while (y) {
+ e += (y << 3) - 4;
+ while (e >= 0) {
+ x++;
+ e += (ex = -((x << 3) + 4));
+ }
+ y--;
+ slw = (x << 1) + 1;
+ if ((e == ex) && (slw > 1))
+ slw--;
+ tpts->x = xorg - x;
+ tpts->y = yorg - y;
+ tpts++;
+ *twids++ = slw;
+ if ((y != 0) && ((slw > 1) || (e != ex))) {
+ bpts--;
+ bpts->x = xorg - x;
+ bpts->y = yorg + y;
+ *--bwids = slw;
+ }
+ }
+ return (pGC->lineWidth);
+}
+
+#define CLIPSTEPEDGE(edgey,edge,edgeleft) \
+ if (ybase == edgey) \
+ { \
+ if (edgeleft) \
+ { \
+ if (edge->x > xcl) \
+ xcl = edge->x; \
+ } \
+ else \
+ { \
+ if (edge->x < xcr) \
+ xcr = edge->x; \
+ } \
+ edgey++; \
+ edge->x += edge->stepx; \
+ edge->e += edge->dx; \
+ if (edge->e > 0) \
+ { \
+ edge->x += edge->signdx; \
+ edge->e -= edge->dy; \
+ } \
+ }
+
+static int
+miLineArcD (GCPtr pGC,
+ double xorg,
+ double yorg,
+ DDXPointPtr points,
+ int *widths,
+ PolyEdgePtr edge1,
+ int edgey1, Boolean edgeleft1, PolyEdgePtr edge2, int edgey2, Boolean edgeleft2)
+{
+ DDXPointPtr pts;
+ int *wids;
+ double radius, x0, y0, el, er, yk, xlk, xrk, k;
+ int xbase, ybase, y, boty, xl, xr, xcl, xcr;
+ int ymin, ymax;
+ Boolean edge1IsMin, edge2IsMin;
+ int ymin1, ymin2;
+
+ pts = points;
+ wids = widths;
+ xbase = (int)floor (xorg);
+ x0 = xorg - xbase;
+ ybase = ICEIL (yorg);
+ y0 = yorg - ybase;
+ xlk = x0 + x0 + 1.0;
+ xrk = x0 + x0 - 1.0;
+ yk = y0 + y0 - 1.0;
+ radius = ((double) pGC->lineWidth) / 2.0;
+ y = (int)floor (radius - y0 + 1.0);
+ ybase -= y;
+ ymin = ybase;
+ ymax = 65536;
+ edge1IsMin = FALSE;
+ ymin1 = edgey1;
+ if (edge1->dy >= 0) {
+ if (!edge1->dy) {
+ if (edgeleft1)
+ edge1IsMin = TRUE;
+ else
+ ymax = edgey1;
+ edgey1 = 65536;
+ } else {
+ if ((edge1->signdx < 0) == edgeleft1)
+ edge1IsMin = TRUE;
+ }
+ }
+ edge2IsMin = FALSE;
+ ymin2 = edgey2;
+ if (edge2->dy >= 0) {
+ if (!edge2->dy) {
+ if (edgeleft2)
+ edge2IsMin = TRUE;
+ else
+ ymax = edgey2;
+ edgey2 = 65536;
+ } else {
+ if ((edge2->signdx < 0) == edgeleft2)
+ edge2IsMin = TRUE;
+ }
+ }
+ if (edge1IsMin) {
+ ymin = ymin1;
+ if (edge2IsMin && ymin1 > ymin2)
+ ymin = ymin2;
+ } else if (edge2IsMin)
+ ymin = ymin2;
+ el = radius * radius - ((y + y0) * (y + y0)) - (x0 * x0);
+ er = el + xrk;
+ xl = 1;
+ xr = 0;
+ if (x0 < 0.5) {
+ xl = 0;
+ el -= xlk;
+ }
+ boty = (y0 < -0.5) ? 1 : 0;
+ if (ybase + y - boty > ymax)
+ boty = ymax - ybase - y;
+ while (y > boty) {
+ k = (y << 1) + yk;
+ er += k;
+ while (er > 0.0) {
+ xr++;
+ er += xrk - (xr << 1);
+ }
+ el += k;
+ while (el >= 0.0) {
+ xl--;
+ el += (xl << 1) - xlk;
+ }
+ y--;
+ ybase++;
+ if (ybase < ymin)
+ continue;
+ xcl = xl + xbase;
+ xcr = xr + xbase;
+ CLIPSTEPEDGE (edgey1, edge1, edgeleft1);
+ CLIPSTEPEDGE (edgey2, edge2, edgeleft2);
+ if (xcr >= xcl) {
+ pts->x = xcl;
+ pts->y = ybase;
+ pts++;
+ *wids++ = xcr - xcl + 1;
+ }
+ }
+ er = xrk - (xr << 1) - er;
+ el = (xl << 1) - xlk - el;
+ boty = (int)floor (-y0 - radius + 1.0);
+ if (ybase + y - boty > ymax)
+ boty = ymax - ybase - y;
+ while (y > boty) {
+ k = (y << 1) + yk;
+ er -= k;
+ while ((er >= 0.0) && (xr >= 0)) {
+ xr--;
+ er += xrk - (xr << 1);
+ }
+ el -= k;
+ while ((el > 0.0) && (xl <= 0)) {
+ xl++;
+ el += (xl << 1) - xlk;
+ }
+ y--;
+ ybase++;
+ if (ybase < ymin)
+ continue;
+ xcl = xl + xbase;
+ xcr = xr + xbase;
+ CLIPSTEPEDGE (edgey1, edge1, edgeleft1);
+ CLIPSTEPEDGE (edgey2, edge2, edgeleft2);
+ if (xcr >= xcl) {
+ pts->x = xcl;
+ pts->y = ybase;
+ pts++;
+ *wids++ = xcr - xcl + 1;
+ }
+ }
+ return (pts - points);
+}
+
+static int
+miRoundJoinFace (LineFacePtr face, PolyEdgePtr edge, Boolean * leftEdge)
+{
+ int y;
+ int dx, dy;
+ double xa, ya;
+ Boolean left;
+
+ dx = -face->dy;
+ dy = face->dx;
+ xa = face->xa;
+ ya = face->ya;
+ left = 1;
+ if (ya > 0) {
+ ya = 0.0;
+ xa = 0.0;
+ }
+ if (dy < 0 || (dy == 0 && dx > 0)) {
+ dx = -dx;
+ dy = -dy;
+ left = !left;
+ }
+ if (dx == 0 && dy == 0)
+ dy = 1;
+ if (dy == 0) {
+ y = ICEIL (face->ya) + face->y;
+ edge->x = -32767;
+ edge->stepx = 0;
+ edge->signdx = 0;
+ edge->e = -1;
+ edge->dy = 0;
+ edge->dx = 0;
+ edge->height = 0;
+ } else {
+ y = miPolyBuildEdge (xa, ya, 0.0, dx, dy, face->x, face->y, !left, edge);
+ edge->height = 32767;
+ }
+ *leftEdge = !left;
+ return y;
+}
+
+static void
+miRoundJoinClip (LineFacePtr pLeft, LineFacePtr pRight,
+ PolyEdgePtr edge1, PolyEdgePtr edge2, int *y1, int *y2, Boolean * left1, Boolean * left2)
+{
+ double denom;
+
+ denom = -pLeft->dx * (double) pRight->dy + pRight->dx * (double) pLeft->dy;
+
+ if (denom >= 0) {
+ pLeft->xa = -pLeft->xa;
+ pLeft->ya = -pLeft->ya;
+ } else {
+ pRight->xa = -pRight->xa;
+ pRight->ya = -pRight->ya;
+ }
+ *y1 = miRoundJoinFace (pLeft, edge1, left1);
+ *y2 = miRoundJoinFace (pRight, edge2, left2);
+}
+
+static int
+miRoundCapClip (LineFacePtr face, Boolean isInt, PolyEdgePtr edge, Boolean * leftEdge)
+{
+ int y;
+ int dx, dy;
+ double xa, ya, k;
+ Boolean left;
+
+ dx = -face->dy;
+ dy = face->dx;
+ xa = face->xa;
+ ya = face->ya;
+ k = 0.0;
+ if (!isInt)
+ k = face->k;
+ left = 1;
+ if (dy < 0 || (dy == 0 && dx > 0)) {
+ dx = -dx;
+ dy = -dy;
+ xa = -xa;
+ ya = -ya;
+ left = !left;
+ }
+ if (dx == 0 && dy == 0)
+ dy = 1;
+ if (dy == 0) {
+ y = ICEIL (face->ya) + face->y;
+ edge->x = -32767;
+ edge->stepx = 0;
+ edge->signdx = 0;
+ edge->e = -1;
+ edge->dy = 0;
+ edge->dx = 0;
+ edge->height = 0;
+ } else {
+ y = miPolyBuildEdge (xa, ya, k, dx, dy, face->x, face->y, !left, edge);
+ edge->height = 32767;
+ }
+ *leftEdge = !left;
+ return y;
+}
+
+static void
+miLineArc (GCPtr pGC,
+ Boolean foreground,
+ SpanDataPtr spanData,
+ LineFacePtr leftFace, LineFacePtr rightFace, double xorg, double yorg, Boolean isInt)
+{
+ DDXPointPtr points;
+ int *widths;
+ int xorgi = 0, yorgi = 0;
+ Spans spanRec;
+ int n;
+ PolyEdgeRec edge1, edge2;
+ int edgey1, edgey2;
+ Boolean edgeleft1, edgeleft2;
+
+ if (isInt) {
+ xorgi = leftFace ? leftFace->x : rightFace->x;
+ yorgi = leftFace ? leftFace->y : rightFace->y;
+ }
+ edgey1 = 65536;
+ edgey2 = 65536;
+ edge1.x = 0; /* not used, keep memory checkers happy */
+ edge1.dy = -1;
+ edge2.x = 0; /* not used, keep memory checkers happy */
+ edge2.dy = -1;
+ edgeleft1 = FALSE;
+ edgeleft2 = FALSE;
+ if ((pGC->lineStyle != LineSolid || pGC->lineWidth > 2) &&
+ ((pGC->capStyle == CapRound && pGC->joinStyle != JoinRound) ||
+ (pGC->joinStyle == JoinRound && pGC->capStyle == CapButt))) {
+ if (isInt) {
+ xorg = (double) xorgi;
+ yorg = (double) yorgi;
+ }
+ if (leftFace && rightFace) {
+ miRoundJoinClip (leftFace, rightFace, &edge1, &edge2,
+ &edgey1, &edgey2, &edgeleft1, &edgeleft2);
+ } else if (leftFace) {
+ edgey1 = miRoundCapClip (leftFace, isInt, &edge1, &edgeleft1);
+ } else if (rightFace) {
+ edgey2 = miRoundCapClip (rightFace, isInt, &edge2, &edgeleft2);
+ }
+ isInt = FALSE;
+ }
+ if (!spanData) {
+ points = (DDXPointRec *)xalloc (sizeof (DDXPointRec) * pGC->lineWidth);
+ if (!points)
+ return;
+ widths = (int *)xalloc (sizeof (int) * pGC->lineWidth);
+ if (!widths) {
+ xfree (points);
+ return;
+ }
+ } else {
+ points = (DDXPointRec *)xalloc (pGC->lineWidth * sizeof (DDXPointRec));
+ if (!points)
+ return;
+ widths = (int *)xalloc (pGC->lineWidth * sizeof (int));
+ if (!widths) {
+ xfree (points);
+ return;
+ }
+ spanRec.points = points;
+ spanRec.widths = widths;
+ }
+ if (isInt)
+ n = miLineArcI (pGC, xorgi, yorgi, points, widths);
+ else
+ n = miLineArcD (pGC, xorg, yorg, points, widths,
+ &edge1, edgey1, edgeleft1, &edge2, edgey2, edgeleft2);
+
+ if (!spanData) {
+ (*pGC->ops->FillSpans) (pGC, n, points, widths, TRUE, foreground);
+ xfree (widths);
+ xfree (points);
+ } else {
+ spanRec.count = n;
+ AppendSpanGroup (pGC, foreground, &spanRec, spanData)
+ }
+}
+
+static void
+miLineProjectingCap (GCPtr pGC,
+ Boolean foreground,
+ SpanDataPtr spanData,
+ LineFacePtr face,
+ Boolean isLeft,
+ SPICE_GNUC_UNUSED double xorg,
+ SPICE_GNUC_UNUSED double yorg,
+ Boolean isInt)
+{
+ int xorgi = 0, yorgi = 0;
+ int lw;
+ PolyEdgeRec lefts[4], rights[4];
+ int lefty, righty, topy, bottomy;
+ PolyEdgePtr left, right;
+ PolyEdgePtr top, bottom;
+ double xa, ya;
+ double k;
+ double xap, yap;
+ int dx, dy;
+ double projectXoff, projectYoff;
+ double maxy;
+ int finaly;
+
+ if (isInt) {
+ xorgi = face->x;
+ yorgi = face->y;
+ }
+ lw = pGC->lineWidth;
+ dx = face->dx;
+ dy = face->dy;
+ k = face->k;
+ if (dy == 0) {
+ lefts[0].height = lw;
+ lefts[0].x = xorgi;
+ if (isLeft)
+ lefts[0].x -= (lw >> 1);
+ lefts[0].stepx = 0;
+ lefts[0].signdx = 1;
+ lefts[0].e = -lw;
+ lefts[0].dx = 0;
+ lefts[0].dy = lw;
+ rights[0].height = lw;
+ rights[0].x = xorgi;
+ if (!isLeft)
+ rights[0].x += ((lw + 1) >> 1);
+ rights[0].stepx = 0;
+ rights[0].signdx = 1;
+ rights[0].e = -lw;
+ rights[0].dx = 0;
+ rights[0].dy = lw;
+ miFillPolyHelper (pGC, foreground, spanData, yorgi - (lw >> 1), lw, lefts, rights, 1, 1);
+ } else if (dx == 0) {
+ if (dy < 0) {
+ dy = -dy;
+ isLeft = !isLeft;
+ }
+ topy = yorgi;
+ bottomy = yorgi + dy;
+ if (isLeft)
+ topy -= (lw >> 1);
+ else
+ bottomy += (lw >> 1);
+ lefts[0].height = bottomy - topy;
+ lefts[0].x = xorgi - (lw >> 1);
+ lefts[0].stepx = 0;
+ lefts[0].signdx = 1;
+ lefts[0].e = -dy;
+ lefts[0].dx = dx;
+ lefts[0].dy = dy;
+
+ rights[0].height = bottomy - topy;
+ rights[0].x = lefts[0].x + (lw - 1);
+ rights[0].stepx = 0;
+ rights[0].signdx = 1;
+ rights[0].e = -dy;
+ rights[0].dx = dx;
+ rights[0].dy = dy;
+ miFillPolyHelper (pGC, foreground, spanData, topy, bottomy - topy, lefts, rights, 1, 1);
+ } else {
+ xa = face->xa;
+ ya = face->ya;
+ projectXoff = -ya;
+ projectYoff = xa;
+ if (dx < 0) {
+ right = &rights[1];
+ left = &lefts[0];
+ top = &rights[0];
+ bottom = &lefts[1];
+ } else {
+ right = &rights[0];
+ left = &lefts[1];
+ top = &lefts[0];
+ bottom = &rights[1];
+ }
+ if (isLeft) {
+ righty = miPolyBuildEdge (xa, ya, k, dx, dy, xorgi, yorgi, 0, right);
+
+ xa = -xa;
+ ya = -ya;
+ k = -k;
+ lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, xorgi, yorgi, 1, left);
+ if (dx > 0) {
+ ya = -ya;
+ xa = -xa;
+ }
+ xap = xa - projectXoff;
+ yap = ya - projectYoff;
+ topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, xorgi, yorgi, dx > 0, top);
+ bottomy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, xorgi, yorgi, dx < 0, bottom);
+ maxy = -ya;
+ } else {
+ righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, xorgi, yorgi, 0, right);
+
+ xa = -xa;
+ ya = -ya;
+ k = -k;
+ lefty = miPolyBuildEdge (xa, ya, k, dx, dy, xorgi, yorgi, 1, left);
+ if (dx > 0) {
+ ya = -ya;
+ xa = -xa;
+ }
+ xap = xa - projectXoff;
+ yap = ya - projectYoff;
+ topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, xorgi, xorgi, dx > 0, top);
+ bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, xorgi, xorgi, dx < 0, bottom);
+ maxy = -ya + projectYoff;
+ }
+ finaly = ICEIL (maxy) + yorgi;
+ if (dx < 0) {
+ left->height = bottomy - lefty;
+ right->height = finaly - righty;
+ top->height = righty - topy;
+ } else {
+ right->height = bottomy - righty;
+ left->height = finaly - lefty;
+ top->height = lefty - topy;
+ }
+ bottom->height = finaly - bottomy;
+ miFillPolyHelper (pGC, foreground, spanData, topy,
+ bottom->height + bottomy - topy, lefts, rights, 2, 2);
+ }
+}
+
+static void
+miWideSegment (GCPtr pGC,
+ Boolean foreground,
+ SpanDataPtr spanData,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ Boolean projectLeft, Boolean projectRight, LineFacePtr leftFace, LineFacePtr rightFace)
+{
+ double l, L, r;
+ double xa, ya;
+ double projectXoff = 0.0, projectYoff = 0.0;
+ double k;
+ double maxy;
+ int x, y;
+ int dx, dy;
+ int finaly;
+ PolyEdgePtr left, right;
+ PolyEdgePtr top, bottom;
+ int lefty, righty, topy, bottomy;
+ int signdx;
+ PolyEdgeRec lefts[4], rights[4];
+ LineFacePtr tface;
+ int lw = pGC->lineWidth;
+
+ /* draw top-to-bottom always */
+ if (y2 < y1 || (y2 == y1 && x2 < x1)) {
+ x = x1;
+ x1 = x2;
+ x2 = x;
+
+ y = y1;
+ y1 = y2;
+ y2 = y;
+
+ x = projectLeft;
+ projectLeft = projectRight;
+ projectRight = x;
+
+ tface = leftFace;
+ leftFace = rightFace;
+ rightFace = tface;
+ }
+
+ dy = y2 - y1;
+ signdx = 1;
+ dx = x2 - x1;
+ if (dx < 0)
+ signdx = -1;
+
+ leftFace->x = x1;
+ leftFace->y = y1;
+ leftFace->dx = dx;
+ leftFace->dy = dy;
+
+ rightFace->x = x2;
+ rightFace->y = y2;
+ rightFace->dx = -dx;
+ rightFace->dy = -dy;
+
+ if (dy == 0) {
+ rightFace->xa = 0;
+ rightFace->ya = (double) lw / 2.0;
+ rightFace->k = -(double) (lw * dx) / 2.0;
+ leftFace->xa = 0;
+ leftFace->ya = -rightFace->ya;
+ leftFace->k = rightFace->k;
+ x = x1;
+ if (projectLeft)
+ x -= (lw >> 1);
+ y = y1 - (lw >> 1);
+ dx = x2 - x;
+ if (projectRight)
+ dx += ((lw + 1) >> 1);
+ dy = lw;
+ miFillRectPolyHelper (pGC, foreground, spanData, x, y, dx, dy);
+ } else if (dx == 0) {
+ leftFace->xa = (double) lw / 2.0;
+ leftFace->ya = 0;
+ leftFace->k = (double) (lw * dy) / 2.0;
+ rightFace->xa = -leftFace->xa;
+ rightFace->ya = 0;
+ rightFace->k = leftFace->k;
+ y = y1;
+ if (projectLeft)
+ y -= lw >> 1;
+ x = x1 - (lw >> 1);
+ dy = y2 - y;
+ if (projectRight)
+ dy += ((lw + 1) >> 1);
+ dx = lw;
+ miFillRectPolyHelper (pGC, foreground, spanData, x, y, dx, dy);
+ } else {
+ l = ((double) lw) / 2.0;
+ L = hypot ((double) dx, (double) dy);
+
+ if (dx < 0) {
+ right = &rights[1];
+ left = &lefts[0];
+ top = &rights[0];
+ bottom = &lefts[1];
+ } else {
+ right = &rights[0];
+ left = &lefts[1];
+ top = &lefts[0];
+ bottom = &rights[1];
+ }
+ r = l / L;
+
+ /* coord of upper bound at integral y */
+ ya = -r * dx;
+ xa = r * dy;
+
+ if (projectLeft | projectRight) {
+ projectXoff = -ya;
+ projectYoff = xa;
+ }
+
+ /* xa * dy - ya * dx */
+ k = l * L;
+
+ leftFace->xa = xa;
+ leftFace->ya = ya;
+ leftFace->k = k;
+ rightFace->xa = -xa;
+ rightFace->ya = -ya;
+ rightFace->k = k;
+
+ if (projectLeft)
+ righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, x1, y1, 0, right);
+ else
+ righty = miPolyBuildEdge (xa, ya, k, dx, dy, x1, y1, 0, right);
+
+ /* coord of lower bound at integral y */
+ ya = -ya;
+ xa = -xa;
+
+ /* xa * dy - ya * dx */
+ k = -k;
+
+ if (projectLeft)
+ lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, x1, y1, 1, left);
+ else
+ lefty = miPolyBuildEdge (xa, ya, k, dx, dy, x1, y1, 1, left);
+
+ /* coord of top face at integral y */
+
+ if (signdx > 0) {
+ ya = -ya;
+ xa = -xa;
+ }
+
+ if (projectLeft) {
+ double xap = xa - projectXoff;
+ double yap = ya - projectYoff;
+ topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy, -dy, dx, x1, y1, dx > 0, top);
+ } else
+ topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, x1, y1, dx > 0, top);
+
+ /* coord of bottom face at integral y */
+
+ if (projectRight) {
+ double xap = xa + projectXoff;
+ double yap = ya + projectYoff;
+ bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, x2, y2, dx < 0, bottom);
+ maxy = -ya + projectYoff;
+ } else {
+ bottomy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, x2, y2, dx < 0, bottom);
+ maxy = -ya;
+ }
+
+ finaly = ICEIL (maxy) + y2;
+
+ if (dx < 0) {
+ left->height = bottomy - lefty;
+ right->height = finaly - righty;
+ top->height = righty - topy;
+ } else {
+ right->height = bottomy - righty;
+ left->height = finaly - lefty;
+ top->height = lefty - topy;
+ }
+ bottom->height = finaly - bottomy;
+ miFillPolyHelper (pGC, foreground, spanData, topy,
+ bottom->height + bottomy - topy, lefts, rights, 2, 2);
+ }
+}
+
+static SpanDataPtr
+miSetupSpanData (GCPtr pGC, SpanDataPtr spanData, int npt)
+{
+ if ((npt < 3 && pGC->capStyle != CapRound) || miSpansEasyRop (pGC->alu))
+ return (SpanDataPtr) NULL;
+ if (pGC->lineStyle == LineDoubleDash)
+ miInitSpanGroup (&spanData->bgGroup);
+ miInitSpanGroup (&spanData->fgGroup);
+ return spanData;
+}
+
+static void
+miCleanupSpanData (GCPtr pGC, SpanDataPtr spanData)
+{
+ if (pGC->lineStyle == LineDoubleDash) {
+ miFillUniqueSpanGroup (pGC, &spanData->bgGroup, FALSE);
+ miFreeSpanGroup (&spanData->bgGroup);
+ }
+ miFillUniqueSpanGroup (pGC, &spanData->fgGroup, TRUE);
+ miFreeSpanGroup (&spanData->fgGroup);
+}
+
+void
+miWideLine (GCPtr pGC, int mode, int npt, DDXPointPtr pPts)
+{
+ int x1, y1, x2, y2;
+ SpanDataRec spanDataRec;
+ SpanDataPtr spanData;
+ Boolean projectLeft, projectRight;
+ LineFaceRec leftFace, rightFace, prevRightFace;
+ LineFaceRec firstFace;
+ int first;
+ Boolean somethingDrawn = FALSE;
+ Boolean selfJoin;
+
+ spanData = miSetupSpanData (pGC, &spanDataRec, npt);
+ x2 = pPts->x;
+ y2 = pPts->y;
+ first = TRUE;
+ selfJoin = FALSE;
+ if (npt > 1) {
+ if (mode == CoordModePrevious) {
+ int nptTmp;
+ DDXPointPtr pPtsTmp;
+
+ x1 = x2;
+ y1 = y2;
+ nptTmp = npt;
+ pPtsTmp = pPts + 1;
+ while (--nptTmp) {
+ x1 += pPtsTmp->x;
+ y1 += pPtsTmp->y;
+ ++pPtsTmp;
+ }
+ if (x2 == x1 && y2 == y1)
+ selfJoin = TRUE;
+ } else if (x2 == pPts[npt - 1].x && y2 == pPts[npt - 1].y) {
+ selfJoin = TRUE;
+ }
+ }
+ projectLeft = pGC->capStyle == CapProjecting && !selfJoin;
+ projectRight = FALSE;
+ while (--npt) {
+ x1 = x2;
+ y1 = y2;
+ ++pPts;
+ x2 = pPts->x;
+ y2 = pPts->y;
+ if (mode == CoordModePrevious) {
+ x2 += x1;
+ y2 += y1;
+ }
+ if (x1 != x2 || y1 != y2) {
+ somethingDrawn = TRUE;
+ if (npt == 1 && pGC->capStyle == CapProjecting && !selfJoin)
+ projectRight = TRUE;
+ miWideSegment (pGC, TRUE, spanData, x1, y1, x2, y2,
+ projectLeft, projectRight, &leftFace, &rightFace);
+ if (first) {
+ if (selfJoin)
+ firstFace = leftFace;
+ else if (pGC->capStyle == CapRound) {
+ if (pGC->lineWidth == 1 && !spanData)
+ miLineOnePoint (pGC, TRUE, spanData, x1, y1);
+ else
+ miLineArc (pGC, TRUE, spanData,
+ &leftFace, (LineFacePtr) NULL, (double) 0.0, (double) 0.0, TRUE);
+ }
+ } else {
+ miLineJoin (pGC, TRUE, spanData, &leftFace, &prevRightFace);
+ }
+ prevRightFace = rightFace;
+ first = FALSE;
+ projectLeft = FALSE;
+ }
+ if (npt == 1 && somethingDrawn) {
+ if (selfJoin)
+ miLineJoin (pGC, TRUE, spanData, &firstFace, &rightFace);
+ else if (pGC->capStyle == CapRound) {
+ if (pGC->lineWidth == 1 && !spanData)
+ miLineOnePoint (pGC, TRUE, spanData, x2, y2);
+ else
+ miLineArc (pGC, TRUE, spanData,
+ (LineFacePtr) NULL, &rightFace, (double) 0.0, (double) 0.0, TRUE);
+ }
+ }
+ }
+ /* handle crock where all points are coincedent */
+ if (!somethingDrawn) {
+ projectLeft = pGC->capStyle == CapProjecting;
+ miWideSegment (pGC, TRUE, spanData,
+ x2, y2, x2, y2, projectLeft, projectLeft, &leftFace, &rightFace);
+ if (pGC->capStyle == CapRound) {
+ miLineArc (pGC, TRUE, spanData,
+ &leftFace, (LineFacePtr) NULL, (double) 0.0, (double) 0.0, TRUE);
+ rightFace.dx = -1; /* sleezy hack to make it work */
+ miLineArc (pGC, TRUE, spanData,
+ (LineFacePtr) NULL, &rightFace, (double) 0.0, (double) 0.0, TRUE);
+ }
+ }
+ if (spanData)
+ miCleanupSpanData (pGC, spanData);
+}
+
+#define V_TOP 0
+#define V_RIGHT 1
+#define V_BOTTOM 2
+#define V_LEFT 3
+
+static void
+miWideDashSegment (GCPtr pGC,
+ SpanDataPtr spanData,
+ int *pDashOffset,
+ int *pDashIndex,
+ int x1,
+ int y1,
+ int x2,
+ int y2,
+ Boolean projectLeft, Boolean projectRight, LineFacePtr leftFace, LineFacePtr rightFace)
+{
+ int dashIndex, dashRemain;
+ unsigned char *pDash;
+ double L, l;
+ double k;
+ PolyVertexRec vertices[4];
+ PolyVertexRec saveRight = { 0, 0 }, saveBottom;
+ PolySlopeRec slopes[4];
+ PolyEdgeRec left[4], right[4];
+ LineFaceRec lcapFace, rcapFace;
+ int nleft, nright;
+ int h;
+ int y;
+ int dy, dx;
+ Boolean foreground;
+ double LRemain;
+ double r;
+ double rdx, rdy;
+ double dashDx, dashDy;
+ double saveK = 0.0;
+ Boolean first = TRUE;
+ double lcenterx, lcentery, rcenterx = 0.0, rcentery = 0.0;
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ dashIndex = *pDashIndex;
+ pDash = pGC->dash;
+ dashRemain = pDash[dashIndex] - *pDashOffset;
+
+ l = ((double) pGC->lineWidth) / 2.0;
+ if (dx == 0) {
+ L = dy;
+ rdx = 0;
+ rdy = l;
+ if (dy < 0) {
+ L = -dy;
+ rdy = -l;
+ }
+ } else if (dy == 0) {
+ L = dx;
+ rdx = l;
+ rdy = 0;
+ if (dx < 0) {
+ L = -dx;
+ rdx = -l;
+ }
+ } else {
+ L = hypot ((double) dx, (double) dy);
+ r = l / L;
+
+ rdx = r * dx;
+ rdy = r * dy;
+ }
+ k = l * L;
+ LRemain = L;
+ /* All position comments are relative to a line with dx and dy > 0,
+ * but the code does not depend on this */
+ /* top */
+ slopes[V_TOP].dx = dx;
+ slopes[V_TOP].dy = dy;
+ slopes[V_TOP].k = k;
+ /* right */
+ slopes[V_RIGHT].dx = -dy;
+ slopes[V_RIGHT].dy = dx;
+ slopes[V_RIGHT].k = 0;
+ /* bottom */
+ slopes[V_BOTTOM].dx = -dx;
+ slopes[V_BOTTOM].dy = -dy;
+ slopes[V_BOTTOM].k = k;
+ /* left */
+ slopes[V_LEFT].dx = dy;
+ slopes[V_LEFT].dy = -dx;
+ slopes[V_LEFT].k = 0;
+
+ /* preload the start coordinates */
+ vertices[V_RIGHT].x = vertices[V_TOP].x = rdy;
+ vertices[V_RIGHT].y = vertices[V_TOP].y = -rdx;
+
+ vertices[V_BOTTOM].x = vertices[V_LEFT].x = -rdy;
+ vertices[V_BOTTOM].y = vertices[V_LEFT].y = rdx;
+
+ if (projectLeft) {
+ vertices[V_TOP].x -= rdx;
+ vertices[V_TOP].y -= rdy;
+
+ vertices[V_LEFT].x -= rdx;
+ vertices[V_LEFT].y -= rdy;
+
+ slopes[V_LEFT].k = rdx * dx + rdy * dy;
+ }
+
+ lcenterx = x1;
+ lcentery = y1;
+
+ if (pGC->capStyle == CapRound) {
+ lcapFace.dx = dx;
+ lcapFace.dy = dy;
+ lcapFace.x = x1;
+ lcapFace.y = y1;
+
+ rcapFace.dx = -dx;
+ rcapFace.dy = -dy;
+ rcapFace.x = x1;
+ rcapFace.y = y1;
+ }
+ while (LRemain > dashRemain) {
+ dashDx = (dashRemain * dx) / L;
+ dashDy = (dashRemain * dy) / L;
+
+ rcenterx = lcenterx + dashDx;
+ rcentery = lcentery + dashDy;
+
+ vertices[V_RIGHT].x += dashDx;
+ vertices[V_RIGHT].y += dashDy;
+
+ vertices[V_BOTTOM].x += dashDx;
+ vertices[V_BOTTOM].y += dashDy;
+
+ slopes[V_RIGHT].k = vertices[V_RIGHT].x * dx + vertices[V_RIGHT].y * dy;
+
+ if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1)) {
+ if (pGC->lineStyle == LineOnOffDash && pGC->capStyle == CapProjecting) {
+ saveRight = vertices[V_RIGHT];
+ saveBottom = vertices[V_BOTTOM];
+ saveK = slopes[V_RIGHT].k;
+
+ if (!first) {
+ vertices[V_TOP].x -= rdx;
+ vertices[V_TOP].y -= rdy;
+
+ vertices[V_LEFT].x -= rdx;
+ vertices[V_LEFT].y -= rdy;
+
+ slopes[V_LEFT].k = vertices[V_LEFT].x *
+ slopes[V_LEFT].dy - vertices[V_LEFT].y * slopes[V_LEFT].dx;
+ }
+
+ vertices[V_RIGHT].x += rdx;
+ vertices[V_RIGHT].y += rdy;
+
+ vertices[V_BOTTOM].x += rdx;
+ vertices[V_BOTTOM].y += rdy;
+
+ slopes[V_RIGHT].k = vertices[V_RIGHT].x *
+ slopes[V_RIGHT].dy - vertices[V_RIGHT].y * slopes[V_RIGHT].dx;
+ }
+ y = miPolyBuildPoly (vertices, slopes, 4, x1, y1, left, right, &nleft, &nright, &h);
+ foreground = (dashIndex & 1) == 0;
+ miFillPolyHelper (pGC, foreground, spanData, y, h, left, right, nleft, nright);
+
+ if (pGC->lineStyle == LineOnOffDash) {
+ switch (pGC->capStyle) {
+ case CapProjecting:
+ vertices[V_BOTTOM] = saveBottom;
+ vertices[V_RIGHT] = saveRight;
+ slopes[V_RIGHT].k = saveK;
+ break;
+ case CapRound:
+ if (!first) {
+ if (dx < 0) {
+ lcapFace.xa = -vertices[V_LEFT].x;
+ lcapFace.ya = -vertices[V_LEFT].y;
+ lcapFace.k = slopes[V_LEFT].k;
+ } else {
+ lcapFace.xa = vertices[V_TOP].x;
+ lcapFace.ya = vertices[V_TOP].y;
+ lcapFace.k = -slopes[V_LEFT].k;
+ }
+ miLineArc (pGC, foreground, spanData,
+ &lcapFace, (LineFacePtr) NULL, lcenterx, lcentery, FALSE);
+ }
+ if (dx < 0) {
+ rcapFace.xa = vertices[V_BOTTOM].x;
+ rcapFace.ya = vertices[V_BOTTOM].y;
+ rcapFace.k = slopes[V_RIGHT].k;
+ } else {
+ rcapFace.xa = -vertices[V_RIGHT].x;
+ rcapFace.ya = -vertices[V_RIGHT].y;
+ rcapFace.k = -slopes[V_RIGHT].k;
+ }
+ miLineArc (pGC, foreground, spanData,
+ (LineFacePtr) NULL, &rcapFace, rcenterx, rcentery, FALSE);
+ break;
+ }
+ }
+ }
+ LRemain -= dashRemain;
+ ++dashIndex;
+ if (dashIndex == pGC->numInDashList)
+ dashIndex = 0;
+ dashRemain = pDash[dashIndex];
+
+ lcenterx = rcenterx;
+ lcentery = rcentery;
+
+ vertices[V_TOP] = vertices[V_RIGHT];
+ vertices[V_LEFT] = vertices[V_BOTTOM];
+ slopes[V_LEFT].k = -slopes[V_RIGHT].k;
+ first = FALSE;
+ }
+
+ if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1)) {
+ vertices[V_TOP].x -= dx;
+ vertices[V_TOP].y -= dy;
+
+ vertices[V_LEFT].x -= dx;
+ vertices[V_LEFT].y -= dy;
+
+ vertices[V_RIGHT].x = rdy;
+ vertices[V_RIGHT].y = -rdx;
+
+ vertices[V_BOTTOM].x = -rdy;
+ vertices[V_BOTTOM].y = rdx;
+
+
+ if (projectRight) {
+ vertices[V_RIGHT].x += rdx;
+ vertices[V_RIGHT].y += rdy;
+
+ vertices[V_BOTTOM].x += rdx;
+ vertices[V_BOTTOM].y += rdy;
+ slopes[V_RIGHT].k = vertices[V_RIGHT].x *
+ slopes[V_RIGHT].dy - vertices[V_RIGHT].y * slopes[V_RIGHT].dx;
+ } else
+ slopes[V_RIGHT].k = 0;
+
+ if (!first && pGC->lineStyle == LineOnOffDash && pGC->capStyle == CapProjecting) {
+ vertices[V_TOP].x -= rdx;
+ vertices[V_TOP].y -= rdy;
+
+ vertices[V_LEFT].x -= rdx;
+ vertices[V_LEFT].y -= rdy;
+ slopes[V_LEFT].k = vertices[V_LEFT].x *
+ slopes[V_LEFT].dy - vertices[V_LEFT].y * slopes[V_LEFT].dx;
+ } else
+ slopes[V_LEFT].k += dx * dx + dy * dy;
+
+
+ y = miPolyBuildPoly (vertices, slopes, 4, x2, y2, left, right, &nleft, &nright, &h);
+
+ foreground = (dashIndex & 1) == 0;
+ miFillPolyHelper (pGC, foreground, spanData, y, h, left, right, nleft, nright);
+ if (!first && pGC->lineStyle == LineOnOffDash && pGC->capStyle == CapRound) {
+ lcapFace.x = x2;
+ lcapFace.y = y2;
+ if (dx < 0) {
+ lcapFace.xa = -vertices[V_LEFT].x;
+ lcapFace.ya = -vertices[V_LEFT].y;
+ lcapFace.k = slopes[V_LEFT].k;
+ } else {
+ lcapFace.xa = vertices[V_TOP].x;
+ lcapFace.ya = vertices[V_TOP].y;
+ lcapFace.k = -slopes[V_LEFT].k;
+ }
+ miLineArc (pGC, foreground, spanData,
+ &lcapFace, (LineFacePtr) NULL, rcenterx, rcentery, FALSE);
+ }
+ }
+ dashRemain = (int)(((double) dashRemain) - LRemain);
+ if (dashRemain == 0) {
+ dashIndex++;
+ if (dashIndex == pGC->numInDashList)
+ dashIndex = 0;
+ dashRemain = pDash[dashIndex];
+ }
+
+ leftFace->x = x1;
+ leftFace->y = y1;
+ leftFace->dx = dx;
+ leftFace->dy = dy;
+ leftFace->xa = rdy;
+ leftFace->ya = -rdx;
+ leftFace->k = k;
+
+ rightFace->x = x2;
+ rightFace->y = y2;
+ rightFace->dx = -dx;
+ rightFace->dy = -dy;
+ rightFace->xa = -rdy;
+ rightFace->ya = rdx;
+ rightFace->k = k;
+
+ *pDashIndex = dashIndex;
+ *pDashOffset = pDash[dashIndex] - dashRemain;
+}
+
+void
+miWideDash (GCPtr pGC, int mode, int npt, DDXPointPtr pPts)
+{
+ int x1, y1, x2, y2;
+ Boolean foreground;
+ Boolean projectLeft, projectRight;
+ LineFaceRec leftFace, rightFace, prevRightFace;
+ LineFaceRec firstFace;
+ int first;
+ int dashIndex, dashOffset;
+ int prevDashIndex;
+ SpanDataRec spanDataRec;
+ SpanDataPtr spanData;
+ Boolean somethingDrawn = FALSE;
+ Boolean selfJoin;
+ Boolean endIsFg = FALSE, startIsFg = FALSE;
+ Boolean firstIsFg = FALSE, prevIsFg = FALSE;
+
+ if (npt == 0)
+ return;
+ spanData = miSetupSpanData (pGC, &spanDataRec, npt);
+ x2 = pPts->x;
+ y2 = pPts->y;
+ first = TRUE;
+ selfJoin = FALSE;
+ if (mode == CoordModePrevious) {
+ int nptTmp;
+ DDXPointPtr pPtsTmp;
+
+ x1 = x2;
+ y1 = y2;
+ nptTmp = npt;
+ pPtsTmp = pPts + 1;
+ while (--nptTmp) {
+ x1 += pPtsTmp->x;
+ y1 += pPtsTmp->y;
+ ++pPtsTmp;
+ }
+ if (x2 == x1 && y2 == y1)
+ selfJoin = TRUE;
+ } else if (x2 == pPts[npt - 1].x && y2 == pPts[npt - 1].y) {
+ selfJoin = TRUE;
+ }
+ projectLeft = pGC->capStyle == CapProjecting && !selfJoin;
+ projectRight = FALSE;
+ dashIndex = 0;
+ dashOffset = 0;
+ miStepDash ((int) pGC->dashOffset, &dashIndex,
+ pGC->dash, (int) pGC->numInDashList, &dashOffset);
+ while (--npt) {
+ x1 = x2;
+ y1 = y2;
+ ++pPts;
+ x2 = pPts->x;
+ y2 = pPts->y;
+ if (mode == CoordModePrevious) {
+ x2 += x1;
+ y2 += y1;
+ }
+ if (x1 != x2 || y1 != y2) {
+ somethingDrawn = TRUE;
+ if (npt == 1 && pGC->capStyle == CapProjecting && (!selfJoin || !firstIsFg))
+ projectRight = TRUE;
+ prevDashIndex = dashIndex;
+ miWideDashSegment (pGC, spanData, &dashOffset, &dashIndex,
+ x1, y1, x2, y2, projectLeft, projectRight, &leftFace, &rightFace);
+ startIsFg = !(prevDashIndex & 1);
+ endIsFg = (dashIndex & 1) ^ (dashOffset != 0);
+ if (pGC->lineStyle == LineDoubleDash || startIsFg) {
+ foreground = startIsFg;
+ if (first || (pGC->lineStyle == LineOnOffDash && !prevIsFg)) {
+ if (first && selfJoin) {
+ firstFace = leftFace;
+ firstIsFg = startIsFg;
+ } else if (pGC->capStyle == CapRound)
+ miLineArc (pGC, foreground, spanData,
+ &leftFace, (LineFacePtr) NULL, (double) 0.0, (double) 0.0, TRUE);
+ } else {
+ miLineJoin (pGC, foreground, spanData, &leftFace, &prevRightFace);
+ }
+ }
+ prevRightFace = rightFace;
+ prevIsFg = endIsFg;
+ first = FALSE;
+ projectLeft = FALSE;
+ }
+ if (npt == 1 && somethingDrawn) {
+ if (pGC->lineStyle == LineDoubleDash || endIsFg) {
+ foreground = endIsFg;
+ if (selfJoin && (pGC->lineStyle == LineDoubleDash || firstIsFg)) {
+ miLineJoin (pGC, foreground, spanData, &firstFace, &rightFace);
+ } else {
+ if (pGC->capStyle == CapRound)
+ miLineArc (pGC, foreground, spanData,
+ (LineFacePtr) NULL, &rightFace,
+ (double) 0.0, (double) 0.0, TRUE);
+ }
+ } else {
+ /* glue a cap to the start of the line if
+ * we're OnOffDash and ended on odd dash
+ */
+ if (selfJoin && firstIsFg) {
+ foreground = TRUE;
+ if (pGC->capStyle == CapProjecting)
+ miLineProjectingCap (pGC, foreground, spanData,
+ &firstFace, TRUE, (double) 0.0, (double) 0.0, TRUE);
+ else if (pGC->capStyle == CapRound)
+ miLineArc (pGC, foreground, spanData,
+ &firstFace, (LineFacePtr) NULL,
+ (double) 0.0, (double) 0.0, TRUE);
+ }
+ }
+ }
+ }
+ /* handle crock where all points are coincident */
+ if (!somethingDrawn && (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1))) {
+ /* not the same as endIsFg computation above */
+ foreground = (dashIndex & 1) == 0;
+ switch (pGC->capStyle) {
+ case CapRound:
+ miLineArc (pGC, foreground, spanData,
+ (LineFacePtr) NULL, (LineFacePtr) NULL, (double) x2, (double) y2, FALSE);
+ break;
+ case CapProjecting:
+ x1 = pGC->lineWidth;
+ miFillRectPolyHelper (pGC, foreground, spanData,
+ x2 - (x1 >> 1), y2 - (x1 >> 1), x1, x1);
+ break;
+ }
+ }
+ if (spanData)
+ miCleanupSpanData (pGC, spanData);
+}
+
+#undef ExchangeSpans
+#define ExchangeSpans(a, b) \
+{ \
+ DDXPointRec tpt; \
+ int tw; \
+ \
+ tpt = spans[a]; spans[a] = spans[b]; spans[b] = tpt; \
+ tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
+}
+
+static void QuickSortSpans(
+ DDXPointRec spans[],
+ int widths[],
+ int numSpans)
+{
+ int y;
+ int i, j, m;
+ DDXPointPtr r;
+
+ /* Always called with numSpans > 1 */
+ /* Sorts only by y, doesn't bother to sort by x */
+
+ do
+ {
+ if (numSpans < 9)
+ {
+ /* Do insertion sort */
+ int yprev;
+
+ yprev = spans[0].y;
+ i = 1;
+ do
+ { /* while i != numSpans */
+ y = spans[i].y;
+ if (yprev > y)
+ {
+ /* spans[i] is out of order. Move into proper location. */
+ DDXPointRec tpt;
+ int tw, k;
+
+ for (j = 0; y >= spans[j].y; j++) {}
+ tpt = spans[i];
+ tw = widths[i];
+ for (k = i; k != j; k--)
+ {
+ spans[k] = spans[k-1];
+ widths[k] = widths[k-1];
+ }
+ spans[j] = tpt;
+ widths[j] = tw;
+ y = spans[i].y;
+ } /* if out of order */
+ yprev = y;
+ i++;
+ } while (i != numSpans);
+ return;
+ }
+
+ /* Choose partition element, stick in location 0 */
+ m = numSpans / 2;
+ if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
+ if (spans[m].y > spans[numSpans-1].y) ExchangeSpans(m, numSpans-1);
+ if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
+ y = spans[0].y;
+
+ /* Partition array */
+ i = 0;
+ j = numSpans;
+ do
+ {
+ r = &(spans[i]);
+ do
+ {
+ r++;
+ i++;
+ } while (i != numSpans && r->y < y);
+ r = &(spans[j]);
+ do
+ {
+ r--;
+ j--;
+ } while (y < r->y);
+ if (i < j)
+ ExchangeSpans(i, j);
+ } while (i < j);
+
+ /* Move partition element back to middle */
+ ExchangeSpans(0, j);
+
+ /* Recurse */
+ if (numSpans-j-1 > 1)
+ QuickSortSpans(&spans[j+1], &widths[j+1], numSpans-j-1);
+ numSpans = j;
+ } while (numSpans > 1);
+}
+
+#define NextBand() \
+{ \
+ clipy1 = pboxBandStart->y1; \
+ clipy2 = pboxBandStart->y2; \
+ pboxBandEnd = pboxBandStart + 1; \
+ while (pboxBandEnd != pboxLast && pboxBandEnd->y1 == clipy1) { \
+ pboxBandEnd++; \
+ } \
+ for (; ppt != pptLast && ppt->y < clipy1; ppt++, pwidth++) {} \
+}
+
+/*
+ Clip a list of scanlines to a region. The caller has allocated the
+ space. FSorted is non-zero if the scanline origins are in ascending
+ order.
+ returns the number of new, clipped scanlines.
+*/
+
+int spice_canvas_clip_spans(pixman_region32_t *prgnDst,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ DDXPointPtr pptNew,
+ int *pwidthNew,
+ int fSorted)
+{
+ DDXPointPtr pptLast;
+ int *pwidthNewStart; /* the vengeance of Xerox! */
+ int y, x1, x2;
+ int numRects;
+ pixman_box32_t *pboxBandStart;
+
+ pptLast = ppt + nspans;
+ pwidthNewStart = pwidthNew;
+
+ pboxBandStart = pixman_region32_rectangles (prgnDst, &numRects);
+
+ if (numRects == 1) {
+ /* Do special fast code with clip boundaries in registers(?) */
+ /* It doesn't pay much to make use of fSorted in this case,
+ so we lump everything together. */
+
+ int clipx1, clipx2, clipy1, clipy2;
+
+ clipx1 = pboxBandStart->x1;
+ clipy1 = pboxBandStart->y1;
+ clipx2 = pboxBandStart->x2;
+ clipy2 = pboxBandStart->y2;
+
+ for (; ppt != pptLast; ppt++, pwidth++) {
+ y = ppt->y;
+ x1 = ppt->x;
+ if (clipy1 <= y && y < clipy2) {
+ x2 = x1 + *pwidth;
+ if (x1 < clipx1)
+ x1 = clipx1;
+ if (x2 > clipx2)
+ x2 = clipx2;
+ if (x1 < x2) {
+ /* part of span in clip rectangle */
+ pptNew->x = x1;
+ pptNew->y = y;
+ *pwidthNew = x2 - x1;
+ pptNew++;
+ pwidthNew++;
+ }
+ }
+ } /* end for */
+ } else if (numRects != 0) {
+ /* Have to clip against many boxes */
+ pixman_box32_t *pboxBandEnd, *pbox, *pboxLast;
+ int clipy1, clipy2;
+
+ /* In this case, taking advantage of sorted spans gains more than
+ the sorting costs. */
+ if ((! fSorted) && (nspans > 1))
+ QuickSortSpans(ppt, pwidth, nspans);
+
+ pboxLast = pboxBandStart + numRects;
+
+ NextBand();
+
+ for (; ppt != pptLast; ) {
+ y = ppt->y;
+ if (y < clipy2) {
+ /* span is in the current band */
+ pbox = pboxBandStart;
+ x1 = ppt->x;
+ x2 = x1 + *pwidth;
+ do { /* For each box in band */
+ int newx1, newx2;
+
+ newx1 = x1;
+ newx2 = x2;
+ if (newx1 < pbox->x1)
+ newx1 = pbox->x1;
+ if (newx2 > pbox->x2)
+ newx2 = pbox->x2;
+ if (newx1 < newx2) {
+ /* Part of span in clip rectangle */
+ pptNew->x = newx1;
+ pptNew->y = y;
+ *pwidthNew = newx2 - newx1;
+ pptNew++;
+ pwidthNew++;
+ }
+ pbox++;
+ } while (pbox != pboxBandEnd);
+ ppt++;
+ pwidth++;
+ } else {
+ /* Move to next band, adjust ppt as needed */
+ pboxBandStart = pboxBandEnd;
+ if (pboxBandStart == pboxLast)
+ break; /* We're completely done */
+ NextBand();
+ }
+ }
+ }
+ return (pwidthNew - pwidthNewStart);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#ifndef LINES_H
+#define LINES_H
+
+#include <stdlib.h>
+#include <string.h>
+#include <spice/macros.h>
+
+#include "pixman_utils.h"
+#include "draw.h"
+
+SPICE_BEGIN_DECLS
+
+typedef struct lineGC lineGC;
+
+typedef struct {
+ void (*FillSpans)(lineGC * pGC,
+ int num_spans, SpicePoint * points, int *widths,
+ int sorted, int foreground);
+ void (*FillRects)(lineGC * pGC,
+ int nun_rects, pixman_rectangle32_t * rects,
+ int foreground);
+} lineGCOps;
+
+struct lineGC {
+ int width;
+ int height;
+ unsigned char alu;
+ unsigned short lineWidth;
+ unsigned short dashOffset;
+ unsigned short numInDashList;
+ unsigned char *dash;
+ unsigned int lineStyle:2;
+ unsigned int capStyle:2;
+ unsigned int joinStyle:2;
+ lineGCOps *ops;
+};
+
+/* CoordinateMode for drawing routines */
+
+#define CoordModeOrigin 0 /* relative to the origin */
+#define CoordModePrevious 1 /* relative to previous point */
+
+/* LineStyle */
+
+#define LineSolid 0
+#define LineOnOffDash 1
+#define LineDoubleDash 2
+
+/* capStyle */
+
+#define CapNotLast 0
+#define CapButt 1
+#define CapRound 2
+#define CapProjecting 3
+
+/* joinStyle */
+
+#define JoinMiter 0
+#define JoinRound 1
+#define JoinBevel 2
+
+extern void spice_canvas_zero_line(lineGC *pgc,
+ int mode,
+ int num_points,
+ SpicePoint * points);
+extern void spice_canvas_zero_dash_line(lineGC * pgc,
+ int mode,
+ int n_points,
+ SpicePoint * points);
+extern void spice_canvas_wide_dash_line(lineGC * pGC,
+ int mode,
+ int num_points,
+ SpicePoint * points);
+extern void spice_canvas_wide_line(lineGC *pGC,
+ int mode,
+ int num_points,
+ SpicePoint * points);
+extern int spice_canvas_clip_spans(pixman_region32_t *clip_region,
+ SpicePoint *points,
+ int *widths,
+ int num_spans,
+ SpicePoint *new_points,
+ int *new_widths,
+ int sorted);
+
+SPICE_END_DECLS
+
+#endif /* LINES_H */
--- /dev/null
+/*
+ Copyright (C) 2012-2015 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+
+#include "log.h"
+#include "backtrace.h"
+
+static int glib_debug_level = 0;
+static int abort_level = -1;
+
+#ifndef SPICE_ABORT_LEVEL_DEFAULT
+#ifdef SPICE_DISABLE_ABORT
+#define SPICE_ABORT_LEVEL_DEFAULT -1
+#else
+#define SPICE_ABORT_LEVEL_DEFAULT SPICE_LOG_LEVEL_CRITICAL
+#endif
+#endif
+
+static GLogLevelFlags spice_log_level_to_glib(SpiceLogLevel level)
+{
+ static const GLogLevelFlags glib_levels[] = {
+ [ SPICE_LOG_LEVEL_ERROR ] = G_LOG_LEVEL_ERROR,
+ [ SPICE_LOG_LEVEL_CRITICAL ] = G_LOG_LEVEL_CRITICAL,
+ [ SPICE_LOG_LEVEL_WARNING ] = G_LOG_LEVEL_WARNING,
+ [ SPICE_LOG_LEVEL_INFO ] = G_LOG_LEVEL_INFO,
+ [ SPICE_LOG_LEVEL_DEBUG ] = G_LOG_LEVEL_DEBUG,
+ };
+ g_return_val_if_fail (level >= 0, G_LOG_LEVEL_ERROR);
+ g_return_val_if_fail (level < G_N_ELEMENTS(glib_levels), G_LOG_LEVEL_DEBUG);
+
+ return glib_levels[level];
+}
+
+static void spice_log_set_debug_level(void)
+{
+ if (glib_debug_level == 0) {
+ const char *debug_str = g_getenv("SPICE_DEBUG_LEVEL");
+ if (debug_str != NULL) {
+ int debug_level;
+ char *debug_env;
+
+ /* FIXME: To be removed after enough deprecation time */
+ g_warning("Setting SPICE_DEBUG_LEVEL is deprecated, use G_MESSAGES_DEBUG instead");
+ debug_level = atoi(debug_str);
+ if (debug_level > SPICE_LOG_LEVEL_DEBUG) {
+ debug_level = SPICE_LOG_LEVEL_DEBUG;
+ }
+ glib_debug_level = spice_log_level_to_glib(debug_level);
+
+ /* If the debug level is too high, make sure we don't try to enable
+ * display of glib debug logs */
+ if (debug_level < SPICE_LOG_LEVEL_INFO)
+ return;
+
+ /* Make sure GLib default log handler will show the debug messages. Messing with
+ * environment variables like this is ugly, but this only happens when the legacy
+ * SPICE_DEBUG_LEVEL is used
+ */
+ debug_env = (char *)g_getenv("G_MESSAGES_DEBUG");
+ if (debug_env == NULL) {
+ g_setenv("G_MESSAGES_DEBUG", SPICE_LOG_DOMAIN, FALSE);
+ } else {
+ debug_env = g_strconcat(debug_env, ":", SPICE_LOG_DOMAIN, NULL);
+ g_setenv("G_MESSAGES_DEBUG", SPICE_LOG_DOMAIN, FALSE);
+ g_free(debug_env);
+ }
+ }
+ }
+}
+
+static void spice_log_set_abort_level(void)
+{
+ if (abort_level == -1) {
+ const char *abort_str = g_getenv("SPICE_ABORT_LEVEL");
+ if (abort_str != NULL) {
+ GLogLevelFlags glib_abort_level;
+
+ /* FIXME: To be removed after enough deprecation time */
+ g_warning("Setting SPICE_ABORT_LEVEL is deprecated, use G_DEBUG instead");
+ abort_level = atoi(abort_str);
+ glib_abort_level = spice_log_level_to_glib(abort_level);
+ if (glib_abort_level != 0) {
+ unsigned int fatal_mask = G_LOG_FATAL_MASK;
+ while (glib_abort_level >= G_LOG_LEVEL_ERROR) {
+ fatal_mask |= glib_abort_level;
+ glib_abort_level >>= 1;
+ }
+ g_log_set_fatal_mask(SPICE_LOG_DOMAIN, fatal_mask);
+ }
+ } else {
+ abort_level = SPICE_ABORT_LEVEL_DEFAULT;
+ }
+ }
+}
+
+static void spice_logger(const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ if (glib_debug_level != 0) {
+ if ((log_level & G_LOG_LEVEL_MASK) > glib_debug_level)
+ return; // do not print anything
+ }
+ g_log_default_handler(log_domain, log_level, message, NULL);
+}
+
+SPICE_CONSTRUCTOR_FUNC(spice_log_init)
+{
+
+ spice_log_set_debug_level();
+ spice_log_set_abort_level();
+ g_log_set_handler(SPICE_LOG_DOMAIN,
+ G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION,
+ spice_logger, NULL);
+ /* Threading is always enabled from 2.31.0 onwards */
+ /* Our logging is potentially used from different threads.
+ * Older glibs require that g_thread_init() is called when
+ * doing that. */
+#if !GLIB_CHECK_VERSION(2, 31, 0)
+ if (!g_thread_supported())
+ g_thread_init(NULL);
+#endif
+}
+
+static void spice_logv(const char *log_domain,
+ SpiceLogLevel log_level,
+ const char *strloc,
+ const char *function,
+ const char *format,
+ va_list args)
+{
+ GString *log_msg;
+
+ g_return_if_fail(spice_log_level_to_glib(log_level) != 0);
+
+ log_msg = g_string_new(NULL);
+ if (strloc && function) {
+ g_string_append_printf(log_msg, "%s:%s: ", strloc, function);
+ }
+ if (format) {
+ g_string_append_vprintf(log_msg, format, args);
+ }
+ g_log(log_domain, spice_log_level_to_glib(log_level), "%s", log_msg->str);
+ g_string_free(log_msg, TRUE);
+
+ if (abort_level != -1 && abort_level >= (int) log_level) {
+ spice_backtrace();
+ abort();
+ }
+}
+
+void spice_log(const char *log_domain,
+ SpiceLogLevel log_level,
+ const char *strloc,
+ const char *function,
+ const char *format,
+ ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ spice_logv (log_domain, log_level, strloc, function, format, args);
+ va_end (args);
+}
--- /dev/null
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef H_SPICE_LOG
+#define H_SPICE_LOG
+
+#include <glib.h>
+
+#include <spice/macros.h>
+#include <stdarg.h>
+#include "macros.h"
+
+SPICE_BEGIN_DECLS
+
+#ifndef SPICE_LOG_DOMAIN
+#define SPICE_LOG_DOMAIN "Spice"
+#endif
+
+#define SPICE_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__)
+
+typedef enum {
+ SPICE_LOG_LEVEL_ERROR,
+ SPICE_LOG_LEVEL_CRITICAL,
+ SPICE_LOG_LEVEL_WARNING,
+ SPICE_LOG_LEVEL_INFO,
+ SPICE_LOG_LEVEL_DEBUG,
+} SpiceLogLevel;
+
+void spice_log(const char *log_domain,
+ SpiceLogLevel log_level,
+ const char *strloc,
+ const char *function,
+ const char *format,
+ ...) SPICE_ATTR_PRINTF(5, 6);
+
+#define spice_return_if_fail(x) G_STMT_START { \
+ if G_LIKELY(x) { } else { \
+ spice_log(SPICE_LOG_DOMAIN, SPICE_LOG_LEVEL_CRITICAL, SPICE_STRLOC, G_STRFUNC, "condition `%s' failed", #x); \
+ return; \
+ } \
+} G_STMT_END
+
+#define spice_return_val_if_fail(x, val) G_STMT_START { \
+ if G_LIKELY(x) { } else { \
+ spice_log(SPICE_LOG_DOMAIN, SPICE_LOG_LEVEL_CRITICAL, SPICE_STRLOC, __FUNCTION__, "condition `%s' failed", #x); \
+ return (val); \
+ } \
+} G_STMT_END
+
+#define spice_warn_if_reached() G_STMT_START { \
+ spice_log(SPICE_LOG_DOMAIN, SPICE_LOG_LEVEL_WARNING, SPICE_STRLOC, __FUNCTION__, "should not be reached"); \
+} G_STMT_END
+
+#define spice_printerr(format, ...) G_STMT_START { \
+ fprintf(stderr, "%s: " format "\n", __FUNCTION__, ## __VA_ARGS__); \
+} G_STMT_END
+
+#define spice_info(format, ...) G_STMT_START { \
+ spice_log(SPICE_LOG_DOMAIN, SPICE_LOG_LEVEL_INFO, SPICE_STRLOC, __FUNCTION__, format, ## __VA_ARGS__); \
+} G_STMT_END
+
+#define spice_debug(format, ...) G_STMT_START { \
+ spice_log(SPICE_LOG_DOMAIN, SPICE_LOG_LEVEL_DEBUG, SPICE_STRLOC, __FUNCTION__, format, ## __VA_ARGS__); \
+} G_STMT_END
+
+#define spice_warning(format, ...) G_STMT_START { \
+ spice_log(SPICE_LOG_DOMAIN, SPICE_LOG_LEVEL_WARNING, SPICE_STRLOC, __FUNCTION__, format, ## __VA_ARGS__); \
+} G_STMT_END
+
+#define spice_critical(format, ...) G_STMT_START { \
+ spice_log(SPICE_LOG_DOMAIN, SPICE_LOG_LEVEL_CRITICAL, SPICE_STRLOC, __FUNCTION__, format, ## __VA_ARGS__); \
+} G_STMT_END
+
+#define spice_error(format, ...) G_STMT_START { \
+ spice_log(SPICE_LOG_DOMAIN, SPICE_LOG_LEVEL_ERROR, SPICE_STRLOC, __FUNCTION__, format, ## __VA_ARGS__); \
+} G_STMT_END
+
+#define spice_warn_if_fail(x) G_STMT_START { \
+ if G_LIKELY(x) { } else { \
+ spice_warning("condition `%s' failed", #x); \
+ } \
+} G_STMT_END
+
+#define spice_assert(x) G_STMT_START { \
+ if G_LIKELY(x) { } else { \
+ spice_error("assertion `%s' failed", #x); \
+ } \
+} G_STMT_END
+
+/* FIXME: improve that some day.. */
+#define spice_static_assert(x) SPICE_STMT_START { \
+ spice_assert(x); \
+} SPICE_STMT_END
+
+SPICE_END_DECLS
+
+#endif /* H_SPICE_LOG */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+
+ Copyright (C) 2009 Red Hat, Inc. and/or its affiliates.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+ This file incorporates work covered by the following copyright and
+ permission notice:
+ Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
+ Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use, copy,
+ modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "spice_common.h"
+#include "lz.h"
+
+#define HASH_LOG 13
+#define HASH_SIZE (1 << HASH_LOG)
+#define HASH_MASK (HASH_SIZE - 1)
+
+
+typedef struct LzImageSegment LzImageSegment;
+struct LzImageSegment {
+ uint8_t *lines;
+ uint8_t *lines_end;
+ unsigned int size_delta; // total size of the previous segments in units of
+ // pixels for rgb and bytes for plt.
+ LzImageSegment *next;
+};
+
+// TODO: pack?
+typedef struct HashEntry {
+ LzImageSegment *image_seg;
+ uint8_t *ref;
+} HashEntry;
+
+typedef struct Encoder {
+ LzUsrContext *usr;
+
+ LzImageType type;
+ const SpicePalette *palette; // for decoding images with palettes to rgb
+ int stride; // stride is in bytes. For rgb must be equal to
+ // width*bytes_per_pix.
+ // For palettes stride can be bigger than width/pixels_per_byte by 1 only if
+ // width%pixels_per_byte != 0.
+ int height;
+ int width; // the original width (in pixels)
+
+ LzImageSegment *head_image_segs;
+ LzImageSegment *tail_image_segs;
+ LzImageSegment *free_image_segs;
+
+ // the dictionary hash table is composed (1) a pointer to the segment the word was found in
+ // (2) a pointer to the first byte in the segment that matches the word
+ HashEntry htab[HASH_SIZE];
+
+ uint8_t *io_start;
+ uint8_t *io_now;
+ uint8_t *io_end;
+ size_t io_bytes_count;
+
+ uint8_t *io_last_copy; // pointer to the last byte in which copy count was written
+} Encoder;
+
+/****************************************************/
+/* functions for managing the pool of image segments*/
+/****************************************************/
+static inline LzImageSegment *lz_alloc_image_seg(Encoder *encoder);
+static void lz_reset_image_seg(Encoder *encoder);
+static int lz_read_image_segments(Encoder *encoder, uint8_t *first_lines,
+ unsigned int num_first_lines);
+
+
+// return a free image segment if one exists. Make allocation if needed. adds it to the
+// tail of the image segments lists
+static inline LzImageSegment *lz_alloc_image_seg(Encoder *encoder)
+{
+ LzImageSegment *ret;
+
+ if (encoder->free_image_segs) {
+ ret = encoder->free_image_segs;
+ encoder->free_image_segs = ret->next;
+ } else {
+ if (!(ret = (LzImageSegment *)encoder->usr->malloc(encoder->usr, sizeof(*ret)))) {
+ return NULL;
+ }
+ }
+
+ ret->next = NULL;
+ if (encoder->tail_image_segs) {
+ encoder->tail_image_segs->next = ret;
+ }
+ encoder->tail_image_segs = ret;
+
+ if (!encoder->head_image_segs) {
+ encoder->head_image_segs = ret;
+ }
+
+ return ret;
+}
+
+// adding seg to the head of free segments (lz_reset_image_seg removes it from used ones)
+static inline void __lz_free_image_seg(Encoder *encoder, LzImageSegment *seg)
+{
+ seg->next = encoder->free_image_segs;
+ encoder->free_image_segs = seg;
+}
+
+// moves all the used image segments to the free pool
+static void lz_reset_image_seg(Encoder *encoder)
+{
+ while (encoder->head_image_segs) {
+ LzImageSegment *seg = encoder->head_image_segs;
+ encoder->head_image_segs = seg->next;
+ __lz_free_image_seg(encoder, seg);
+ }
+ encoder->tail_image_segs = NULL;
+}
+
+static void lz_dealloc_free_segments(Encoder *encoder)
+{
+ while (encoder->free_image_segs) {
+ LzImageSegment *seg = encoder->free_image_segs;
+ encoder->free_image_segs = seg->next;
+ encoder->usr->free(encoder->usr, seg);
+ }
+}
+
+// return FALSE when operation fails (due to failure in allocation)
+static int lz_read_image_segments(Encoder *encoder, uint8_t *first_lines,
+ unsigned int num_first_lines)
+{
+ LzImageSegment *image_seg;
+ uint32_t size_delta = 0;
+ unsigned int num_lines = num_first_lines;
+ uint8_t* lines = first_lines;
+ int row;
+
+ spice_return_val_if_fail(!encoder->head_image_segs, FALSE);
+
+ image_seg = lz_alloc_image_seg(encoder);
+ if (!image_seg) {
+ goto error_1;
+ }
+
+ image_seg->lines = lines;
+ image_seg->lines_end = lines + num_lines * encoder->stride;
+ image_seg->size_delta = size_delta;
+
+ size_delta += num_lines * encoder->stride / RGB_BYTES_PER_PIXEL[encoder->type];
+
+ for (row = num_first_lines; row < encoder->height; row += num_lines) {
+ num_lines = encoder->usr->more_lines(encoder->usr, &lines);
+ if (num_lines <= 0) {
+ encoder->usr->error(encoder->usr, "more lines failed\n");
+ }
+ image_seg = lz_alloc_image_seg(encoder);
+
+ if (!image_seg) {
+ goto error_1;
+ }
+
+ image_seg->lines = lines;
+ image_seg->lines_end = lines + num_lines * encoder->stride;
+ image_seg->size_delta = size_delta;
+
+ size_delta += num_lines * encoder->stride / RGB_BYTES_PER_PIXEL[encoder->type];
+ }
+
+ return TRUE;
+error_1:
+ lz_reset_image_seg(encoder);
+ return FALSE;
+}
+
+/**************************************************************************
+* Handling encoding and decoding of a byte
+***************************************************************************/
+static inline int more_io_bytes(Encoder *encoder)
+{
+ uint8_t *io_ptr;
+ int num_io_bytes = encoder->usr->more_space(encoder->usr, &io_ptr);
+ encoder->io_bytes_count += num_io_bytes;
+ encoder->io_now = io_ptr;
+ encoder->io_end = encoder->io_now + num_io_bytes;
+ return num_io_bytes;
+}
+
+static inline void encode(Encoder *encoder, uint8_t byte)
+{
+ if (encoder->io_now == encoder->io_end) {
+ if (more_io_bytes(encoder) <= 0) {
+ encoder->usr->error(encoder->usr, "%s: no more bytes\n", __FUNCTION__);
+ }
+ spice_return_if_fail(encoder->io_now);
+ }
+
+ spice_return_if_fail(encoder->io_now < encoder->io_end);
+ *(encoder->io_now++) = byte;
+}
+
+static inline void encode_32(Encoder *encoder, unsigned int word)
+{
+ encode(encoder, (uint8_t)(word >> 24));
+ encode(encoder, (uint8_t)(word >> 16) & 0x0000ff);
+ encode(encoder, (uint8_t)(word >> 8) & 0x0000ff);
+ encode(encoder, (uint8_t)(word & 0x0000ff));
+}
+
+static inline void encode_copy_count(Encoder *encoder, uint8_t copy_count)
+{
+ encode(encoder, copy_count);
+ encoder->io_last_copy = encoder->io_now - 1; // io_now cannot be the first byte of the buffer
+}
+
+static inline void update_copy_count(Encoder *encoder, uint8_t copy_count)
+{
+ spice_return_if_fail(encoder->io_last_copy);
+ *(encoder->io_last_copy) = copy_count;
+}
+
+static inline void encode_level(Encoder *encoder, uint8_t level_code)
+{
+ *(encoder->io_start) |= level_code;
+}
+
+// decrease the io ptr by 1
+static inline void compress_output_prev(Encoder *encoder)
+{
+ // io_now cannot be the first byte of the buffer
+ encoder->io_now--;
+ // the function should be called only when copy count is written unnecessarily by lz_compress
+ spice_return_if_fail(encoder->io_now == encoder->io_last_copy);
+}
+
+static int encoder_reset(Encoder *encoder, uint8_t *io_ptr, uint8_t *io_ptr_end)
+{
+ spice_return_val_if_fail(io_ptr <= io_ptr_end, FALSE);
+
+ encoder->io_bytes_count = io_ptr_end - io_ptr;
+ encoder->io_start = io_ptr;
+ encoder->io_now = io_ptr;
+ encoder->io_end = io_ptr_end;
+ encoder->io_last_copy = NULL;
+
+ return TRUE;
+}
+
+static inline uint8_t decode(Encoder *encoder)
+{
+ if (encoder->io_now == encoder->io_end) {
+ int num_io_bytes = more_io_bytes(encoder);
+ if (num_io_bytes <= 0) {
+ encoder->usr->error(encoder->usr, "%s: no more bytes\n", __FUNCTION__);
+ }
+ spice_assert(encoder->io_now);
+ }
+ spice_assert(encoder->io_now < encoder->io_end);
+ return *(encoder->io_now++);
+}
+
+static inline uint32_t decode_32(Encoder *encoder)
+{
+ uint32_t word = 0;
+ word |= decode(encoder);
+ word <<= 8;
+ word |= decode(encoder);
+ word <<= 8;
+ word |= decode(encoder);
+ word <<= 8;
+ word |= decode(encoder);
+ return word;
+}
+
+static inline int is_io_to_decode_end(Encoder *encoder)
+{
+ if (encoder->io_now != encoder->io_end) {
+ return FALSE;
+ } else {
+ int num_io_bytes = more_io_bytes(encoder); //disable inline optimizations
+ return (num_io_bytes <= 0);
+ }
+}
+
+/*******************************************************************
+* intialization and finalization of lz
+********************************************************************/
+static int init_encoder(Encoder *encoder, LzUsrContext *usr)
+{
+ encoder->usr = usr;
+ encoder->free_image_segs = NULL;
+ encoder->head_image_segs = NULL;
+ encoder->tail_image_segs = NULL;
+ return TRUE;
+}
+
+LzContext *lz_create(LzUsrContext *usr)
+{
+ Encoder *encoder;
+
+ if (!usr || !usr->error || !usr->warn || !usr->info || !usr->malloc ||
+ !usr->free || !usr->more_space || !usr->more_lines) {
+ return NULL;
+ }
+
+ if (!(encoder = (Encoder *)usr->malloc(usr, sizeof(Encoder)))) {
+ return NULL;
+ }
+
+ if (!init_encoder(encoder, usr)) {
+ usr->free(usr, encoder);
+ return NULL;
+ }
+ return (LzContext *)encoder;
+}
+
+void lz_destroy(LzContext *lz)
+{
+ Encoder *encoder = (Encoder *)lz;
+
+ if (!lz) {
+ return;
+ }
+
+ if (encoder->head_image_segs) {
+ encoder->usr->error(encoder->usr, "%s: used_image_segments not empty\n", __FUNCTION__);
+ lz_reset_image_seg(encoder);
+ }
+ lz_dealloc_free_segments(encoder);
+
+ encoder->usr->free(encoder->usr, encoder);
+}
+
+/*******************************************************************
+* encoding and decoding the image
+********************************************************************/
+/*
+ * Give hints to the compiler for branch prediction optimization.
+ */
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#define LZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
+#define LZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
+#else
+#define LZ_EXPECT_CONDITIONAL(c) (c)
+#define LZ_UNEXPECT_CONDITIONAL(c) (c)
+#endif
+
+
+#ifdef __GNUC__
+#define ATTR_PACKED __attribute__ ((__packed__))
+#else
+#define ATTR_PACKED
+#pragma pack(push)
+#pragma pack(1)
+#endif
+
+
+/* the palette images will be treated as one byte pixels. Their width should be transformed
+ accordingly.
+*/
+typedef struct ATTR_PACKED one_byte_pixel_t {
+ uint8_t a;
+} one_byte_pixel_t;
+
+typedef struct ATTR_PACKED rgb32_pixel_t {
+ uint8_t b;
+ uint8_t g;
+ uint8_t r;
+ uint8_t pad;
+} rgb32_pixel_t;
+
+typedef struct ATTR_PACKED rgb24_pixel_t {
+ uint8_t b;
+ uint8_t g;
+ uint8_t r;
+} rgb24_pixel_t;
+
+typedef uint16_t rgb16_pixel_t;
+
+#ifndef __GNUC__
+#pragma pack(pop)
+#endif
+
+#undef ATTR_PACKED
+
+
+#define MAX_COPY 32
+#define MAX_LEN 264 /* 256 + 8 */
+#define BOUND_OFFSET 2
+#define LIMIT_OFFSET 6
+#define MIN_FILE_SIZE 4
+#define COMP_LEVEL_SIZE_LIMIT 65536
+
+// TODO: implemented lz2. should lz1 be an option (no RLE + distance limitation of MAX_DISTANCE)
+// TODO: I think MAX_FARDISTANCE can be changed easily to 2^29
+// (and maybe even more when pixel > byte).
+// i.e. we can support 512M Bytes/Pixels distance instead of only ~68K.
+#define MAX_DISTANCE 8191 // 2^13
+#define MAX_FARDISTANCE (65535 + MAX_DISTANCE - 1) // ~2^16+2^13
+
+
+#define LZ_PLT
+#include "lz_compress_tmpl.c"
+#define LZ_PLT
+#include "lz_decompress_tmpl.c"
+
+#define LZ_PLT
+#define PLT8
+#define TO_RGB32
+#include "lz_decompress_tmpl.c"
+
+#define LZ_PLT
+#define PLT4_BE
+#define TO_RGB32
+#include "lz_decompress_tmpl.c"
+
+#define LZ_PLT
+#define PLT4_LE
+#define TO_RGB32
+#include "lz_decompress_tmpl.c"
+
+#define LZ_PLT
+#define PLT1_BE
+#define TO_RGB32
+#include "lz_decompress_tmpl.c"
+
+#define LZ_PLT
+#define PLT1_LE
+#define TO_RGB32
+#include "lz_decompress_tmpl.c"
+
+#define LZ_A8
+#include "lz_compress_tmpl.c"
+#define LZ_A8
+#include "lz_decompress_tmpl.c"
+#define LZ_A8
+#define TO_RGB32
+#include "lz_decompress_tmpl.c"
+
+#define LZ_RGB16
+#include "lz_compress_tmpl.c"
+#define LZ_RGB16
+#include "lz_decompress_tmpl.c"
+#define LZ_RGB16
+#define TO_RGB32
+#include "lz_decompress_tmpl.c"
+
+#define LZ_RGB24
+#include "lz_compress_tmpl.c"
+#define LZ_RGB24
+#include "lz_decompress_tmpl.c"
+
+
+#define LZ_RGB32
+#include "lz_compress_tmpl.c"
+#define LZ_RGB32
+#include "lz_decompress_tmpl.c"
+
+#define LZ_RGB_ALPHA
+#include "lz_compress_tmpl.c"
+#define LZ_RGB_ALPHA
+#include "lz_decompress_tmpl.c"
+
+#undef LZ_UNEXPECT_CONDITIONAL
+#undef LZ_EXPECT_CONDITIONAL
+
+int lz_encode(LzContext *lz, LzImageType type, int width, int height, int top_down,
+ uint8_t *lines, unsigned int num_lines, int stride,
+ uint8_t *io_ptr, unsigned int num_io_bytes)
+{
+ Encoder *encoder = (Encoder *)lz;
+ uint8_t *io_ptr_end = io_ptr + num_io_bytes;
+
+ encoder->type = type;
+ encoder->width = width;
+ encoder->height = height;
+ encoder->stride = stride;
+
+ if (IS_IMAGE_TYPE_PLT[encoder->type]) {
+ if (encoder->stride > (width / PLT_PIXELS_PER_BYTE[encoder->type])) {
+ if (((width % PLT_PIXELS_PER_BYTE[encoder->type]) == 0) || (
+ (encoder->stride - (width / PLT_PIXELS_PER_BYTE[encoder->type])) > 1)) {
+ encoder->usr->error(encoder->usr, "stride overflows (plt)\n");
+ }
+ }
+ } else {
+ if (encoder->stride != width * RGB_BYTES_PER_PIXEL[encoder->type]) {
+ encoder->usr->error(encoder->usr, "stride != width*bytes_per_pixel (rgb) %d != %d * %d (%d)\n",
+ encoder->stride, width, RGB_BYTES_PER_PIXEL[encoder->type],
+ encoder->type);
+ }
+ }
+
+ // assign the output buffer
+ if (!encoder_reset(encoder, io_ptr, io_ptr_end)) {
+ encoder->usr->error(encoder->usr, "lz encoder io reset failed\n");
+ }
+
+ // first read the list of the image segments
+ if (!lz_read_image_segments(encoder, lines, num_lines)) {
+ encoder->usr->error(encoder->usr, "lz encoder reading image segments failed\n");
+ }
+
+ encode_32(encoder, LZ_MAGIC);
+ encode_32(encoder, LZ_VERSION);
+ encode_32(encoder, type);
+ encode_32(encoder, width);
+ encode_32(encoder, height);
+ encode_32(encoder, stride);
+ encode_32(encoder, top_down); // TODO: maybe compress type and top_down to one byte
+
+ switch (encoder->type) {
+ case LZ_IMAGE_TYPE_PLT1_BE:
+ case LZ_IMAGE_TYPE_PLT1_LE:
+ case LZ_IMAGE_TYPE_PLT4_BE:
+ case LZ_IMAGE_TYPE_PLT4_LE:
+ case LZ_IMAGE_TYPE_PLT8:
+ lz_plt_compress(encoder);
+ break;
+ case LZ_IMAGE_TYPE_RGB16:
+ lz_rgb16_compress(encoder);
+ break;
+ case LZ_IMAGE_TYPE_RGB24:
+ lz_rgb24_compress(encoder);
+ break;
+ case LZ_IMAGE_TYPE_RGB32:
+ lz_rgb32_compress(encoder);
+ break;
+ case LZ_IMAGE_TYPE_RGBA:
+ lz_rgb32_compress(encoder);
+ lz_rgb_alpha_compress(encoder);
+ break;
+ case LZ_IMAGE_TYPE_XXXA:
+ lz_rgb_alpha_compress(encoder);
+ break;
+ case LZ_IMAGE_TYPE_A8:
+ lz_a8_compress(encoder);
+ break;
+ case LZ_IMAGE_TYPE_INVALID:
+ default:
+ encoder->usr->error(encoder->usr, "bad image type\n");
+ }
+
+ // move all the used segments to the free ones
+ lz_reset_image_seg(encoder);
+
+ encoder->io_bytes_count -= (encoder->io_end - encoder->io_now);
+
+ return encoder->io_bytes_count;
+}
+
+/*
+ initialize and read lz magic
+*/
+void lz_decode_begin(LzContext *lz, uint8_t *io_ptr, unsigned int num_io_bytes,
+ LzImageType *out_type, int *out_width, int *out_height,
+ int *out_n_pixels, int *out_top_down, const SpicePalette *palette)
+{
+ Encoder *encoder = (Encoder *)lz;
+ uint8_t *io_ptr_end = io_ptr + num_io_bytes;
+ uint32_t magic;
+ uint32_t version;
+
+ if (!encoder_reset(encoder, io_ptr, io_ptr_end)) {
+ encoder->usr->error(encoder->usr, "io reset failed");
+ }
+
+ magic = decode_32(encoder);
+ if (magic != LZ_MAGIC) {
+ encoder->usr->error(encoder->usr, "bad magic\n");
+ }
+
+ version = decode_32(encoder);
+ if (version != LZ_VERSION) {
+ encoder->usr->error(encoder->usr, "bad version\n");
+ }
+
+ encoder->type = (LzImageType)decode_32(encoder);
+ encoder->width = decode_32(encoder);
+ encoder->height = decode_32(encoder);
+ encoder->stride = decode_32(encoder);
+ *out_top_down = decode_32(encoder);
+
+ *out_width = encoder->width;
+ *out_height = encoder->height;
+// *out_stride = encoder->stride;
+ *out_type = encoder->type;
+
+ // TODO: maybe instead of stride we can encode out_n_pixels
+ // (if stride is not necessary in decoding).
+ if (IS_IMAGE_TYPE_PLT[encoder->type]) {
+ encoder->palette = palette;
+ *out_n_pixels = encoder->stride * PLT_PIXELS_PER_BYTE[encoder->type] * encoder->height;
+ } else {
+ *out_n_pixels = encoder->width * encoder->height;
+ }
+}
+
+void lz_decode(LzContext *lz, LzImageType to_type, uint8_t *buf)
+{
+ Encoder *encoder = (Encoder *)lz;
+ size_t out_size = 0;
+ size_t alpha_size = 0;
+ size_t size = 0;
+ if (IS_IMAGE_TYPE_PLT[encoder->type]) {
+ if (to_type == encoder->type) {
+ size = encoder->height * encoder->stride;
+ out_size = lz_plt_decompress(encoder, (one_byte_pixel_t *)buf, size);
+ } else if (to_type == LZ_IMAGE_TYPE_RGB32) {
+ size = encoder->height * encoder->stride * PLT_PIXELS_PER_BYTE[encoder->type];
+ if (!encoder->palette) {
+ encoder->usr->error(encoder->usr,
+ "a palette is missing (for bpp to rgb decoding)\n");
+ return;
+ }
+ switch (encoder->type) {
+ case LZ_IMAGE_TYPE_PLT1_BE:
+ out_size = lz_plt1_be_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
+ break;
+ case LZ_IMAGE_TYPE_PLT1_LE:
+ out_size = lz_plt1_le_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
+ break;
+ case LZ_IMAGE_TYPE_PLT4_BE:
+ out_size = lz_plt4_be_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
+ break;
+ case LZ_IMAGE_TYPE_PLT4_LE:
+ out_size = lz_plt4_le_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
+ break;
+ case LZ_IMAGE_TYPE_PLT8:
+ out_size = lz_plt8_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
+ break;
+ case LZ_IMAGE_TYPE_RGB16:
+ case LZ_IMAGE_TYPE_RGB24:
+ case LZ_IMAGE_TYPE_RGB32:
+ case LZ_IMAGE_TYPE_RGBA:
+ case LZ_IMAGE_TYPE_XXXA:
+ case LZ_IMAGE_TYPE_INVALID:
+ default:
+ encoder->usr->error(encoder->usr, "bad image type\n");
+ }
+ } else {
+ encoder->usr->error(encoder->usr, "unsupported output format\n");
+ }
+ } else {
+ size = encoder->height * encoder->width;
+ switch (encoder->type) {
+ case LZ_IMAGE_TYPE_RGB16:
+ if (encoder->type == to_type) {
+ out_size = lz_rgb16_decompress(encoder, (rgb16_pixel_t *)buf, size);
+ } else if (to_type == LZ_IMAGE_TYPE_RGB32) {
+ out_size = lz_rgb16_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
+ } else {
+ encoder->usr->error(encoder->usr, "unsupported output format\n");
+ }
+ break;
+ case LZ_IMAGE_TYPE_RGB24:
+ if (encoder->type == to_type) {
+ out_size = lz_rgb24_decompress(encoder, (rgb24_pixel_t *)buf, size);
+ } else if (to_type == LZ_IMAGE_TYPE_RGB32) {
+ out_size = lz_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
+ } else {
+ encoder->usr->error(encoder->usr, "unsupported output format\n");
+ }
+ break;
+ case LZ_IMAGE_TYPE_RGB32:
+ if (encoder->type == to_type) {
+ out_size = lz_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
+ } else {
+ encoder->usr->error(encoder->usr, "unsupported output format\n");
+ }
+ break;
+ case LZ_IMAGE_TYPE_RGBA:
+ if (encoder->type == to_type) {
+ out_size = lz_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
+ alpha_size = lz_rgb_alpha_decompress(encoder, (rgb32_pixel_t *)buf, size);
+ spice_assert(alpha_size == size);
+ } else {
+ encoder->usr->error(encoder->usr, "unsupported output format\n");
+ }
+ break;
+ case LZ_IMAGE_TYPE_XXXA:
+ if (encoder->type == to_type) {
+ alpha_size = lz_rgb_alpha_decompress(encoder, (rgb32_pixel_t *)buf, size);
+ out_size = alpha_size;
+ } else {
+ encoder->usr->error(encoder->usr, "unsupported output format\n");
+ }
+ break;
+ case LZ_IMAGE_TYPE_A8:
+ if (encoder->type == to_type) {
+ alpha_size = lz_a8_decompress(encoder, (one_byte_pixel_t *)buf, size);
+ out_size = alpha_size;
+ } else if (to_type == LZ_IMAGE_TYPE_RGB32) {
+ alpha_size = lz_a8_to_rgb32_decompress(encoder, (rgb32_pixel_t *)buf, size);
+ out_size = alpha_size;
+ } else {
+ encoder->usr->error(encoder->usr, "unsupported output format\n");
+ }
+ break;
+ case LZ_IMAGE_TYPE_PLT1_LE:
+ case LZ_IMAGE_TYPE_PLT1_BE:
+ case LZ_IMAGE_TYPE_PLT4_LE:
+ case LZ_IMAGE_TYPE_PLT4_BE:
+ case LZ_IMAGE_TYPE_PLT8:
+ case LZ_IMAGE_TYPE_INVALID:
+ default:
+ encoder->usr->error(encoder->usr, "bad image type\n");
+ }
+ }
+
+ spice_assert(is_io_to_decode_end(encoder));
+ spice_assert(out_size == size);
+
+ if (out_size != size) {
+ encoder->usr->error(encoder->usr, "bad decode size\n");
+ }
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ dictionary compression for images based on fastlz (http://www.fastlz.org/)
+ (Distributed under MIT license).
+*/
+#ifndef __LZ_H
+#define __LZ_H
+
+#include <spice/macros.h>
+
+#include "lz_common.h"
+#include "lz_config.h"
+#include "draw.h"
+#include "macros.h"
+
+SPICE_BEGIN_DECLS
+
+typedef void *LzContext;
+
+typedef struct LzUsrContext LzUsrContext;
+struct LzUsrContext {
+ SPICE_ATTR_PRINTF(2, 3) void (*error)(LzUsrContext *usr, const char *fmt, ...);
+ SPICE_ATTR_PRINTF(2, 3) void (*warn)(LzUsrContext *usr, const char *fmt, ...);
+ SPICE_ATTR_PRINTF(2, 3) void (*info)(LzUsrContext *usr, const char *fmt, ...);
+ void *(*malloc)(LzUsrContext *usr, int size);
+ void (*free)(LzUsrContext *usr, void *ptr);
+ int (*more_space)(LzUsrContext *usr, uint8_t **io_ptr); // get the next chunk of the
+ // compressed buffer. return
+ // number of bytes in the chunk.
+ int (*more_lines)(LzUsrContext *usr, uint8_t **lines); // get the next chunk of the
+ // original image. If the image
+ // is down to top, return it from
+ // the last line to the first one
+ // (stride should always be
+ // positive)
+};
+
+/*
+ assumes width is in pixels and stride is in bytes
+ return: the number of bytes in the compressed data
+
+ TODO : determine size limit for the first segment and each chunk. check validity
+ of the segment or go to literal copy.
+ TODO : currently support only rgb images in which width*bytes_per_pixel = stride OR
+ palette images in which stride equals the min number of bytes to
+ hold a line. stride is not necessary for now. just for sanity check.
+ stride should be > 0
+*/
+int lz_encode(LzContext *lz, LzImageType type, int width, int height, int top_down,
+ uint8_t *lines, unsigned int num_lines, int stride,
+ uint8_t *io_ptr, unsigned int num_io_bytes);
+
+/*
+ prepare encoder and read lz magic.
+ out_n_pixels number of compressed pixels. May differ from Width*height in plt1/4.
+ Use it for allocation the decompressed buffer.
+
+*/
+void lz_decode_begin(LzContext *lz, uint8_t *io_ptr, unsigned int num_io_bytes,
+ LzImageType *out_type, int *out_width, int *out_height,
+ int *out_n_pixels, int *out_top_down, const SpicePalette *palette);
+
+/*
+ to_type = the image output type.
+ We assume the buffer is consecutive. i.e. width = stride
+
+ Important: if the image is plt1/4 and to_type is rgb32, the image
+ will decompressed including the last bits in each line. This means buffer should be
+ larger than width*height if needed and you should use stride to fix it.
+ Note: If the image is down to top, set the stride in the sw surface to negative.
+ use alloc_lz_image_surface create the surface.
+*/
+void lz_decode(LzContext *lz, LzImageType to_type, uint8_t *buf);
+
+LzContext *lz_create(LzUsrContext *usr);
+
+void lz_destroy(LzContext *lz);
+
+SPICE_END_DECLS
+
+#endif // __LZ_H
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/*common header for encoder and decoder*/
+
+#ifndef _LZ_COMMON_H
+#define _LZ_COMMON_H
+
+#include <spice/macros.h>
+#include "verify.h"
+
+SPICE_BEGIN_DECLS
+
+//#define DEBUG
+
+/* change the max window size will require change in the encoding format*/
+#define LZ_MAX_WINDOW_SIZE (1 << 25)
+#define MAX_COPY 32
+
+typedef enum {
+ LZ_IMAGE_TYPE_INVALID,
+ LZ_IMAGE_TYPE_PLT1_LE,
+ LZ_IMAGE_TYPE_PLT1_BE, // PLT stands for palette
+ LZ_IMAGE_TYPE_PLT4_LE,
+ LZ_IMAGE_TYPE_PLT4_BE,
+ LZ_IMAGE_TYPE_PLT8,
+ LZ_IMAGE_TYPE_RGB16,
+ LZ_IMAGE_TYPE_RGB24,
+ LZ_IMAGE_TYPE_RGB32,
+ LZ_IMAGE_TYPE_RGBA,
+ LZ_IMAGE_TYPE_XXXA,
+ LZ_IMAGE_TYPE_A8
+} LzImageType;
+
+#define LZ_IMAGE_TYPE_MASK 0x0f
+#define LZ_IMAGE_TYPE_LOG 4 // number of bits required for coding the image type
+
+/* access to the arrays is based on the image types */
+static const int IS_IMAGE_TYPE_PLT[] = {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0};
+static const int IS_IMAGE_TYPE_RGB[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1};
+static const int PLT_PIXELS_PER_BYTE[] = {0, 8, 8, 2, 2, 1};
+static const int RGB_BYTES_PER_PIXEL[] = {0, 1, 1, 1, 1, 1, 2, 3, 4, 4, 4, 1};
+
+verify(SPICE_N_ELEMENTS(IS_IMAGE_TYPE_PLT) == (LZ_IMAGE_TYPE_A8 + 1));
+verify(SPICE_N_ELEMENTS(IS_IMAGE_TYPE_RGB) == (LZ_IMAGE_TYPE_A8 + 1));
+verify(SPICE_N_ELEMENTS(PLT_PIXELS_PER_BYTE) == (LZ_IMAGE_TYPE_PLT8 + 1));
+verify(SPICE_N_ELEMENTS(RGB_BYTES_PER_PIXEL) == (LZ_IMAGE_TYPE_A8 + 1));
+
+/* ASCII "LZ " */
+#define LZ_MAGIC 0x20205a4c
+#define LZ_VERSION_MAJOR 1U
+#define LZ_VERSION_MINOR 1U
+#define LZ_VERSION ((LZ_VERSION_MAJOR << 16) | (LZ_VERSION_MINOR & 0xffff))
+
+SPICE_END_DECLS
+
+#endif // _LZ_COMMON_H
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+
+ Copyright (C) 2009 Red Hat, Inc. and/or its affiliates.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ This file incorporates work covered by the following copyright and
+ permission notice:
+ Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
+ Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use, copy,
+ modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define DJB2_START 5381
+#define DJB2_HASH(hash, c) (hash = ((hash << 5) + hash) ^ (c)) //|{hash = ((hash << 5) + hash) + c;}
+
+/*
+ For each pixel type the following macros are defined:
+ PIXEL : input type
+ FNAME(name)
+ ENCODE_PIXEL(encoder, pixel) : writing a pixel to the compressed buffer (byte by byte)
+ SAME_PIXEL(pix1, pix2) : comparing two pixels
+ HASH_FUNC(value, pix_ptr) : hash func of 3 consecutive pixels
+*/
+
+#ifdef LZ_PLT
+#define PIXEL one_byte_pixel_t
+#define FNAME(name) lz_plt_##name
+#define ENCODE_PIXEL(e, pix) encode(e, (pix).a) // gets the pixel and write only the needed bytes
+ // from the pixel
+#define SAME_PIXEL(pix1, pix2) ((pix1).a == (pix2).a)
+#define HASH_FUNC(v, p) { \
+ v = DJB2_START; \
+ DJB2_HASH(v, p[0].a); \
+ DJB2_HASH(v, p[1].a); \
+ DJB2_HASH(v, p[2].a); \
+ v &= HASH_MASK; \
+ }
+#endif
+
+#ifdef LZ_A8
+#define PIXEL one_byte_pixel_t
+#define FNAME(name) lz_a8_##name
+#define ENCODE_PIXEL(e, pix) encode(e, (pix).a) // gets the pixel and write only the needed bytes
+ // from the pixel
+#define SAME_PIXEL(pix1, pix2) ((pix1).a == (pix2).a)
+#define HASH_FUNC(v, p) { \
+ v = DJB2_START; \
+ DJB2_HASH(v, p[0].a); \
+ DJB2_HASH(v, p[1].a); \
+ DJB2_HASH(v, p[2].a); \
+ v &= HASH_MASK; \
+ }
+#endif
+
+#ifdef LZ_RGB_ALPHA
+//#undef LZ_RGB_ALPHA
+#define PIXEL rgb32_pixel_t
+#define FNAME(name) lz_rgb_alpha_##name
+#define ENCODE_PIXEL(e, pix) {encode(e, (pix).pad);}
+#define SAME_PIXEL(pix1, pix2) ((pix1).pad == (pix2).pad)
+#define HASH_FUNC(v, p) { \
+ v = DJB2_START; \
+ DJB2_HASH(v, p[0].pad); \
+ DJB2_HASH(v, p[1].pad); \
+ DJB2_HASH(v, p[2].pad); \
+ v &= HASH_MASK; \
+ }
+#endif
+
+
+#ifdef LZ_RGB16
+#define PIXEL rgb16_pixel_t
+#define FNAME(name) lz_rgb16_##name
+#define GET_r(pix) (((pix) >> 10) & 0x1f)
+#define GET_g(pix) (((pix) >> 5) & 0x1f)
+#define GET_b(pix) ((pix) & 0x1f)
+#define ENCODE_PIXEL(e, pix) {encode(e, (pix) >> 8); encode(e, (pix) & 0xff);}
+
+#define HASH_FUNC(v, p) { \
+ v = DJB2_START; \
+ DJB2_HASH(v, p[0] & (0x00ff)); \
+ DJB2_HASH(v, (p[0] >> 8) & (0x007f)); \
+ DJB2_HASH(v, p[1]&(0x00ff)); \
+ DJB2_HASH(v, (p[1] >> 8) & (0x007f)); \
+ DJB2_HASH(v, p[2] & (0x00ff)); \
+ DJB2_HASH(v, (p[2] >> 8) & (0x007f)); \
+ v &= HASH_MASK; \
+}
+#endif
+
+#ifdef LZ_RGB24
+#define PIXEL rgb24_pixel_t
+#define FNAME(name) lz_rgb24_##name
+#define ENCODE_PIXEL(e, pix) {encode(e, (pix).b); encode(e, (pix).g); encode(e, (pix).r);}
+#endif
+
+#ifdef LZ_RGB32
+#define PIXEL rgb32_pixel_t
+#define FNAME(name) lz_rgb32_##name
+#define ENCODE_PIXEL(e, pix) {encode(e, (pix).b); encode(e, (pix).g); encode(e, (pix).r);}
+#endif
+
+
+#if defined(LZ_RGB24) || defined(LZ_RGB32)
+#define GET_r(pix) ((pix).r)
+#define GET_g(pix) ((pix).g)
+#define GET_b(pix) ((pix).b)
+#define HASH_FUNC(v, p) { \
+ v = DJB2_START; \
+ DJB2_HASH(v, p[0].r); \
+ DJB2_HASH(v, p[0].g); \
+ DJB2_HASH(v, p[0].b); \
+ DJB2_HASH(v, p[1].r); \
+ DJB2_HASH(v, p[1].g); \
+ DJB2_HASH(v, p[1].b); \
+ DJB2_HASH(v, p[2].r); \
+ DJB2_HASH(v, p[2].g); \
+ DJB2_HASH(v, p[2].b); \
+ v &= HASH_MASK; \
+ }
+#endif
+
+#if defined(LZ_RGB16) || defined(LZ_RGB24) || defined(LZ_RGB32)
+#define SAME_PIXEL(p1, p2) (GET_r(p1) == GET_r(p2) && GET_g(p1) == GET_g(p2) && \
+ GET_b(p1) == GET_b(p2))
+
+#endif
+
+#define PIXEL_ID(pix_ptr, seg_ptr) (pix_ptr - ((PIXEL *)seg_ptr->lines) + seg_ptr->size_delta)
+
+// when encoding, the ref can be in previous segment, and we should check that it doesn't
+// exceeds its bounds.
+// TODO: optimization: when only one chunk exists or when the reference is in the same segment,
+// don't make checks if we reach end of segments
+// TODO: optimize to continue match between segments?
+// TODO: check hash function
+// TODO: check times
+
+/* compresses one segment starting from 'from'.*/
+static void FNAME(compress_seg)(Encoder *encoder, LzImageSegment *seg, PIXEL *from, int copied)
+{
+ const PIXEL *ip = from;
+ const PIXEL *ip_bound = (PIXEL *)(seg->lines_end) - BOUND_OFFSET;
+ const PIXEL *ip_limit = (PIXEL *)(seg->lines_end) - LIMIT_OFFSET;
+ HashEntry *hslot;
+ int hval;
+ int copy = copied;
+
+ if (copy == 0) {
+ encode_copy_count(encoder, MAX_COPY - 1);
+ }
+
+
+ while (LZ_EXPECT_CONDITIONAL(ip < ip_limit)) { // TODO: maybe change ip_limit and enabling
+ // moving to the next seg
+ const PIXEL *ref;
+ const PIXEL *ref_limit;
+ size_t distance;
+
+ /* minimum match length */
+#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_A8)
+ size_t len = 3;
+#elif defined(LZ_RGB16)
+ size_t len = 2;
+#else
+ size_t len = 1;
+#endif
+ /* comparison starting-point */
+ const PIXEL *anchor = ip;
+
+
+
+ // TODO: RLE without checking if not first byte.
+ // TODO: optimize comparisons
+
+ /* check for a run */ // TODO for RGB we can use less pixels
+ if (LZ_EXPECT_CONDITIONAL(ip > (PIXEL *)(seg->lines))) {
+ if (SAME_PIXEL(ip[-1], ip[0]) && SAME_PIXEL(ip[0], ip[1]) && SAME_PIXEL(ip[1], ip[2])) {
+ distance = 1;
+ ip += 3;
+ ref = anchor + 2;
+ ref_limit = (PIXEL *)(seg->lines_end);
+
+ goto match;
+ }
+ }
+
+ /* find potential match */
+ HASH_FUNC(hval, ip);
+ hslot = encoder->htab + hval;
+ ref = (PIXEL *)(hslot->ref);
+ ref_limit = (PIXEL *)(hslot->image_seg->lines_end);
+
+ /* calculate distance to the match */
+ distance = PIXEL_ID(anchor, seg) - PIXEL_ID(ref, hslot->image_seg);
+
+ /* update hash table */
+ hslot->image_seg = seg;
+ hslot->ref = (uint8_t *)anchor;
+
+ /* is this a match? check the first 3 pixels */
+ if (distance == 0 || (distance >= MAX_FARDISTANCE)) {
+ goto literal;
+ }
+ /* check if the hval key identical*/
+ // no need to check ref limit here because the word size in the htab is 3 pixels
+ if (!SAME_PIXEL(*ref, *ip)) {
+ ref++;
+ ip++;
+ goto literal;
+ }
+ ref++;
+ ip++;
+
+ /* minimum match length for rgb16 is 2 and for plt and alpha is 3 */
+#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_RGB16) || defined(LZ_A8)
+ if (!SAME_PIXEL(*ref, *ip)) {
+ ref++;
+ ip++;
+ goto literal;
+ }
+ ref++;
+ ip++;
+#endif
+
+#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_A8)
+ if (!SAME_PIXEL(*ref, *ip)) {
+ ref++;
+ ip++;
+ goto literal;
+ }
+ ref++;
+ ip++;
+#endif
+ /* far, needs at least 5-byte match */
+ if (distance >= MAX_DISTANCE) {
+#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_A8)
+ if (ref >= (ref_limit - 1)) {
+ goto literal;
+ }
+#else
+ if (ref > (ref_limit - 1)) {
+ goto literal;
+ }
+#endif
+ if (!SAME_PIXEL(*ref, *ip)) {
+ ref++;
+ ip++;
+ goto literal;
+ }
+ ref++;
+ ip++;
+ len++;
+#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_A8)
+ if (!SAME_PIXEL(*ref, *ip)) {
+ ref++;
+ ip++;
+ goto literal;
+ }
+ ref++;
+ ip++;
+ len++;
+#endif
+ }
+match: // RLE or dictionary (both are encoded by distance from ref (-1) and length)
+
+ /* distance is biased */
+ distance--;
+
+ // ip is located now at the position of the second mismatch.
+ // later it will be subtracted by 3
+
+ if (!distance) {
+ /* zero distance means a run */
+ PIXEL x = *ref;
+ while ((ip < ip_bound) && (ref < ref_limit)) { // TODO: maybe separate a run from
+ // the same seg or from different
+ // ones in order to spare
+ // ref < ref_limit
+ if (!SAME_PIXEL(*ref, x)) {
+ ref++;
+ break;
+ } else {
+ ref++;
+ ip++;
+ }
+ }
+ } else {
+ // TODO: maybe separate a run from the same seg or from different ones in order
+ // to spare ref < ref_limit and that way we can also perform 8 calls of
+ // (ref++ != ip++) outside a loop
+ while ((ip < ip_bound) && (ref < ref_limit)) {
+ if (!SAME_PIXEL(*ref, *ip)) {
+ ref++;
+ ip++;
+ break;
+ } else {
+ ref++;
+ ip++;
+ }
+ }
+ }
+
+ /* if we have copied something, adjust the copy count */
+ if (copy) {
+ /* copy is biased, '0' means 1 byte copy */
+ update_copy_count(encoder, copy - 1);
+ } else {
+ /* back, to overwrite the copy count */
+ compress_output_prev(encoder);
+ }
+
+ /* reset literal counter */
+ copy = 0;
+
+ /* length is biased, '1' means a match of 3 pixels for PLT and alpha*/
+ /* for RGB 16 1 means 2 */
+ /* for RGB24/32 1 means 1...*/
+ ip -= 3;
+ len = ip - anchor;
+#if defined(LZ_RGB16)
+ len++;
+#elif defined(LZ_RGB24) || defined(LZ_RGB32)
+ len += 2;
+#endif
+ /* encode the match (like fastlz level 2)*/
+ if (distance < MAX_DISTANCE) { // MAX_DISTANCE is 2^13 - 1
+ // when copy is performed, the byte that holds the copy count is smaller than 32.
+ // When there is a reference, the first byte is always larger then 32
+
+ // 3 bits = length, 5 bits = 5 MSB of distance, 8 bits = 8 LSB of distance
+ if (len < 7) {
+ encode(encoder, (uint8_t)((len << 5) + (distance >> 8)));
+ encode(encoder, (uint8_t)(distance & 255));
+ } else { // more than 3 bits are needed for length
+ // 3 bits 7, 5 bits = 5 MSB of distance, next bytes are 255 till we
+ // receive a smaller number, last byte = 8 LSB of distance
+ encode(encoder, (uint8_t)((7 << 5) + (distance >> 8)));
+ for (len -= 7; len >= 255; len -= 255) {
+ encode(encoder, 255);
+ }
+ encode(encoder, (uint8_t)len);
+ encode(encoder, (uint8_t)(distance & 255));
+ }
+ } else {
+ /* far away */
+ if (len < 7) { // the max_far_distance is ~2^16+2^13 so two more bytes are needed
+ // 3 bits = length, 5 bits = 5 MSB of MAX_DISTANCE, 8 bits = 8 LSB of MAX_DISTANCE,
+ // 8 bits = 8 MSB distance-MAX_distance (smaller than 2^16),8 bits=8 LSB of
+ // distance-MAX_distance
+ distance -= MAX_DISTANCE;
+ encode(encoder, (uint8_t)((len << 5) + 31));
+ encode(encoder, (uint8_t)255);
+ encode(encoder, (uint8_t)(distance >> 8));
+ encode(encoder, (uint8_t)(distance & 255));
+ } else {
+ // same as before, but the first byte is followed by the left overs of len
+ distance -= MAX_DISTANCE;
+ encode(encoder, (uint8_t)((7 << 5) + 31));
+ for (len -= 7; len >= 255; len -= 255) {
+ encode(encoder, 255);
+ }
+ encode(encoder, (uint8_t)len);
+ encode(encoder, 255);
+ encode(encoder, (uint8_t)(distance >> 8));
+ encode(encoder, (uint8_t)(distance & 255));
+ }
+ }
+
+ /* update the hash at match boundary */
+#if defined(LZ_RGB16) || defined(LZ_RGB24) || defined(LZ_RGB32)
+ if (ip > anchor)
+#endif
+ {
+ HASH_FUNC(hval, ip);
+ encoder->htab[hval].ref = (uint8_t *)ip;
+ encoder->htab[hval].image_seg = seg;
+ }
+ ip++;
+#if defined(LZ_RGB24) || defined(LZ_RGB32)
+ if (ip > anchor)
+#endif
+ {
+ HASH_FUNC(hval, ip);
+ encoder->htab[hval].ref = (uint8_t *)ip;
+ encoder->htab[hval].image_seg = seg;
+ }
+ ip++;
+ /* assuming literal copy */
+ encode_copy_count(encoder, MAX_COPY - 1);
+ continue;
+
+literal:
+ ENCODE_PIXEL(encoder, *anchor);
+ anchor++;
+ ip = anchor;
+ copy++;
+
+ if (LZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY)) {
+ copy = 0;
+ encode_copy_count(encoder, MAX_COPY - 1);
+ }
+ } // END LOOP (ip < ip_limit)
+
+
+ /* left-over as literal copy */
+ ip_bound++;
+ while (ip <= ip_bound) {
+ ENCODE_PIXEL(encoder, *ip);
+ ip++;
+ copy++;
+ if (copy == MAX_COPY) {
+ copy = 0;
+ encode_copy_count(encoder, MAX_COPY - 1);
+ }
+ }
+
+ /* if we have copied something, adjust the copy length */
+ if (copy) {
+ update_copy_count(encoder, copy - 1);
+ } else {
+ compress_output_prev(encoder); // in case we created a new buffer for copy, check that
+ // red_worker could handle size that do not contain the
+ // ne buffer
+ }
+}
+
+
+/* initializes the hash table. if the file is very small, copies it.
+ copies the first two pixels of the first segment, and sends the segments
+ one by one to compress_seg.
+ the number of bytes compressed are stored inside encoder.
+ */
+static void FNAME(compress)(Encoder *encoder)
+{
+ LzImageSegment *cur_seg = encoder->head_image_segs;
+ HashEntry *hslot;
+ PIXEL *ip;
+
+ // fetch the first image segment that is not too small
+ while (cur_seg && ((((PIXEL *)cur_seg->lines_end) - ((PIXEL *)cur_seg->lines)) < 4)) {
+ // coping the segment
+ if (cur_seg->lines != cur_seg->lines_end) {
+ ip = (PIXEL *)cur_seg->lines;
+ // Note: we assume MAX_COPY > 3
+ encode_copy_count(encoder, (uint8_t)(
+ (((PIXEL *)cur_seg->lines_end) - ((PIXEL *)cur_seg->lines)) - 1));
+ while (ip < (PIXEL *)cur_seg->lines_end) {
+ ENCODE_PIXEL(encoder, *ip);
+ ip++;
+ }
+ }
+ cur_seg = cur_seg->next;
+ }
+
+ if (!cur_seg) {
+ return;
+ }
+
+ ip = (PIXEL *)cur_seg->lines;
+
+ /* initialize hash table */
+ for (hslot = encoder->htab; hslot < encoder->htab + HASH_SIZE; hslot++) {
+ hslot->ref = (uint8_t*)ip;
+ hslot->image_seg = cur_seg;
+ }
+
+ encode_copy_count(encoder, MAX_COPY - 1);
+ ENCODE_PIXEL(encoder, *ip);
+ ip++;
+ ENCODE_PIXEL(encoder, *ip);
+ ip++;
+
+ // compressing the first segment
+ FNAME(compress_seg)(encoder, cur_seg, ip, 2);
+
+ // compressing the next segments
+ for (cur_seg = cur_seg->next; cur_seg; cur_seg = cur_seg->next) {
+ FNAME(compress_seg)(encoder, cur_seg, (PIXEL *)cur_seg->lines, 0);
+ }
+}
+
+#undef FNAME
+#undef PIXEL_ID
+#undef PIXEL
+#undef ENCODE_PIXEL
+#undef SAME_PIXEL
+#undef LZ_READU16
+#undef HASH_FUNC
+#undef BYTES_TO_16
+#undef HASH_FUNC_16
+#undef GET_r
+#undef GET_g
+#undef GET_b
+#undef GET_CODE
+#undef LZ_PLT
+#undef LZ_RGB_ALPHA
+#undef LZ_RGB16
+#undef LZ_RGB24
+#undef LZ_RGB32
+#undef LZ_A8
+#undef HASH_FUNC2
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef __LZ_CONFIG_H
+#define __LZ_CONFIG_H
+
+#include <spice/types.h>
+#include <spice/macros.h>
+
+#ifdef __GNUC__
+#include <string.h>
+#else
+#ifdef QXLDD
+#include <windef.h>
+#include "os_dep.h"
+#else
+#include <stddef.h>
+#include <string.h>
+#endif // QXLDD
+#endif //__GNUC__
+
+#endif //__LZ_CONFIG_H
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+
+ Copyright (C) 2009 Red Hat, Inc. and/or its affiliates.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+ This file incorporates work covered by the following copyright and
+ permission notice:
+ Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
+ Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
+ Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use, copy,
+ modify, merge, publish, distribute, sublicense, and/or sell copies
+ of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
+*/
+
+// External defines: PLT, RGBX/PLTXX/ALPHA, TO_RGB32.
+// If PLT4/1 and TO_RGB32 are defined, we need CAST_PLT_DISTANCE (because then the number of
+// pixels differ from the units used in the compression)
+
+/*
+ For each output pixel type the following macros are defined:
+ OUT_PIXEL - the output pixel type
+ COPY_PIXEL(p, out) - assigns the pixel to the place pointed by out and increases
+ out. Used in RLE. Need special handling because in alpha we
+ copy only the pad byte.
+ COPY_REF_PIXEL(ref, out) - copies the pixel pointed by ref to the pixel pointed by out.
+ Increases ref and out.
+ COPY_COMP_PIXEL(encoder, out) - copies pixel from the compressed buffer to the decompressed
+ buffer. Increases out.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if !defined(LZ_RGB_ALPHA)
+#define COPY_PIXEL(p, out) (*out++ = p)
+#define COPY_REF_PIXEL(ref, out) (*out++ = *ref++)
+#endif
+
+
+// decompressing plt to plt
+#ifdef LZ_PLT
+#ifndef TO_RGB32
+#define OUT_PIXEL one_byte_pixel_t
+#define FNAME(name) lz_plt_##name
+#define COPY_COMP_PIXEL(encoder, out) {out->a = decode(encoder); out++;}
+#else // TO_RGB32
+#define OUT_PIXEL rgb32_pixel_t
+#define COPY_PLT_ENTRY(ent, out) { \
+ (out)->b = ent; \
+ (out)->g = (ent >> 8); \
+ (out)->r = (ent >> 16); \
+ (out)->pad = 0; \
+}
+#ifdef PLT8
+#define FNAME(name) lz_plt8_to_rgb32_##name
+#define COPY_COMP_PIXEL(encoder, out) { \
+ uint32_t rgb = encoder->palette->ents[decode(encoder)]; \
+ COPY_PLT_ENTRY(rgb, out); \
+ out++;}
+#elif defined(PLT4_BE)
+#define FNAME(name) lz_plt4_be_to_rgb32_##name
+#define COPY_COMP_PIXEL(encoder, out){ \
+ uint8_t byte = decode(encoder); \
+ uint32_t rgb = encoder->palette->ents[((byte >> 4) & 0x0f) % (encoder->palette->num_ents)]; \
+ COPY_PLT_ENTRY(rgb, out); \
+ out++; \
+ rgb = encoder->palette->ents[(byte & 0x0f) % (encoder->palette->num_ents)]; \
+ COPY_PLT_ENTRY(rgb, out); \
+ out++; \
+}
+#define CAST_PLT_DISTANCE(dist) (dist*2)
+#elif defined(PLT4_LE)
+#define FNAME(name) lz_plt4_le_to_rgb32_##name
+#define COPY_COMP_PIXEL(encoder, out){ \
+ uint8_t byte = decode(encoder); \
+ uint32_t rgb = encoder->palette->ents[(byte & 0x0f) % (encoder->palette->num_ents)]; \
+ COPY_PLT_ENTRY(rgb, out); \
+ out++; \
+ rgb = encoder->palette->ents[((byte >> 4) & 0x0f) % (encoder->palette->num_ents)]; \
+ COPY_PLT_ENTRY(rgb, out); \
+ out++; \
+}
+#define CAST_PLT_DISTANCE(dist) (dist*2)
+#elif defined(PLT1_BE) // TODO store palette entries for direct access
+#define FNAME(name) lz_plt1_be_to_rgb32_##name
+#define COPY_COMP_PIXEL(encoder, out){ \
+ uint8_t byte = decode(encoder); \
+ int i; \
+ uint32_t fore = encoder->palette->ents[1]; \
+ uint32_t back = encoder->palette->ents[0]; \
+ for (i = 7; i >= 0; i--) \
+ { \
+ if ((byte >> i) & 1) { \
+ COPY_PLT_ENTRY(fore, out); \
+ } else { \
+ COPY_PLT_ENTRY(back, out); \
+ } \
+ out++; \
+ } \
+}
+#define CAST_PLT_DISTANCE(dist) (dist*8)
+#elif defined(PLT1_LE)
+#define FNAME(name) lz_plt1_le_to_rgb32_##name
+#define COPY_COMP_PIXEL(encoder, out){ \
+ uint8_t byte = decode(encoder); \
+ int i; \
+ uint32_t fore = encoder->palette->ents[1]; \
+ uint32_t back = encoder->palette->ents[0]; \
+ for (i = 0; i < 8; i++) \
+ { \
+ if ((byte >> i) & 1) { \
+ COPY_PLT_ENTRY(fore, out); \
+ } else { \
+ COPY_PLT_ENTRY(back, out); \
+ } \
+ out++; \
+ } \
+}
+#define CAST_PLT_DISTANCE(dist) (dist*8)
+#endif // PLT Type
+#endif // TO_RGB32
+#endif
+
+#ifdef LZ_A8
+#ifndef TO_RGB32
+#define OUT_PIXEL one_byte_pixel_t
+#define FNAME(name) lz_a8_##name
+#define COPY_COMP_PIXEL(encoder, out) {out->a = decode(encoder); out++;}
+#else // TO_RGB32
+#define OUT_PIXEL rgb32_pixel_t
+#define FNAME(name) lz_a8_to_rgb32_##name
+#define COPY_COMP_PIXEL(encoder, out) { \
+ (out)->b = (out)->g = (out)->r = 0; \
+ (out)->pad = decode(encoder); \
+ (out)++; \
+ }
+#endif
+#endif
+
+#ifdef LZ_RGB16
+#ifndef TO_RGB32
+#define OUT_PIXEL rgb16_pixel_t
+#define FNAME(name) lz_rgb16_##name
+#define COPY_COMP_PIXEL(e, out) {*out = ((decode(e) << 8) | decode(e)); out++;}
+#else
+#define OUT_PIXEL rgb32_pixel_t
+#define FNAME(name) lz_rgb16_to_rgb32_##name
+#define COPY_COMP_PIXEL(e, out) { \
+ out->r = decode(e); \
+ out->b = decode(e); \
+ out->g = (((out->r) << 6) | ((out->b) >> 2)) & ~0x07; \
+ out->g |= (out->g >> 5); \
+ out->r = ((out->r << 1) & ~0x07)| ((out->r >> 4) & 0x07); \
+ out->b = (out->b << 3) | ((out->b >> 2) & 0x07); \
+ out->pad = 0; \
+ out++; \
+}
+#endif
+#endif
+
+#ifdef LZ_RGB24
+#define OUT_PIXEL rgb24_pixel_t
+#define FNAME(name) lz_rgb24_##name
+#define COPY_COMP_PIXEL(e, out) {out->b = decode(e); out->g = decode(e); out->r = decode(e); out++;}
+#endif
+
+#ifdef LZ_RGB32
+#define OUT_PIXEL rgb32_pixel_t
+#define FNAME(name) lz_rgb32_##name
+#define COPY_COMP_PIXEL(e, out) { \
+ out->b = decode(e); \
+ out->g = decode(e); \
+ out->r = decode(e); \
+ out->pad = 0; \
+ out++; \
+}
+#endif
+
+#ifdef LZ_RGB_ALPHA
+#define OUT_PIXEL rgb32_pixel_t
+#define FNAME(name) lz_rgb_alpha_##name
+#define COPY_PIXEL(p, out) {out->pad = p.pad; out++;}
+#define COPY_REF_PIXEL(ref, out) {out->pad = ref->pad; out++; ref++;}
+#define COPY_COMP_PIXEL(e, out) {out->pad = decode(e); out++;}
+#endif
+
+// return num of bytes in out_buf
+static size_t FNAME(decompress)(Encoder *encoder, OUT_PIXEL *out_buf, int size)
+{
+ OUT_PIXEL *op = out_buf;
+ OUT_PIXEL *op_limit = out_buf + size;
+ uint32_t ctrl = decode(encoder);
+ int loop = TRUE;
+
+ do {
+ const OUT_PIXEL *ref = op;
+ uint32_t len = ctrl >> 5;
+ uint32_t ofs = (ctrl & 31) << 8; // 5 MSb of distance
+
+ if (ctrl >= MAX_COPY) { // reference (dictionary/RLE)
+ /* retrieving the reference and the match length */
+
+ uint8_t code;
+ len--;
+ //ref -= ofs;
+ if (len == 7 - 1) { // match length is bigger than 7
+ do {
+ code = decode(encoder);
+ len += code;
+ } while (code == 255); // remaining of len
+ }
+ code = decode(encoder);
+ ofs += code;
+
+ /* match from 16-bit distance */
+ if (LZ_UNEXPECT_CONDITIONAL(code == 255)) {
+ if (LZ_EXPECT_CONDITIONAL((ofs - code) == (31 << 8))) {
+ ofs = decode(encoder) << 8;
+ ofs += decode(encoder);
+ ofs += MAX_DISTANCE;
+ }
+ }
+
+#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA) || defined(LZ_A8)
+ len += 3; // length is biased by 2 + 1 (fixing bias)
+#elif defined(LZ_RGB16)
+ len += 2; // length is biased by 1 + 1 (fixing bias)
+#else
+ len += 1;
+#endif
+ ofs += 1; // offset is biased by 1 (fixing bias)
+
+#if defined(TO_RGB32)
+#if defined(PLT4_BE) || defined(PLT4_LE) || defined(PLT1_BE) || defined(PLT1_LE)
+ ofs = CAST_PLT_DISTANCE(ofs);
+ len = CAST_PLT_DISTANCE(len);
+#endif
+#endif
+ ref -= ofs;
+
+ spice_assert(op + len <= op_limit);
+ spice_assert(ref + len <= op_limit);
+ spice_assert(ref >= out_buf);
+
+ // TODO: optimize by not calling loop at least 3 times when not PLT_TO_RGB32 (len is
+ // always >=3). in PLT_TO_RGB32 len >= 3*number_of_pixels_per_byte
+
+ /* copying the match*/
+
+ if (ref == (op - 1)) { // run // TODO: this will never be called in PLT4/1_TO_RGB
+ // because the number of pixel copied is larger
+ // then one...
+ /* optimize copy for a run */
+ OUT_PIXEL b = *ref;
+ for (; len; --len) {
+ COPY_PIXEL(b, op);
+ spice_assert(op <= op_limit);
+ }
+ } else {
+ for (; len; --len) {
+ COPY_REF_PIXEL(ref, op);
+ spice_assert(op <= op_limit);
+ }
+ }
+ } else { // copy
+ ctrl++; // copy count is biased by 1
+#if defined(TO_RGB32) && (defined(PLT4_BE) || defined(PLT4_LE) || defined(PLT1_BE) || \
+ defined(PLT1_LE))
+ spice_assert(op + CAST_PLT_DISTANCE(ctrl) <= op_limit);
+#else
+ spice_assert(op + ctrl <= op_limit);
+#endif
+ COPY_COMP_PIXEL(encoder, op);
+
+ spice_assert(op <= op_limit);
+
+ for (--ctrl; ctrl; ctrl--) {
+ COPY_COMP_PIXEL(encoder, op);
+ spice_assert(op <= op_limit);
+ }
+ }
+
+ if (LZ_EXPECT_CONDITIONAL(op < op_limit)) {
+ ctrl = decode(encoder);
+ } else {
+ loop = FALSE;
+ }
+ } while (LZ_EXPECT_CONDITIONAL(loop));
+
+ return (op - out_buf);
+}
+
+#undef LZ_PLT
+#undef PLT8
+#undef PLT4_BE
+#undef PLT4_LE
+#undef PLT1_BE
+#undef PLT1_LE
+#undef LZ_RGB16
+#undef LZ_RGB24
+#undef LZ_RGB32
+#undef LZ_A8
+#undef LZ_RGB_ALPHA
+#undef TO_RGB32
+#undef OUT_PIXEL
+#undef FNAME
+#undef COPY_PIXEL
+#undef COPY_REF_PIXEL
+#undef COPY_COMP_PIXEL
+#undef COPY_PLT_ENTRY
+#undef CAST_PLT_DISTANCE
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __MACROS_H
+#define __MACROS_H
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5)
+#define SPICE_ATTR_NORETURN \
+ __attribute__((noreturn))
+#define SPICE_ATTR_PRINTF(a,b) \
+ __attribute__((format(printf,a,b)))
+#else
+#define SPICE_ATTR_NORETURN
+#define SPICE_ATTR_PRINTF
+#endif /* __GNUC__ */
+
+#ifdef __GNUC__
+#define SPICE_CONSTRUCTOR_FUNC(func_name) \
+ static void __attribute__((constructor)) func_name(void)
+#define SPICE_DESTRUCTOR_FUNC(func_name) \
+ static void __attribute__((destructor)) func_name(void)
+#elif defined(_MSC_VER)
+#define SPICE_CONSTRUCTOR_FUNC(func_name) \
+ static void func_name(void); \
+ static int func_name ## _wrapper(void) { func_name(); return 0; } \
+ __pragma(section(".CRT$XCU",read)) \
+ __declspec(allocate(".CRT$XCU")) static int (* _array ## func_name)(void) = func_name ## _wrapper; \
+ static void func_name(void)
+#define SPICE_DESTRUCTOR_FUNC(func_name) \
+ static void func_name(void); \
+ static int func_name ## _wrapper(void) { func_name(); return 0; } \
+ __pragma(section(".CRT$XPU",read)) \
+ __declspec(allocate(".CRT$XPU")) static int (* _array ## func_name)(void) = func_name ## _wrapper; \
+ static void func_name(void)
+#else
+#error Please implement SPICE_CONSTRUCTOR_FUNC and SPICE_DESTRUCTOR_FUNC for this compiler
+#endif
+
+
+#endif /* __MACROS_H */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "log.h"
+#include "marshaller.h"
+#include "mem.h"
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#ifdef WORDS_BIGENDIAN
+#define write_int8(ptr,v) (*((int8_t *)(ptr)) = v)
+#define write_uint8(ptr,v) (*((uint8_t *)(ptr)) = v)
+#define write_int16(ptr,v) (*((int16_t *)(ptr)) = SPICE_BYTESWAP16((uint16_t)(v)))
+#define write_uint16(ptr,v) (*((uint16_t *)(ptr)) = SPICE_BYTESWAP16((uint16_t)(v)))
+#define write_int32(ptr,v) (*((int32_t *)(ptr)) = SPICE_BYTESWAP32((uint32_t)(v)))
+#define write_uint32(ptr,v) (*((uint32_t *)(ptr)) = SPICE_BYTESWAP32((uint32_t)(v)))
+#define write_int64(ptr,v) (*((int64_t *)(ptr)) = SPICE_BYTESWAP64((uint64_t)(v)))
+#define write_uint64(ptr,v) (*((uint64_t *)(ptr)) = SPICE_BYTESWAP64((uint64_t)(v)))
+#else
+#define write_int8(ptr,v) (*((int8_t *)(ptr)) = v)
+#define write_uint8(ptr,v) (*((uint8_t *)(ptr)) = v)
+#define write_int16(ptr,v) (*((int16_t *)(ptr)) = v)
+#define write_uint16(ptr,v) (*((uint16_t *)(ptr)) = v)
+#define write_int32(ptr,v) (*((int32_t *)(ptr)) = v)
+#define write_uint32(ptr,v) (*((uint32_t *)(ptr)) = v)
+#define write_int64(ptr,v) (*((int64_t *)(ptr)) = v)
+#define write_uint64(ptr,v) (*((uint64_t *)(ptr)) = v)
+#endif
+
+typedef struct {
+ uint8_t *data;
+ size_t len;
+ spice_marshaller_item_free_func free_data;
+ void *opaque;
+} MarshallerItem;
+
+/* Try to fit in 4k page with 2*pointer-size overhead (next ptr and malloc size) */
+#define MARSHALLER_BUFFER_SIZE (4096 - sizeof(void *) * 2)
+
+typedef struct MarshallerBuffer MarshallerBuffer;
+struct MarshallerBuffer {
+ MarshallerBuffer *next;
+ uint8_t data[MARSHALLER_BUFFER_SIZE];
+};
+
+#define N_STATIC_ITEMS 4
+
+typedef struct SpiceMarshallerData SpiceMarshallerData;
+
+typedef struct {
+ SpiceMarshaller *marshaller;
+ int item_nr;
+ int is_64bit;
+ size_t offset;
+} MarshallerRef;
+
+struct SpiceMarshaller {
+ size_t total_size;
+ SpiceMarshallerData *data;
+ SpiceMarshaller *next;
+
+ MarshallerRef pointer_ref;
+
+ int n_items;
+ int items_size; /* number of items available in items */
+ MarshallerItem *items;
+
+ MarshallerItem static_items[N_STATIC_ITEMS];
+ bool has_fd;
+ int fd;
+};
+
+struct SpiceMarshallerData {
+ size_t total_size;
+ size_t base;
+ SpiceMarshaller *marshallers;
+ SpiceMarshaller *last_marshaller;
+
+ size_t current_buffer_position;
+ MarshallerBuffer *current_buffer;
+ MarshallerItem *current_buffer_item;
+ MarshallerBuffer *buffers;
+
+ SpiceMarshaller static_marshaller;
+ MarshallerBuffer static_buffer;
+};
+
+static void spice_marshaller_init(SpiceMarshaller *m,
+ SpiceMarshallerData *data)
+{
+ m->data = data;
+ m->next = NULL;
+ m->total_size = 0;
+ m->pointer_ref.marshaller = NULL;
+ m->n_items = 0;
+ m->items_size = N_STATIC_ITEMS;
+ m->items = m->static_items;
+ m->fd = -1;
+ m->has_fd = false;
+}
+
+SpiceMarshaller *spice_marshaller_new(void)
+{
+ SpiceMarshallerData *d;
+ SpiceMarshaller *m;
+
+ d = spice_new(SpiceMarshallerData, 1);
+
+ d->last_marshaller = d->marshallers = &d->static_marshaller;
+ d->total_size = 0;
+ d->base = 0;
+ d->buffers = &d->static_buffer;
+ d->buffers->next = NULL;
+ d->current_buffer = d->buffers;
+ d->current_buffer_position = 0;
+ d->current_buffer_item = NULL;
+
+ m = &d->static_marshaller;
+ spice_marshaller_init(m, d);
+
+ return m;
+}
+
+static void free_item_data(SpiceMarshaller *m)
+{
+ MarshallerItem *item;
+ int i;
+
+ /* Free all user data */
+ for (i = 0; i < m->n_items; i++) {
+ item = &m->items[i];
+ if (item->free_data != NULL) {
+ item->free_data(item->data, item->opaque);
+ }
+ }
+}
+
+static void free_items(SpiceMarshaller *m)
+{
+ if (m->items != m->static_items) {
+ free(m->items);
+ }
+}
+
+void spice_marshaller_reset(SpiceMarshaller *m)
+{
+ SpiceMarshaller *m2, *next;
+ SpiceMarshallerData *d;
+
+ /* Only supported for root marshaller */
+ assert(m->data->marshallers == m);
+
+ for (m2 = m; m2 != NULL; m2 = next) {
+ next = m2->next;
+ free_item_data(m2);
+
+ /* Free non-root marshallers */
+ if (m2 != m) {
+ free_items(m2);
+ free(m2);
+ }
+ }
+
+ m->next = NULL;
+ m->n_items = 0;
+ m->total_size = 0;
+
+ d = m->data;
+ d->last_marshaller = d->marshallers;
+ d->total_size = 0;
+ d->base = 0;
+ d->current_buffer_item = NULL;
+ d->current_buffer = d->buffers;
+ d->current_buffer_position = 0;
+}
+
+void spice_marshaller_destroy(SpiceMarshaller *m)
+{
+ MarshallerBuffer *buf, *next;
+ SpiceMarshallerData *d;
+
+ /* Only supported for root marshaller */
+ assert(m->data->marshallers == m);
+
+ spice_marshaller_reset(m);
+
+ free_items(m);
+
+ d = m->data;
+
+ buf = d->buffers->next;
+ while (buf != NULL) {
+ next = buf->next;
+ free(buf);
+ buf = next;
+ }
+
+ free(d);
+}
+
+static MarshallerItem *spice_marshaller_add_item(SpiceMarshaller *m)
+{
+ MarshallerItem *item;
+
+ if (m->n_items == m->items_size) {
+ int items_size = m->items_size * 2;
+
+ if (m->items == m->static_items) {
+ m->items = spice_new(MarshallerItem, items_size);
+ memcpy(m->items, m->static_items, sizeof(MarshallerItem) * m->n_items);
+ } else {
+ m->items = spice_renew(MarshallerItem, m->items, items_size);
+ }
+ m->items_size = items_size;
+ }
+ item = &m->items[m->n_items++];
+ item->free_data = NULL;
+
+ return item;
+}
+
+static size_t remaining_buffer_size(SpiceMarshallerData *d)
+{
+ return MARSHALLER_BUFFER_SIZE - d->current_buffer_position;
+}
+
+uint8_t *spice_marshaller_reserve_space(SpiceMarshaller *m, size_t size)
+{
+ MarshallerItem *item;
+ SpiceMarshallerData *d;
+ uint8_t *res;
+
+ if (size == 0) {
+ return NULL;
+ }
+
+ d = m->data;
+
+ /* Check current item */
+ item = &m->items[m->n_items - 1];
+ if (item == d->current_buffer_item &&
+ remaining_buffer_size(d) >= size) {
+ assert(m->n_items >= 1);
+ /* We can piggy back on existing item+buffer */
+ res = item->data + item->len;
+ item->len += size;
+ d->current_buffer_position += size;
+ d->total_size += size;
+ m->total_size += size;
+ return res;
+ }
+
+ item = spice_marshaller_add_item(m);
+
+ if (remaining_buffer_size(d) >= size) {
+ /* Fits in current buffer */
+ item->data = d->current_buffer->data + d->current_buffer_position;
+ item->len = size;
+ d->current_buffer_position += size;
+ d->current_buffer_item = item;
+ } else if (size > MARSHALLER_BUFFER_SIZE / 2) {
+ /* Large item, allocate by itself */
+ item->data = (uint8_t *)spice_malloc(size);
+ item->len = size;
+ item->free_data = (spice_marshaller_item_free_func)free;
+ item->opaque = NULL;
+ } else {
+ /* Use next buffer */
+ if (d->current_buffer->next == NULL) {
+ d->current_buffer->next = spice_new(MarshallerBuffer, 1);
+ d->current_buffer->next->next = NULL;
+ }
+ d->current_buffer = d->current_buffer->next;
+ d->current_buffer_position = size;
+ d->current_buffer_item = item;
+ item->data = d->current_buffer->data;
+ item->len = size;
+ }
+
+ d->total_size += size;
+ m->total_size += size;
+ return item->data;
+}
+
+void spice_marshaller_unreserve_space(SpiceMarshaller *m, size_t size)
+{
+ MarshallerItem *item;
+
+ if (size == 0) {
+ return;
+ }
+
+ item = &m->items[m->n_items - 1];
+
+ assert(item->len >= size);
+ item->len -= size;
+}
+
+uint8_t *spice_marshaller_add_ref_full(SpiceMarshaller *m, uint8_t *data, size_t size,
+ spice_marshaller_item_free_func free_data, void *opaque)
+{
+ MarshallerItem *item;
+ SpiceMarshallerData *d;
+
+ if (data == NULL || size == 0) {
+ return NULL;
+ }
+
+ item = spice_marshaller_add_item(m);
+ item->data = data;
+ item->len = size;
+ item->free_data = free_data;
+ item->opaque = opaque;
+
+ d = m->data;
+ m->total_size += size;
+ d->total_size += size;
+
+ return data;
+}
+
+uint8_t *spice_marshaller_add(SpiceMarshaller *m, const uint8_t *data, size_t size)
+{
+ uint8_t *ptr;
+
+ ptr = spice_marshaller_reserve_space(m, size);
+ memcpy(ptr, data, size);
+ return ptr;
+}
+
+uint8_t *spice_marshaller_add_ref(SpiceMarshaller *m, const uint8_t *data, size_t size)
+{
+ /* the cast to no-const here is safe as data is used for writing only if
+ * free_data pointer is not NULL
+ */
+ return spice_marshaller_add_ref_full(m, (uint8_t *) data, size, NULL, NULL);
+}
+
+void spice_marshaller_add_ref_chunks(SpiceMarshaller *m, SpiceChunks *chunks)
+{
+ unsigned int i;
+
+ for (i = 0; i < chunks->num_chunks; i++) {
+ spice_marshaller_add_ref(m, chunks->chunk[i].data,
+ chunks->chunk[i].len);
+ }
+}
+
+SpiceMarshaller *spice_marshaller_get_submarshaller(SpiceMarshaller *m)
+{
+ SpiceMarshallerData *d;
+ SpiceMarshaller *m2;
+
+ d = m->data;
+
+ m2 = spice_new(SpiceMarshaller, 1);
+ spice_marshaller_init(m2, d);
+
+ d->last_marshaller->next = m2;
+ d->last_marshaller = m2;
+
+ return m2;
+}
+
+SpiceMarshaller *spice_marshaller_get_ptr_submarshaller(SpiceMarshaller *m, int is_64bit)
+{
+ SpiceMarshaller *m2;
+ uint8_t *p;
+ int size;
+
+ size = is_64bit ? 8 : 4;
+
+ p = spice_marshaller_reserve_space(m, size);
+ memset(p, 0, size);
+ m2 = spice_marshaller_get_submarshaller(m);
+ m2->pointer_ref.marshaller = m;
+ m2->pointer_ref.item_nr = m->n_items - 1;
+ m2->pointer_ref.offset = m->items[m->n_items - 1].len - size;
+ m2->pointer_ref.is_64bit = is_64bit;
+
+ return m2;
+}
+
+static uint8_t *lookup_ref(MarshallerRef *ref)
+{
+ MarshallerItem *item;
+
+ item = &ref->marshaller->items[ref->item_nr];
+ return item->data + ref->offset;
+}
+
+
+void spice_marshaller_set_base(SpiceMarshaller *m, size_t base)
+{
+ /* Only supported for root marshaller */
+ assert(m->data->marshallers == m);
+
+ m->data->base = base;
+}
+
+uint8_t *spice_marshaller_linearize(SpiceMarshaller *m, size_t skip_bytes,
+ size_t *len, int *free_res)
+{
+ MarshallerItem *item;
+ uint8_t *res, *p;
+ int i;
+
+ /* Only supported for root marshaller */
+ assert(m->data->marshallers == m);
+
+ if (m->n_items == 1 && m->next == NULL) {
+ *free_res = FALSE;
+ if (m->items[0].len <= skip_bytes) {
+ *len = 0;
+ return NULL;
+ }
+ *len = m->items[0].len - skip_bytes;
+ return m->items[0].data + skip_bytes;
+ }
+
+ *free_res = TRUE;
+ res = (uint8_t *)spice_malloc(m->data->total_size - skip_bytes);
+ *len = m->data->total_size - skip_bytes;
+ p = res;
+
+ do {
+ for (i = 0; i < m->n_items; i++) {
+ item = &m->items[i];
+
+ if (item->len <= skip_bytes) {
+ skip_bytes -= item->len;
+ continue;
+ }
+ memcpy(p, item->data + skip_bytes, item->len - skip_bytes);
+ p += item->len - skip_bytes;
+ skip_bytes = 0;
+ }
+ m = m->next;
+ } while (m != NULL);
+
+ return res;
+}
+
+uint8_t *spice_marshaller_get_ptr(SpiceMarshaller *m)
+{
+ return m->items[0].data;
+}
+
+size_t spice_marshaller_get_offset(SpiceMarshaller *m)
+{
+ SpiceMarshaller *m2;
+ size_t offset;
+
+ offset = 0;
+ m2 = m->data->marshallers;
+ while (m2 != m) {
+ offset += m2->total_size;
+ m2 = m2->next;
+ }
+ return offset - m->data->base;
+}
+
+size_t spice_marshaller_get_size(SpiceMarshaller *m)
+{
+ return m->total_size;
+}
+
+size_t spice_marshaller_get_total_size(SpiceMarshaller *m)
+{
+ return m->data->total_size;
+}
+
+void spice_marshaller_flush(SpiceMarshaller *m)
+{
+ SpiceMarshaller *m2;
+ uint8_t *ptr_pos;
+
+ /* Only supported for root marshaller */
+ assert(m->data->marshallers == m);
+
+ for (m2 = m; m2 != NULL; m2 = m2->next) {
+ if (m2->pointer_ref.marshaller != NULL && m2->total_size > 0) {
+ ptr_pos = lookup_ref(&m2->pointer_ref);
+ if (m2->pointer_ref.is_64bit) {
+ write_uint64(ptr_pos,
+ spice_marshaller_get_offset(m2));
+ } else {
+ write_uint32(ptr_pos,
+ spice_marshaller_get_offset(m2));
+ }
+ }
+ }
+}
+
+#ifndef WIN32
+int spice_marshaller_fill_iovec(SpiceMarshaller *m, struct iovec *vec,
+ int n_vec, size_t skip_bytes)
+{
+ MarshallerItem *item;
+ int v, i;
+
+ /* Only supported for root marshaller */
+ assert(m->data->marshallers == m);
+
+ v = 0;
+ do {
+ for (i = 0; i < m->n_items; i++) {
+ item = &m->items[i];
+
+ if (item->len <= skip_bytes) {
+ skip_bytes -= item->len;
+ continue;
+ }
+ if (v == n_vec) {
+ return v; /* Not enough space in vec */
+ }
+ vec[v].iov_base = (uint8_t *)item->data + skip_bytes;
+ vec[v].iov_len = item->len - skip_bytes;
+ skip_bytes = 0;
+ v++;
+ }
+ m = m->next;
+ } while (m != NULL);
+
+ return v;
+}
+#endif
+
+void *spice_marshaller_add_uint64(SpiceMarshaller *m, uint64_t v)
+{
+ uint8_t *ptr;
+
+ ptr = spice_marshaller_reserve_space(m, sizeof(uint64_t));
+ write_uint64(ptr, v);
+ return (void *)ptr;
+}
+
+void *spice_marshaller_add_int64(SpiceMarshaller *m, int64_t v)
+{
+ uint8_t *ptr;
+
+ ptr = spice_marshaller_reserve_space(m, sizeof(int64_t));
+ write_int64(ptr, v);
+ return (void *)ptr;
+}
+
+void *spice_marshaller_add_uint32(SpiceMarshaller *m, uint32_t v)
+{
+ uint8_t *ptr;
+
+ ptr = spice_marshaller_reserve_space(m, sizeof(uint32_t));
+ write_uint32(ptr, v);
+ return (void *)ptr;
+}
+
+void spice_marshaller_set_uint32(SPICE_GNUC_UNUSED SpiceMarshaller *m, void *ref, uint32_t v)
+{
+ write_uint32((uint8_t *)ref, v);
+}
+
+void *spice_marshaller_add_int32(SpiceMarshaller *m, int32_t v)
+{
+ uint8_t *ptr;
+
+ ptr = spice_marshaller_reserve_space(m, sizeof(int32_t));
+ write_int32(ptr, v);
+ return (void *)ptr;
+}
+
+void *spice_marshaller_add_uint16(SpiceMarshaller *m, uint16_t v)
+{
+ uint8_t *ptr;
+
+ ptr = spice_marshaller_reserve_space(m, sizeof(uint16_t));
+ write_uint16(ptr, v);
+ return (void *)ptr;
+}
+
+void *spice_marshaller_add_int16(SpiceMarshaller *m, int16_t v)
+{
+ uint8_t *ptr;
+
+ ptr = spice_marshaller_reserve_space(m, sizeof(int16_t));
+ write_int16(ptr, v);
+ return (void *)ptr;
+}
+
+void *spice_marshaller_add_uint8(SpiceMarshaller *m, uint8_t v)
+{
+ uint8_t *ptr;
+
+ ptr = spice_marshaller_reserve_space(m, sizeof(uint8_t));
+ write_uint8(ptr, v);
+ return (void *)ptr;
+}
+
+void *spice_marshaller_add_int8(SpiceMarshaller *m, int8_t v)
+{
+ uint8_t *ptr;
+
+ ptr = spice_marshaller_reserve_space(m, sizeof(int8_t));
+ write_int8(ptr, v);
+ return (void *)ptr;
+}
+
+void spice_marshaller_add_fd(SpiceMarshaller *m, int fd)
+{
+ spice_assert(m->has_fd == false);
+
+ m->has_fd = true;
+ if (fd != -1) {
+ m->fd = dup(fd);
+ if (m->fd == -1) {
+ perror("dup");
+ }
+ } else {
+ m->fd = -1;
+ }
+}
+
+bool spice_marshaller_get_fd(SpiceMarshaller *m, int *fd)
+{
+ bool had_fd = m->has_fd;
+
+ *fd = m->fd;
+ m->has_fd = false;
+
+ return had_fd;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_MARSHALLER
+#define _H_MARSHALLER
+
+#include <stdbool.h>
+#include <spice/macros.h>
+#include <spice/types.h>
+#include "mem.h"
+#ifndef WIN32
+#include <sys/uio.h>
+#endif
+
+SPICE_BEGIN_DECLS
+
+typedef struct SpiceMarshaller SpiceMarshaller;
+typedef void (*spice_marshaller_item_free_func)(uint8_t *data, void *opaque);
+
+SpiceMarshaller *spice_marshaller_new(void);
+void spice_marshaller_reset(SpiceMarshaller *m);
+void spice_marshaller_destroy(SpiceMarshaller *m);
+uint8_t *spice_marshaller_reserve_space(SpiceMarshaller *m, size_t size);
+void spice_marshaller_unreserve_space(SpiceMarshaller *m, size_t size);
+uint8_t *spice_marshaller_add(SpiceMarshaller *m, const uint8_t *data, size_t size);
+uint8_t *spice_marshaller_add_ref(SpiceMarshaller *m, const uint8_t *data, size_t size);
+uint8_t *spice_marshaller_add_ref_full(SpiceMarshaller *m, uint8_t *data, size_t size,
+ spice_marshaller_item_free_func free_data, void *opaque);
+void spice_marshaller_add_ref_chunks(SpiceMarshaller *m, SpiceChunks *chunks);
+void spice_marshaller_flush(SpiceMarshaller *m);
+void spice_marshaller_set_base(SpiceMarshaller *m, size_t base);
+uint8_t *spice_marshaller_linearize(SpiceMarshaller *m, size_t skip,
+ size_t *len, int *free_res);
+uint8_t *spice_marshaller_get_ptr(SpiceMarshaller *m);
+size_t spice_marshaller_get_offset(SpiceMarshaller *m);
+size_t spice_marshaller_get_size(SpiceMarshaller *m);
+size_t spice_marshaller_get_total_size(SpiceMarshaller *m);
+SpiceMarshaller *spice_marshaller_get_submarshaller(SpiceMarshaller *m);
+SpiceMarshaller *spice_marshaller_get_ptr_submarshaller(SpiceMarshaller *m, int is_64bit);
+#ifndef WIN32
+int spice_marshaller_fill_iovec(SpiceMarshaller *m, struct iovec *vec,
+ int n_vec, size_t skip_bytes);
+#endif
+void *spice_marshaller_add_uint64(SpiceMarshaller *m, uint64_t v);
+void *spice_marshaller_add_int64(SpiceMarshaller *m, int64_t v);
+void *spice_marshaller_add_uint32(SpiceMarshaller *m, uint32_t v);
+void *spice_marshaller_add_int32(SpiceMarshaller *m, int32_t v);
+void *spice_marshaller_add_uint16(SpiceMarshaller *m, uint16_t v);
+void *spice_marshaller_add_int16(SpiceMarshaller *m, int16_t v);
+void *spice_marshaller_add_uint8(SpiceMarshaller *m, uint8_t v);
+void *spice_marshaller_add_int8(SpiceMarshaller *m, int8_t v);
+
+void spice_marshaller_set_uint32(SpiceMarshaller *m, void *ref, uint32_t v);
+
+void spice_marshaller_add_fd(SpiceMarshaller *m, int fd);
+bool spice_marshaller_get_fd(SpiceMarshaller *m, int *fd);
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "spice_common.h"
+#include "mem.h"
+
+#include <string.h>
+
+#ifndef MALLOC_ERROR
+#define MALLOC_ERROR(format, ...) SPICE_STMT_START { \
+ spice_error(format, ## __VA_ARGS__); \
+ abort(); \
+} SPICE_STMT_END
+#endif
+
+size_t spice_strnlen(const char *str, size_t max_len)
+{
+ size_t len = 0;
+
+ while (len < max_len && *str != 0) {
+ len++;
+ str++;
+ }
+
+ return len;
+}
+
+char *spice_strdup(const char *str)
+{
+ char *copy;
+ size_t len;
+
+ if (str == NULL) {
+ return NULL;
+ }
+
+ len = strlen(str) + 1;
+ copy = (char *)spice_malloc(len);
+ memcpy(copy, str, len);
+ return copy;
+}
+
+char *spice_strndup(const char *str, size_t n_bytes)
+{
+ char *copy;
+
+ if (str == NULL) {
+ return NULL;
+ }
+
+ copy = (char *)spice_malloc(n_bytes + 1);
+ strncpy(copy, str, n_bytes);
+ copy[n_bytes] = 0;
+ return copy;
+}
+
+void *spice_memdup(const void *mem, size_t n_bytes)
+{
+ void *copy;
+
+ if (mem == NULL) {
+ return NULL;
+ }
+
+ copy = spice_malloc(n_bytes);
+ memcpy(copy, mem, n_bytes);
+ return copy;
+}
+
+void *spice_malloc(size_t n_bytes)
+{
+ void *mem;
+
+ if (SPICE_LIKELY(n_bytes)) {
+ mem = malloc(n_bytes);
+
+ if (SPICE_LIKELY(mem != NULL)) {
+ return mem;
+ }
+
+ MALLOC_ERROR("unable to allocate %lu bytes", (unsigned long)n_bytes);
+ }
+ return NULL;
+}
+
+void *spice_malloc0(size_t n_bytes)
+{
+ void *mem;
+
+ if (SPICE_LIKELY(n_bytes)) {
+ mem = calloc(1, n_bytes);
+
+ if (SPICE_LIKELY(mem != NULL)) {
+ return mem;
+ }
+
+ MALLOC_ERROR("unable to allocate %lu bytes", (unsigned long)n_bytes);
+ }
+ return NULL;
+}
+
+void *spice_realloc(void *mem, size_t n_bytes)
+{
+ if (SPICE_LIKELY(n_bytes)) {
+ mem = realloc(mem, n_bytes);
+
+ if (SPICE_LIKELY(mem != NULL)) {
+ return mem;
+ }
+
+ MALLOC_ERROR("unable to allocate %lu bytes", (unsigned long)n_bytes);
+ }
+
+ free(mem);
+
+ return NULL;
+}
+
+#define SIZE_OVERFLOWS(a,b) (SPICE_UNLIKELY ((a) > SIZE_MAX / (b)))
+
+void *spice_malloc_n(size_t n_blocks, size_t n_block_bytes)
+{
+ if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) {
+ MALLOC_ERROR("overflow allocating %lu*%lu bytes",
+ (unsigned long)n_blocks, (unsigned long)n_block_bytes);
+ }
+
+ return spice_malloc(n_blocks * n_block_bytes);
+}
+
+void *spice_malloc_n_m(size_t n_blocks, size_t n_block_bytes, size_t extra_size)
+{
+ size_t size1, size2;
+ if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) {
+ MALLOC_ERROR("spice_malloc_n: overflow allocating %lu*%lu + %lubytes",
+ (unsigned long)n_blocks, (unsigned long)n_block_bytes, (unsigned long)extra_size);
+ }
+ size1 = n_blocks * n_block_bytes;
+ size2 = size1 + extra_size;
+ if (size2 < size1) {
+ MALLOC_ERROR("spice_malloc_n: overflow allocating %lu*%lu + %lubytes",
+ (unsigned long)n_blocks, (unsigned long)n_block_bytes, (unsigned long)extra_size);
+ }
+ return spice_malloc(size2);
+}
+
+
+void *spice_malloc0_n(size_t n_blocks, size_t n_block_bytes)
+{
+ if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) {
+ MALLOC_ERROR("spice_malloc0_n: overflow allocating %lu*%lu bytes",
+ (unsigned long)n_blocks, (unsigned long)n_block_bytes);
+ }
+
+ return spice_malloc0 (n_blocks * n_block_bytes);
+}
+
+void *spice_realloc_n(void *mem, size_t n_blocks, size_t n_block_bytes)
+{
+ if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) {
+ MALLOC_ERROR("spice_realloc_n: overflow allocating %lu*%lu bytes",
+ (unsigned long)n_blocks, (unsigned long)n_block_bytes);
+ }
+
+ return spice_realloc(mem, n_blocks * n_block_bytes);
+}
+
+SpiceChunks *spice_chunks_new(uint32_t count)
+{
+ SpiceChunks *chunks;
+
+ chunks = (SpiceChunks *)spice_malloc_n_m(count, sizeof(SpiceChunk), sizeof(SpiceChunks));
+ chunks->flags = 0;
+ chunks->num_chunks = count;
+
+ return chunks;
+}
+
+SpiceChunks *spice_chunks_new_linear(uint8_t *data, uint32_t len)
+{
+ SpiceChunks *chunks;
+
+ chunks = spice_chunks_new(1);
+ chunks->data_size = chunks->chunk[0].len = len;
+ chunks->chunk[0].data = data;
+ return chunks;
+}
+
+void spice_chunks_destroy(SpiceChunks *chunks)
+{
+ unsigned int i;
+
+ if (chunks->flags & SPICE_CHUNKS_FLAGS_FREE) {
+ for (i = 0; i < chunks->num_chunks; i++) {
+ free(chunks->chunk[i].data);
+ }
+ }
+
+ free(chunks);
+}
+
+void spice_chunks_linearize(SpiceChunks *chunks)
+{
+ uint8_t *data, *p;
+ unsigned int i;
+
+ if (chunks->num_chunks > 1) {
+ data = (uint8_t*)spice_malloc(chunks->data_size);
+ for (p = data, i = 0; i < chunks->num_chunks; i++) {
+ memcpy(p, chunks->chunk[i].data,
+ chunks->chunk[i].len);
+ p += chunks->chunk[i].len;
+ }
+ if (chunks->flags & SPICE_CHUNKS_FLAGS_FREE) {
+ for (i = 0; i < chunks->num_chunks; i++) {
+ free(chunks->chunk[i].data);
+ }
+ }
+ chunks->num_chunks = 1;
+ chunks->flags |= SPICE_CHUNKS_FLAGS_FREE;
+ chunks->flags &= ~SPICE_CHUNKS_FLAGS_UNSTABLE;
+ chunks->chunk[0].data = data;
+ chunks->chunk[0].len = chunks->data_size;
+ }
+}
+
+void spice_buffer_reserve(SpiceBuffer *buffer, size_t len)
+{
+ if ((buffer->capacity - buffer->offset) < len) {
+ buffer->capacity += (len + 1024);
+ buffer->buffer = (uint8_t*)spice_realloc(buffer->buffer, buffer->capacity);
+ }
+}
+
+int spice_buffer_empty(SpiceBuffer *buffer)
+{
+ return buffer->offset == 0;
+}
+
+uint8_t *spice_buffer_end(SpiceBuffer *buffer)
+{
+ return buffer->buffer + buffer->offset;
+}
+
+void spice_buffer_reset(SpiceBuffer *buffer)
+{
+ buffer->offset = 0;
+}
+
+void spice_buffer_free(SpiceBuffer *buffer)
+{
+ free(buffer->buffer);
+ buffer->offset = 0;
+ buffer->capacity = 0;
+ buffer->buffer = NULL;
+}
+
+void spice_buffer_append(SpiceBuffer *buffer, const void *data, size_t len)
+{
+ spice_buffer_reserve(buffer, len);
+ memcpy(buffer->buffer + buffer->offset, data, len);
+ buffer->offset += len;
+}
+
+size_t spice_buffer_copy(SpiceBuffer *buffer, void *dest, size_t len)
+{
+ len = MIN(buffer->offset, len);
+ memcpy(dest, buffer->buffer, len);
+ return len;
+}
+
+size_t spice_buffer_remove(SpiceBuffer *buffer, size_t len)
+{
+ len = MIN(buffer->offset, len);
+ memmove(buffer->buffer, buffer->buffer + len, buffer->offset - len);
+ buffer->offset -= len;
+ return len;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_MEM
+#define _H_MEM
+
+#include <stdlib.h>
+#include <spice/macros.h>
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+SPICE_BEGIN_DECLS
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#elif defined __GNUC__
+#if !defined alloca
+# define alloca __builtin_alloca
+#endif
+#elif defined _AIX
+# define alloca __alloca
+#elif defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+#else
+# ifndef HAVE_ALLOCA
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+# endif
+#endif
+
+typedef struct SpiceChunk {
+ uint8_t *data;
+ uint32_t len;
+} SpiceChunk;
+
+enum {
+ SPICE_CHUNKS_FLAGS_UNSTABLE = (1<<0),
+ SPICE_CHUNKS_FLAGS_FREE = (1<<1)
+};
+
+typedef struct SpiceChunks {
+ uint32_t data_size;
+ uint32_t num_chunks;
+ uint32_t flags;
+ SpiceChunk chunk[0];
+} SpiceChunks;
+
+typedef struct SpiceBuffer
+{
+ size_t capacity;
+ size_t offset;
+ uint8_t *buffer;
+} SpiceBuffer;
+
+char *spice_strdup(const char *str) SPICE_GNUC_MALLOC;
+char *spice_strndup(const char *str, size_t n_bytes) SPICE_GNUC_MALLOC;
+void *spice_memdup(const void *mem, size_t n_bytes) SPICE_GNUC_MALLOC;
+void *spice_malloc(size_t n_bytes) SPICE_GNUC_MALLOC SPICE_GNUC_ALLOC_SIZE(1);
+void *spice_malloc0(size_t n_bytes) SPICE_GNUC_MALLOC SPICE_GNUC_ALLOC_SIZE(1);
+void *spice_realloc(void *mem, size_t n_bytes) SPICE_GNUC_WARN_UNUSED_RESULT;
+void *spice_malloc_n(size_t n_blocks, size_t n_block_bytes) SPICE_GNUC_MALLOC SPICE_GNUC_ALLOC_SIZE2(1,2);
+void *spice_malloc_n_m(size_t n_blocks, size_t n_block_bytes, size_t extra_size) SPICE_GNUC_MALLOC;
+void *spice_malloc0_n(size_t n_blocks, size_t n_block_bytes) SPICE_GNUC_MALLOC SPICE_GNUC_ALLOC_SIZE2(1,2);
+void *spice_realloc_n(void *mem, size_t n_blocks, size_t n_block_bytes) SPICE_GNUC_WARN_UNUSED_RESULT;
+SpiceChunks *spice_chunks_new(uint32_t count) SPICE_GNUC_MALLOC;
+SpiceChunks *spice_chunks_new_linear(uint8_t *data, uint32_t len) SPICE_GNUC_MALLOC;
+void spice_chunks_destroy(SpiceChunks *chunks);
+void spice_chunks_linearize(SpiceChunks *chunks);
+
+size_t spice_strnlen(const char *str, size_t max_len);
+
+/* Optimize: avoid the call to the (slower) _n function if we can
+ * determine at compile-time that no overflow happens.
+ */
+#if defined (__GNUC__) && (__GNUC__ >= 2) && defined (__OPTIMIZE__)
+# define _SPICE_NEW(struct_type, n_structs, func) \
+ (struct_type *) (__extension__ ({ \
+ size_t __n = (size_t) (n_structs); \
+ size_t __s = sizeof (struct_type); \
+ void *__p; \
+ if (__s == 1) \
+ __p = spice_##func (__n); \
+ else if (__builtin_constant_p (__n) && \
+ __n <= SIZE_MAX / __s) \
+ __p = spice_##func (__n * __s); \
+ else \
+ __p = spice_##func##_n (__n, __s); \
+ __p; \
+ }))
+# define _SPICE_RENEW(struct_type, mem, n_structs, func) \
+ (struct_type *) (__extension__ ({ \
+ size_t __n = (size_t) (n_structs); \
+ size_t __s = sizeof (struct_type); \
+ void *__p = (void *) (mem); \
+ if (__s == 1) \
+ __p = spice_##func (__p, __n); \
+ else if (__builtin_constant_p (__n) && \
+ __n <= SIZE_MAX / __s) \
+ __p = spice_##func (__p, __n * __s); \
+ else \
+ __p = spice_##func##_n (__p, __n, __s); \
+ __p; \
+ }))
+#else
+
+/* Unoptimized version: always call the _n() function. */
+
+#define _SPICE_NEW(struct_type, n_structs, func) \
+ ((struct_type *) spice_##func##_n ((n_structs), sizeof (struct_type)))
+#define _SPICE_RENEW(struct_type, mem, n_structs, func) \
+ ((struct_type *) spice_##func##_n (mem, (n_structs), sizeof (struct_type)))
+
+#endif
+
+#define spice_new(struct_type, n_structs) _SPICE_NEW(struct_type, n_structs, malloc)
+#define spice_new0(struct_type, n_structs) _SPICE_NEW(struct_type, n_structs, malloc0)
+#define spice_renew(struct_type, mem, n_structs) _SPICE_RENEW(struct_type, mem, n_structs, realloc)
+
+/* Buffer management */
+void spice_buffer_reserve(SpiceBuffer *buffer, size_t len);
+int spice_buffer_empty(SpiceBuffer *buffer);
+uint8_t *spice_buffer_end(SpiceBuffer *buffer);
+void spice_buffer_reset(SpiceBuffer *buffer);
+void spice_buffer_free(SpiceBuffer *buffer);
+void spice_buffer_append(SpiceBuffer *buffer, const void *data, size_t len);
+size_t spice_buffer_copy(SpiceBuffer *buffer, void *dest, size_t len);
+size_t spice_buffer_remove(SpiceBuffer *buffer, size_t len);
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2009-2010 Red Hat, Inc.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef _H_MESSAGES
+#define _H_MESSAGES
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <spice/protocol.h>
+#include <spice/macros.h>
+
+#ifdef USE_SMARTCARD_012
+#include <vscard_common.h>
+#else
+#ifdef USE_SMARTCARD
+#include <libcacard.h>
+#endif
+#endif
+
+#include "draw.h"
+
+SPICE_BEGIN_DECLS
+
+typedef struct SpiceMsgData {
+ uint32_t data_size;
+ uint8_t data[0];
+} SpiceMsgData;
+
+typedef struct SpiceMsgCompressedData {
+ uint8_t type;
+ uint32_t uncompressed_size;
+ uint32_t compressed_size;
+ uint8_t *compressed_data;
+} SpiceMsgCompressedData;
+
+typedef struct SpiceMsgEmpty {
+ uint8_t padding;
+} SpiceMsgEmpty;
+
+typedef struct SpiceMsgInputsInit {
+ uint32_t keyboard_modifiers;
+} SpiceMsgInputsInit;
+
+typedef struct SpiceMsgInputsKeyModifiers {
+ uint32_t modifiers;
+} SpiceMsgInputsKeyModifiers;
+
+typedef struct SpiceMsgMainMultiMediaTime {
+ uint32_t time;
+} SpiceMsgMainMultiMediaTime;
+
+typedef struct SpiceMigrationDstInfo {
+ uint16_t port;
+ uint16_t sport;
+ uint32_t host_size;
+ uint8_t *host_data;
+ uint16_t pub_key_type;
+ uint32_t pub_key_size;
+ uint8_t *pub_key_data;
+ uint32_t cert_subject_size;
+ uint8_t *cert_subject_data;
+} SpiceMigrationDstInfo;
+
+typedef struct SpiceMsgMainMigrationBegin {
+ SpiceMigrationDstInfo dst_info;
+} SpiceMsgMainMigrationBegin;
+
+typedef struct SpiceMsgMainMigrateBeginSeamless {
+ SpiceMigrationDstInfo dst_info;
+ uint32_t src_mig_version;
+} SpiceMsgMainMigrateBeginSeamless;
+
+typedef struct SpiceMsgcMainMigrateDstDoSeamless {
+ uint32_t src_version;
+} SpiceMsgcMainMigrateDstDoSeamless;
+
+typedef struct SpiceMsgMainMigrationSwitchHost {
+ uint16_t port;
+ uint16_t sport;
+ uint32_t host_size;
+ uint8_t *host_data;
+ uint32_t cert_subject_size;
+ uint8_t *cert_subject_data;
+} SpiceMsgMainMigrationSwitchHost;
+
+
+typedef struct SpiceMsgMigrate {
+ uint32_t flags;
+} SpiceMsgMigrate;
+
+typedef struct SpiceResourceID {
+ uint8_t type;
+ uint64_t id;
+} SpiceResourceID;
+
+typedef struct SpiceResourceList {
+ uint16_t count;
+ SpiceResourceID resources[0];
+} SpiceResourceList;
+
+typedef struct SpiceMsgSetAck {
+ uint32_t generation;
+ uint32_t window;
+} SpiceMsgSetAck;
+
+typedef struct SpiceMsgcAckSync {
+ uint32_t generation;
+} SpiceMsgcAckSync;
+
+typedef struct SpiceWaitForChannel {
+ uint8_t channel_type;
+ uint8_t channel_id;
+ uint64_t message_serial;
+} SpiceWaitForChannel;
+
+typedef struct SpiceMsgWaitForChannels {
+ uint8_t wait_count;
+ SpiceWaitForChannel wait_list[0];
+} SpiceMsgWaitForChannels;
+
+typedef struct SpiceChannelId {
+ uint8_t type;
+ uint8_t id;
+} SpiceChannelId;
+
+typedef struct SpiceMsgMainInit {
+ uint32_t session_id;
+ uint32_t display_channels_hint;
+ uint32_t supported_mouse_modes;
+ uint32_t current_mouse_mode;
+ uint32_t agent_connected;
+ uint32_t agent_tokens;
+ uint32_t multi_media_time;
+ uint32_t ram_hint;
+} SpiceMsgMainInit;
+
+typedef struct SpiceMsgDisconnect {
+ uint64_t time_stamp;
+ uint32_t reason; // SPICE_ERR_?
+} SpiceMsgDisconnect;
+
+typedef struct SpiceMsgNotify {
+ uint64_t time_stamp;
+ uint32_t severity;
+ uint32_t visibilty;
+ uint32_t what;
+ uint32_t message_len;
+ uint8_t message[0];
+} SpiceMsgNotify;
+
+typedef struct SpiceMsgChannels {
+ uint32_t num_of_channels;
+ SpiceChannelId channels[0];
+} SpiceMsgChannels;
+
+typedef struct SpiceMsgMainName {
+ uint32_t name_len;
+ uint8_t name[0];
+} SpiceMsgMainName;
+
+typedef struct SpiceMsgMainUuid {
+ uint8_t uuid[16];
+} SpiceMsgMainUuid;
+
+typedef struct SpiceMsgMainMouseMode {
+ uint32_t supported_modes;
+ uint32_t current_mode;
+} SpiceMsgMainMouseMode;
+
+typedef struct SpiceMsgPing {
+ uint32_t id;
+ uint64_t timestamp;
+ void *data;
+ uint32_t data_len;
+} SpiceMsgPing;
+
+typedef struct SpiceMsgMainAgentDisconnect {
+ uint32_t error_code; // SPICE_ERR_?
+} SpiceMsgMainAgentDisconnect;
+
+#define SPICE_AGENT_MAX_DATA_SIZE 2048
+
+typedef struct SpiceMsgMainAgentTokens {
+ uint32_t num_tokens;
+} SpiceMsgMainAgentTokens, SpiceMsgcMainAgentTokens, SpiceMsgcMainAgentStart;
+
+typedef struct SpiceMsgMainAgentTokens SpiceMsgMainAgentConnectedTokens;
+
+typedef struct SpiceMsgcClientInfo {
+ uint64_t cache_size;
+} SpiceMsgcClientInfo;
+
+typedef struct SpiceMsgcMainMouseModeRequest {
+ uint32_t mode;
+} SpiceMsgcMainMouseModeRequest;
+
+typedef struct SpiceCursor {
+ uint32_t flags;
+ SpiceCursorHeader header;
+ uint32_t data_size;
+ uint8_t *data;
+} SpiceCursor;
+
+typedef struct SpiceMsgDisplayMode {
+ uint32_t x_res;
+ uint32_t y_res;
+ uint32_t bits;
+} SpiceMsgDisplayMode;
+
+typedef struct SpiceMsgSurfaceCreate {
+ uint32_t surface_id;
+ uint32_t width;
+ uint32_t height;
+ uint32_t format;
+ uint32_t flags;
+} SpiceMsgSurfaceCreate;
+
+typedef struct SpiceMsgSurfaceDestroy {
+ uint32_t surface_id;
+} SpiceMsgSurfaceDestroy;
+
+typedef struct SpiceMsgDisplayBase {
+ uint32_t surface_id;
+ SpiceRect box;
+ SpiceClip clip;
+} SpiceMsgDisplayBase;
+
+typedef struct SpiceMsgDisplayDrawFill {
+ SpiceMsgDisplayBase base;
+ SpiceFill data;
+} SpiceMsgDisplayDrawFill;
+
+typedef struct SpiceMsgDisplayDrawOpaque {
+ SpiceMsgDisplayBase base;
+ SpiceOpaque data;
+} SpiceMsgDisplayDrawOpaque;
+
+typedef struct SpiceMsgDisplayDrawCopy {
+ SpiceMsgDisplayBase base;
+ SpiceCopy data;
+} SpiceMsgDisplayDrawCopy;
+
+typedef struct SpiceMsgDisplayDrawTransparent {
+ SpiceMsgDisplayBase base;
+ SpiceTransparent data;
+} SpiceMsgDisplayDrawTransparent;
+
+typedef struct SpiceMsgDisplayDrawAlphaBlend {
+ SpiceMsgDisplayBase base;
+ SpiceAlphaBlend data;
+} SpiceMsgDisplayDrawAlphaBlend;
+
+typedef struct SpiceMsgDisplayDrawComposite {
+ SpiceMsgDisplayBase base;
+ SpiceComposite data;
+} SpiceMsgDisplayDrawComposite;
+
+typedef struct SpiceMsgDisplayCopyBits {
+ SpiceMsgDisplayBase base;
+ SpicePoint src_pos;
+} SpiceMsgDisplayCopyBits;
+
+typedef SpiceMsgDisplayDrawCopy SpiceMsgDisplayDrawBlend;
+
+typedef struct SpiceMsgDisplayDrawRop3 {
+ SpiceMsgDisplayBase base;
+ SpiceRop3 data;
+} SpiceMsgDisplayDrawRop3;
+
+typedef struct SpiceMsgDisplayDrawBlackness {
+ SpiceMsgDisplayBase base;
+ SpiceBlackness data;
+} SpiceMsgDisplayDrawBlackness;
+
+typedef struct SpiceMsgDisplayDrawWhiteness {
+ SpiceMsgDisplayBase base;
+ SpiceWhiteness data;
+} SpiceMsgDisplayDrawWhiteness;
+
+typedef struct SpiceMsgDisplayDrawInvers {
+ SpiceMsgDisplayBase base;
+ SpiceInvers data;
+} SpiceMsgDisplayDrawInvers;
+
+typedef struct SpiceMsgDisplayDrawStroke {
+ SpiceMsgDisplayBase base;
+ SpiceStroke data;
+} SpiceMsgDisplayDrawStroke;
+
+typedef struct SpiceMsgDisplayDrawText {
+ SpiceMsgDisplayBase base;
+ SpiceText data;
+} SpiceMsgDisplayDrawText;
+
+typedef struct SpiceMsgDisplayInvalOne {
+ uint64_t id;
+} SpiceMsgDisplayInvalOne;
+
+typedef struct SpiceMsgDisplayStreamCreate {
+ uint32_t surface_id;
+ uint32_t id;
+ uint32_t flags;
+ uint32_t codec_type;
+ uint64_t stamp;
+ uint32_t stream_width;
+ uint32_t stream_height;
+ uint32_t src_width;
+ uint32_t src_height;
+ SpiceRect dest;
+ SpiceClip clip;
+} SpiceMsgDisplayStreamCreate;
+
+typedef struct SpiceStreamDataHeader {
+ uint32_t id;
+ uint32_t multi_media_time;
+} SpiceStreamDataHeader;
+
+typedef struct SpiceMsgDisplayStreamData {
+ SpiceStreamDataHeader base;
+ uint32_t data_size;
+ uint8_t data[0];
+} SpiceMsgDisplayStreamData;
+
+typedef struct SpiceMsgDisplayStreamDataSized {
+ SpiceStreamDataHeader base;
+ uint32_t width;
+ uint32_t height;
+ SpiceRect dest;
+ uint32_t data_size;
+ uint8_t data[0];
+} SpiceMsgDisplayStreamDataSized;
+
+typedef struct SpiceMsgDisplayStreamClip {
+ uint32_t id;
+ SpiceClip clip;
+} SpiceMsgDisplayStreamClip;
+
+typedef struct SpiceMsgDisplayStreamDestroy {
+ uint32_t id;
+} SpiceMsgDisplayStreamDestroy;
+
+typedef struct SpiceMsgDisplayStreamActivateReport {
+ uint32_t stream_id;
+ uint32_t unique_id;
+ uint32_t max_window_size;
+ uint32_t timeout_ms;
+} SpiceMsgDisplayStreamActivateReport;
+
+typedef struct SpiceMsgcDisplayStreamReport {
+ uint32_t stream_id;
+ uint32_t unique_id;
+ uint32_t start_frame_mm_time;
+ uint32_t end_frame_mm_time;
+ uint32_t num_frames;
+ uint32_t num_drops;
+ int32_t last_frame_delay;
+ uint32_t audio_delay;
+} SpiceMsgcDisplayStreamReport;
+
+typedef struct SpiceMsgcDisplayGlDrawDone {
+} SpiceMsgcDisplayGlDrawDone;
+
+typedef struct SpiceMsgCursorInit {
+ SpicePoint16 position;
+ uint16_t trail_length;
+ uint16_t trail_frequency;
+ uint8_t visible;
+ SpiceCursor cursor;
+} SpiceMsgCursorInit;
+
+typedef struct SpiceMsgCursorSet {
+ SpicePoint16 position;
+ uint8_t visible;
+ SpiceCursor cursor;
+} SpiceMsgCursorSet;
+
+typedef struct SpiceMsgCursorMove {
+ SpicePoint16 position;
+} SpiceMsgCursorMove;
+
+typedef struct SpiceMsgCursorTrail {
+ uint16_t length;
+ uint16_t frequency;
+} SpiceMsgCursorTrail;
+
+typedef struct SpiceMsgcDisplayInit {
+ uint8_t pixmap_cache_id;
+ int64_t pixmap_cache_size; //in pixels
+ uint8_t glz_dictionary_id;
+ int32_t glz_dictionary_window_size; // in pixels
+} SpiceMsgcDisplayInit;
+
+typedef struct SpiceMsgcKeyDown {
+ uint32_t code;
+} SpiceMsgcKeyDown;
+
+typedef struct SpiceMsgcKeyUp {
+ uint32_t code;
+} SpiceMsgcKeyUp;
+
+typedef struct SpiceMsgcKeyModifiers {
+ uint32_t modifiers;
+} SpiceMsgcKeyModifiers;
+
+typedef struct SpiceMsgcMouseMotion {
+ int32_t dx;
+ int32_t dy;
+ uint32_t buttons_state;
+} SpiceMsgcMouseMotion;
+
+typedef struct SpiceMsgcMousePosition {
+ uint32_t x;
+ uint32_t y;
+ uint32_t buttons_state;
+ uint8_t display_id;
+} SpiceMsgcMousePosition;
+
+typedef struct SpiceMsgcMousePress {
+ int32_t button;
+ int32_t buttons_state;
+} SpiceMsgcMousePress;
+
+typedef struct SpiceMsgcMouseRelease {
+ int32_t button;
+ int32_t buttons_state;
+} SpiceMsgcMouseRelease;
+
+typedef struct SpiceMsgAudioVolume {
+ uint8_t nchannels;
+ uint16_t volume[0];
+} SpiceMsgAudioVolume;
+
+typedef struct SpiceMsgAudioMute {
+ uint8_t mute;
+} SpiceMsgAudioMute;
+
+typedef struct SpiceMsgPlaybackMode {
+ uint32_t time;
+ uint32_t mode; //SPICE_AUDIO_DATA_MODE_?
+ uint8_t *data;
+ uint32_t data_size;
+} SpiceMsgPlaybackMode, SpiceMsgcRecordMode;
+
+typedef struct SpiceMsgPlaybackStart {
+ uint32_t channels;
+ uint32_t format; //SPICE_AUDIO_FMT_?
+ uint32_t frequency;
+ uint32_t time;
+} SpiceMsgPlaybackStart;
+
+typedef struct SpiceMsgPlaybackPacket {
+ uint32_t time;
+ uint8_t *data;
+ uint32_t data_size;
+} SpiceMsgPlaybackPacket, SpiceMsgcRecordPacket;
+
+typedef struct SpiceMsgPlaybackLatency {
+ uint32_t latency_ms;
+} SpiceMsgPlaybackLatency;
+
+typedef struct SpiceMsgRecordStart {
+ uint32_t channels;
+ uint32_t format; //SPICE_AUDIO_FMT_?
+ uint32_t frequency;
+} SpiceMsgRecordStart;
+
+typedef struct SpiceMsgcRecordStartMark {
+ uint32_t time;
+} SpiceMsgcRecordStartMark;
+
+typedef struct SpiceMsgTunnelInit {
+ uint16_t max_num_of_sockets;
+ uint32_t max_socket_data_size;
+} SpiceMsgTunnelInit;
+
+typedef uint8_t SpiceTunnelIPv4[4];
+
+typedef struct SpiceMsgTunnelIpInfo {
+ uint16_t type;
+ union {
+ SpiceTunnelIPv4 ipv4;
+ } u;
+ uint8_t data[0];
+} SpiceMsgTunnelIpInfo;
+
+typedef struct SpiceMsgTunnelServiceIpMap {
+ uint32_t service_id;
+ SpiceMsgTunnelIpInfo virtual_ip;
+} SpiceMsgTunnelServiceIpMap;
+
+typedef struct SpiceMsgTunnelSocketOpen {
+ uint16_t connection_id;
+ uint32_t service_id;
+ uint32_t tokens;
+} SpiceMsgTunnelSocketOpen;
+
+/* connection id must be the first field in msgs directed to a specific connection */
+
+typedef struct SpiceMsgTunnelSocketFin {
+ uint16_t connection_id;
+} SpiceMsgTunnelSocketFin;
+
+typedef struct SpiceMsgTunnelSocketClose {
+ uint16_t connection_id;
+} SpiceMsgTunnelSocketClose;
+
+typedef struct SpiceMsgTunnelSocketData {
+ uint16_t connection_id;
+ uint8_t data[0];
+} SpiceMsgTunnelSocketData;
+
+typedef struct SpiceMsgTunnelSocketTokens {
+ uint16_t connection_id;
+ uint32_t num_tokens;
+} SpiceMsgTunnelSocketTokens;
+
+typedef struct SpiceMsgTunnelSocketClosedAck {
+ uint16_t connection_id;
+} SpiceMsgTunnelSocketClosedAck;
+
+typedef struct SpiceMsgcTunnelAddGenericService {
+ uint32_t type;
+ uint32_t id;
+ uint32_t group;
+ uint32_t port;
+ uint64_t name;
+ uint64_t description;
+ union {
+ SpiceMsgTunnelIpInfo ip;
+ } u;
+} SpiceMsgcTunnelAddGenericService;
+
+typedef struct SpiceMsgcTunnelRemoveService {
+ uint32_t id;
+} SpiceMsgcTunnelRemoveService;
+
+/* connection id must be the first field in msgs directed to a specific connection */
+
+typedef struct SpiceMsgcTunnelSocketOpenAck {
+ uint16_t connection_id;
+ uint32_t tokens;
+} SpiceMsgcTunnelSocketOpenAck;
+
+typedef struct SpiceMsgcTunnelSocketOpenNack {
+ uint16_t connection_id;
+} SpiceMsgcTunnelSocketOpenNack;
+
+typedef struct SpiceMsgcTunnelSocketData {
+ uint16_t connection_id;
+ uint8_t data[0];
+} SpiceMsgcTunnelSocketData;
+
+typedef struct SpiceMsgcTunnelSocketFin {
+ uint16_t connection_id;
+} SpiceMsgcTunnelSocketFin;
+
+typedef struct SpiceMsgcTunnelSocketClosed {
+ uint16_t connection_id;
+} SpiceMsgcTunnelSocketClosed;
+
+typedef struct SpiceMsgcTunnelSocketClosedAck {
+ uint16_t connection_id;
+} SpiceMsgcTunnelSocketClosedAck;
+
+typedef struct SpiceMsgcTunnelSocketTokens {
+ uint16_t connection_id;
+ uint32_t num_tokens;
+} SpiceMsgcTunnelSocketTokens;
+
+#ifdef USE_SMARTCARD
+typedef struct SpiceMsgSmartcard {
+ VSCMsgType type;
+ uint32_t length;
+ uint32_t reader_id;
+ uint8_t data[0];
+} SpiceMsgSmartcard;
+
+typedef struct SpiceMsgcSmartcard {
+ VSCMsgHeader header;
+ union {
+ VSCMsgError error;
+ VSCMsgATR atr_data;
+ VSCMsgReaderAdd add;
+ };
+} SpiceMsgcSmartcard;
+#endif
+
+typedef struct SpiceMsgDisplayHead {
+ uint32_t id;
+ uint32_t surface_id;
+ uint32_t width;
+ uint32_t height;
+ uint32_t x;
+ uint32_t y;
+ uint32_t flags;
+} SpiceHead;
+
+typedef struct SpiceMsgDisplayMonitorsConfig {
+ uint16_t count;
+ uint16_t max_allowed;
+ SpiceHead heads[0];
+} SpiceMsgDisplayMonitorsConfig;
+
+typedef struct SpiceMsgPortInit {
+ uint32_t name_size;
+ uint8_t *name;
+ uint8_t opened;
+} SpiceMsgPortInit;
+
+typedef struct SpiceMsgPortEvent {
+ uint8_t event;
+} SpiceMsgPortEvent;
+
+typedef struct SpiceMsgcPortEvent {
+ uint8_t event;
+} SpiceMsgcPortEvent;
+
+typedef struct SpiceMsgcDisplayPreferredCompression {
+ uint8_t image_compression;
+} SpiceMsgcDisplayPreferredCompression;
+
+typedef struct SpiceMsgDisplayGlScanoutUnix {
+ int drm_dma_buf_fd;
+ uint32_t width;
+ uint32_t height;
+ uint32_t stride;
+ uint32_t drm_fourcc_format;
+ uint32_t flags;
+} SpiceMsgDisplayGlScanoutUnix;
+
+typedef struct SpiceMsgDisplayGlDraw {
+ uint32_t x;
+ uint32_t y;
+ uint32_t w;
+ uint32_t h;
+} SpiceMsgDisplayGlDraw;
+
+SPICE_END_DECLS
+
+#endif /* _H_SPICE_PROTOCOL */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "spice_common.h"
+
+#include "pixman_utils.h"
+
+#include <string.h>
+#include "mem.h"
+
+/*
+ * src is used for most OPs, hidden within _equation attribute. For some
+ * operations (such as "clear" and "noop") src is not used and then we have
+ * to add SPICE_GNUC_UNUSED, that's just a __attribute__((__unused__)), to
+ * make GCC happy.
+ * Also, according to GCC documentation [0], the unused attribute "(...) means
+ * that the variable is meant to be possibly unused. GCC does not produce a
+ * warning for this variable.". So, we are safe adding it, even if src is used
+ * for most OPs.
+ */
+#define SOLID_RASTER_OP(_name, _size, _type, _equation) \
+static void \
+solid_rop_ ## _name ## _ ## _size (_type *ptr, int len, SPICE_GNUC_UNUSED _type src) \
+{ \
+ while (len--) { \
+ _type dst = *ptr; \
+ if (dst) /* avoid unused warning */{}; \
+ *ptr = (_type)(_equation); \
+ ptr++; \
+ } \
+} \
+
+#define TILED_RASTER_OP(_name, _size, _type, _equation) \
+static void \
+tiled_rop_ ## _name ## _ ## _size (_type *ptr, int len, _type *tile, _type *tile_end, int tile_width) \
+{ \
+ while (len--) { \
+ _type src = *tile; \
+ _type dst = *ptr; \
+ if (src) /* avoid unused warning */{}; \
+ if (dst) /* avoid unused warning */{}; \
+ *ptr = (_type)(_equation); \
+ ptr++; \
+ tile++; \
+ if (tile == tile_end) \
+ tile -= tile_width; \
+ } \
+} \
+
+#define COPY_RASTER_OP(_name, _size, _type, _equation) \
+static void \
+ copy_rop_ ## _name ## _ ## _size (_type *ptr, _type *src_line, int len) \
+{ \
+ while (len--) { \
+ _type src = *src_line; \
+ _type dst = *ptr; \
+ if (src) /* avoid unused warning */ {}; \
+ if (dst) /* avoid unused warning */{}; \
+ *ptr = (_type)(_equation); \
+ ptr++; \
+ src_line++; \
+ } \
+} \
+
+#define RASTER_OP(name, equation) \
+ SOLID_RASTER_OP(name, 8, uint8_t, equation) \
+ SOLID_RASTER_OP(name, 16, uint16_t, equation) \
+ SOLID_RASTER_OP(name, 32, uint32_t, equation) \
+ TILED_RASTER_OP(name, 8, uint8_t, equation) \
+ TILED_RASTER_OP(name, 16, uint16_t, equation) \
+ TILED_RASTER_OP(name, 32, uint32_t, equation) \
+ COPY_RASTER_OP(name, 8, uint8_t, equation) \
+ COPY_RASTER_OP(name, 16, uint16_t, equation) \
+ COPY_RASTER_OP(name, 32, uint32_t, equation)
+
+RASTER_OP(clear, 0x0)
+RASTER_OP(and, src & dst)
+RASTER_OP(and_reverse, src & ~dst)
+RASTER_OP(copy, src)
+RASTER_OP(and_inverted, ~src & dst)
+RASTER_OP(noop, dst)
+RASTER_OP(xor, src ^ dst)
+RASTER_OP(or, src | dst)
+RASTER_OP(nor, ~src & ~dst)
+RASTER_OP(equiv, ~src ^ dst)
+RASTER_OP(invert, ~dst)
+RASTER_OP(or_reverse, src | ~dst)
+RASTER_OP(copy_inverted, ~src)
+RASTER_OP(or_inverted, ~src | dst)
+RASTER_OP(nand, ~src | ~dst)
+RASTER_OP(set, 0xffffffff)
+
+typedef void (*solid_rop_8_func_t)(uint8_t *ptr, int len, uint8_t src);
+typedef void (*solid_rop_16_func_t)(uint16_t *ptr, int len, uint16_t src);
+typedef void (*solid_rop_32_func_t)(uint32_t *ptr, int len, uint32_t src);
+typedef void (*tiled_rop_8_func_t)(uint8_t *ptr, int len,
+ uint8_t *tile, uint8_t *tile_end, int tile_width);
+typedef void (*tiled_rop_16_func_t)(uint16_t *ptr, int len,
+ uint16_t *tile, uint16_t *tile_end, int tile_width);
+typedef void (*tiled_rop_32_func_t)(uint32_t *ptr, int len,
+ uint32_t *tile, uint32_t *tile_end, int tile_width);
+typedef void (*copy_rop_8_func_t)(uint8_t *ptr, uint8_t *src, int len);
+typedef void (*copy_rop_16_func_t)(uint16_t *ptr, uint16_t *src, int len);
+typedef void (*copy_rop_32_func_t)(uint32_t *ptr, uint32_t *src, int len);
+
+#define ROP_TABLE(_type, _size) \
+static void (*solid_rops_ ## _size[16]) (_type *ptr, int len, _type src) = { \
+ solid_rop_clear_ ## _size, \
+ solid_rop_and_ ## _size, \
+ solid_rop_and_reverse_ ## _size, \
+ solid_rop_copy_ ## _size, \
+ solid_rop_and_inverted_ ## _size, \
+ solid_rop_noop_ ## _size, \
+ solid_rop_xor_ ## _size, \
+ solid_rop_or_ ## _size, \
+ solid_rop_nor_ ## _size, \
+ solid_rop_equiv_ ## _size, \
+ solid_rop_invert_ ## _size, \
+ solid_rop_or_reverse_ ## _size, \
+ solid_rop_copy_inverted_ ## _size, \
+ solid_rop_or_inverted_ ## _size, \
+ solid_rop_nand_ ## _size, \
+ solid_rop_set_ ## _size \
+}; \
+static void (*tiled_rops_ ## _size[16]) (_type *ptr, int len, _type *tile, _type *tile_end, int tile_width) = { \
+ tiled_rop_clear_ ## _size, \
+ tiled_rop_and_ ## _size, \
+ tiled_rop_and_reverse_ ## _size, \
+ tiled_rop_copy_ ## _size, \
+ tiled_rop_and_inverted_ ## _size, \
+ tiled_rop_noop_ ## _size, \
+ tiled_rop_xor_ ## _size, \
+ tiled_rop_or_ ## _size, \
+ tiled_rop_nor_ ## _size, \
+ tiled_rop_equiv_ ## _size, \
+ tiled_rop_invert_ ## _size, \
+ tiled_rop_or_reverse_ ## _size, \
+ tiled_rop_copy_inverted_ ## _size, \
+ tiled_rop_or_inverted_ ## _size, \
+ tiled_rop_nand_ ## _size, \
+ tiled_rop_set_ ## _size \
+}; \
+static void (*copy_rops_ ## _size[16]) (_type *ptr, _type *tile, int len) = { \
+ copy_rop_clear_ ## _size, \
+ copy_rop_and_ ## _size, \
+ copy_rop_and_reverse_ ## _size, \
+ copy_rop_copy_ ## _size, \
+ copy_rop_and_inverted_ ## _size, \
+ copy_rop_noop_ ## _size, \
+ copy_rop_xor_ ## _size, \
+ copy_rop_or_ ## _size, \
+ copy_rop_nor_ ## _size, \
+ copy_rop_equiv_ ## _size, \
+ copy_rop_invert_ ## _size, \
+ copy_rop_or_reverse_ ## _size, \
+ copy_rop_copy_inverted_ ## _size, \
+ copy_rop_or_inverted_ ## _size, \
+ copy_rop_nand_ ## _size, \
+ copy_rop_set_ ## _size \
+};
+
+ROP_TABLE(uint8_t, 8)
+ROP_TABLE(uint16_t, 16)
+ROP_TABLE(uint32_t, 32)
+
+/* We can't get the real bits per pixel info from pixman_image_t,
+ only the DEPTH which is the sum of all a+r+g+b bits, which
+ is e.g. 24 for 32bit xRGB. We really want the bpp, so
+ we have this ugly conversion thing */
+int spice_pixman_image_get_bpp(pixman_image_t *image)
+{
+ int depth;
+
+ depth = pixman_image_get_depth(image);
+ if (depth == 24) {
+ return 32;
+ }
+ if (depth == 15) {
+ return 16;
+ }
+ return depth;
+}
+
+void spice_pixman_fill_rect(pixman_image_t *dest,
+ int x, int y,
+ int width, int height,
+ uint32_t value)
+{
+ uint32_t *bits;
+ int stride, depth;
+ uint32_t byte_width;
+ uint8_t *byte_line;
+
+ bits = pixman_image_get_data(dest);
+ stride = pixman_image_get_stride(dest);
+ depth = spice_pixman_image_get_bpp(dest);
+ /* stride is in bytes, depth in bits */
+
+ spice_assert(x >= 0);
+ spice_assert(y >= 0);
+ spice_assert(width > 0);
+ spice_assert(height > 0);
+ spice_assert(x + width <= pixman_image_get_width(dest));
+ spice_assert(y + height <= pixman_image_get_height(dest));
+
+ if (pixman_fill(bits,
+ stride / 4,
+ depth,
+ x, y,
+ width, height,
+ value)) {
+ return;
+ }
+
+ if (depth == 8) {
+ byte_line = ((uint8_t *)bits) + stride * y + x;
+ byte_width = width;
+ value = (value & 0xff) * 0x01010101;
+ } else if (depth == 16) {
+ byte_line = ((uint8_t *)bits) + stride * y + x * 2;
+ byte_width = 2 * width;
+ value = (value & 0xffff) * 0x00010001;
+ } else {
+ spice_assert (depth == 32);
+ byte_line = ((uint8_t *)bits) + stride * y + x * 4;
+ byte_width = 4 * width;
+ }
+
+ while (height--) {
+ int w;
+ uint8_t *d = byte_line;
+
+ byte_line += stride;
+ w = byte_width;
+
+ while (w >= 1 && ((uintptr_t)d & 1)) {
+ *(uint8_t *)d = (value & 0xff);
+ w--;
+ d++;
+ }
+
+ while (w >= 2 && ((uintptr_t)d & 3)) {
+ *(uint16_t *)d = value;
+ w -= 2;
+ d += 2;
+ }
+
+ while (w >= 4 && ((uintptr_t)d & 7)) {
+ *(uint32_t *)d = value;
+
+ w -= 4;
+ d += 4;
+ }
+
+ while (w >= 4) {
+ *(uint32_t *)d = value;
+
+ w -= 4;
+ d += 4;
+ }
+
+ while (w >= 2) {
+ *(uint16_t *)d = value;
+ w -= 2;
+ d += 2;
+ }
+
+ while (w >= 1) {
+ *(uint8_t *)d = (value & 0xff);
+ w--;
+ d++;
+ }
+ }
+}
+
+void spice_pixman_fill_rect_rop(pixman_image_t *dest,
+ int x, int y,
+ int width, int height,
+ uint32_t value,
+ SpiceROP rop)
+{
+ uint32_t *bits;
+ int stride, depth;
+ uint8_t *byte_line;
+
+ bits = pixman_image_get_data(dest);
+ stride = pixman_image_get_stride(dest);
+ depth = spice_pixman_image_get_bpp(dest);
+ /* stride is in bytes, depth in bits */
+
+ spice_assert(x >= 0);
+ spice_assert(y >= 0);
+ spice_assert(width > 0);
+ spice_assert(height > 0);
+ spice_assert(x + width <= pixman_image_get_width(dest));
+ spice_assert(y + height <= pixman_image_get_height(dest));
+ spice_assert(rop < 16);
+
+ if (depth == 8) {
+ solid_rop_8_func_t rop_func = solid_rops_8[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * y + x;
+ while (height--) {
+ rop_func((uint8_t *)byte_line, width, (uint8_t)value);
+ byte_line += stride;
+ }
+
+ } else if (depth == 16) {
+ solid_rop_16_func_t rop_func = solid_rops_16[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * y + x * 2;
+ while (height--) {
+ rop_func((uint16_t *)byte_line, width, (uint16_t)value);
+ byte_line += stride;
+ }
+ } else {
+ solid_rop_32_func_t rop_func = solid_rops_32[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * y + x * 4;
+ while (height--) {
+ rop_func((uint32_t *)byte_line, width, (uint32_t)value);
+ byte_line += stride;
+ }
+ }
+}
+
+void spice_pixman_tile_rect(pixman_image_t *dest,
+ int x, int y,
+ int width, int height,
+ pixman_image_t *tile,
+ int offset_x,
+ int offset_y)
+{
+ uint32_t *bits, *tile_bits;
+ int stride, depth;
+ int tile_width, tile_height, tile_stride;
+ uint8_t *byte_line;
+ uint8_t *tile_line;
+ int tile_start_x, tile_start_y, tile_end_dx;
+
+ bits = pixman_image_get_data(dest);
+ stride = pixman_image_get_stride(dest);
+ depth = spice_pixman_image_get_bpp(dest);
+ /* stride is in bytes, depth in bits */
+
+ tile_bits = pixman_image_get_data(tile);
+ tile_stride = pixman_image_get_stride(tile);
+ tile_width = pixman_image_get_width(tile);
+ tile_height = pixman_image_get_height(tile);
+
+ spice_assert(x >= 0);
+ spice_assert(y >= 0);
+ spice_assert(width > 0);
+ spice_assert(height > 0);
+ spice_assert(x + width <= pixman_image_get_width(dest));
+ spice_assert(y + height <= pixman_image_get_height(dest));
+ spice_assert(depth == spice_pixman_image_get_bpp(tile));
+
+ tile_start_x = (x - offset_x) % tile_width;
+ if (tile_start_x < 0) {
+ tile_start_x += tile_width;
+ }
+ tile_start_y = (y - offset_y) % tile_height;
+ if (tile_start_y < 0) {
+ tile_start_y += tile_height;
+ }
+ tile_end_dx = tile_width - tile_start_x;
+
+ if (depth == 8) {
+ byte_line = ((uint8_t *)bits) + stride * y + x;
+ tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x;
+ while (height--) {
+ tiled_rop_copy_8((uint8_t *)byte_line, width,
+ (uint8_t *)tile_line, (uint8_t *)tile_line + tile_end_dx,
+ tile_width);
+ byte_line += stride;
+ tile_line += tile_stride;
+ if (++tile_start_y == tile_height) {
+ tile_line -= tile_height * tile_stride;
+ tile_start_y = 0;
+ }
+ }
+
+ } else if (depth == 16) {
+ byte_line = ((uint8_t *)bits) + stride * y + x * 2;
+ tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 2;
+ while (height--) {
+ tiled_rop_copy_16((uint16_t *)byte_line, width,
+ (uint16_t *)tile_line, (uint16_t *)tile_line + tile_end_dx,
+ tile_width);
+ byte_line += stride;
+ tile_line += tile_stride;
+ if (++tile_start_y == tile_height) {
+ tile_line -= tile_height * tile_stride;
+ tile_start_y = 0;
+ }
+ }
+ } else {
+ spice_assert (depth == 32);
+
+ byte_line = ((uint8_t *)bits) + stride * y + x * 4;
+ tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 4;
+ while (height--) {
+ tiled_rop_copy_32((uint32_t *)byte_line, width,
+ (uint32_t *)tile_line, (uint32_t *)tile_line + tile_end_dx,
+ tile_width);
+ byte_line += stride;
+ tile_line += tile_stride;
+ if (++tile_start_y == tile_height) {
+ tile_line -= tile_height * tile_stride;
+ tile_start_y = 0;
+ }
+ }
+ }
+}
+
+void spice_pixman_tile_rect_rop(pixman_image_t *dest,
+ int x, int y,
+ int width, int height,
+ pixman_image_t *tile,
+ int offset_x,
+ int offset_y,
+ SpiceROP rop)
+{
+ uint32_t *bits, *tile_bits;
+ int stride, depth;
+ int tile_width, tile_height, tile_stride;
+ uint8_t *byte_line;
+ uint8_t *tile_line;
+ int tile_start_x, tile_start_y, tile_end_dx;
+
+ bits = pixman_image_get_data(dest);
+ stride = pixman_image_get_stride(dest);
+ depth = spice_pixman_image_get_bpp(dest);
+ /* stride is in bytes, depth in bits */
+
+ tile_bits = pixman_image_get_data(tile);
+ tile_stride = pixman_image_get_stride(tile);
+ tile_width = pixman_image_get_width(tile);
+ tile_height = pixman_image_get_height(tile);
+
+ spice_assert(x >= 0);
+ spice_assert(y >= 0);
+ spice_assert(width > 0);
+ spice_assert(height > 0);
+ spice_assert(x + width <= pixman_image_get_width(dest));
+ spice_assert(y + height <= pixman_image_get_height(dest));
+ spice_assert(rop < 16);
+ spice_assert(depth == spice_pixman_image_get_bpp(tile));
+
+ tile_start_x = (x - offset_x) % tile_width;
+ if (tile_start_x < 0) {
+ tile_start_x += tile_width;
+ }
+ tile_start_y = (y - offset_y) % tile_height;
+ if (tile_start_y < 0) {
+ tile_start_y += tile_height;
+ }
+ tile_end_dx = tile_width - tile_start_x;
+
+ if (depth == 8) {
+ tiled_rop_8_func_t rop_func = tiled_rops_8[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * y + x;
+ tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x;
+ while (height--) {
+ rop_func((uint8_t *)byte_line, width,
+ (uint8_t *)tile_line, (uint8_t *)tile_line + tile_end_dx,
+ tile_width);
+ byte_line += stride;
+ tile_line += tile_stride;
+ if (++tile_start_y == tile_height) {
+ tile_line -= tile_height * tile_stride;
+ tile_start_y = 0;
+ }
+ }
+
+ } else if (depth == 16) {
+ tiled_rop_16_func_t rop_func = tiled_rops_16[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * y + x * 2;
+ tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 2;
+ while (height--) {
+ rop_func((uint16_t *)byte_line, width,
+ (uint16_t *)tile_line, (uint16_t *)tile_line + tile_end_dx,
+ tile_width);
+ byte_line += stride;
+ tile_line += tile_stride;
+ if (++tile_start_y == tile_height) {
+ tile_line -= tile_height * tile_stride;
+ tile_start_y = 0;
+ }
+ }
+ } else {
+ tiled_rop_32_func_t rop_func = tiled_rops_32[rop];
+
+ spice_assert (depth == 32);
+
+ byte_line = ((uint8_t *)bits) + stride * y + x * 4;
+ tile_line = ((uint8_t *)tile_bits) + tile_stride * tile_start_y + tile_start_x * 4;
+ while (height--) {
+ rop_func((uint32_t *)byte_line, width,
+ (uint32_t *)tile_line, (uint32_t *)tile_line + tile_end_dx,
+ tile_width);
+ byte_line += stride;
+ tile_line += tile_stride;
+ if (++tile_start_y == tile_height) {
+ tile_line -= tile_height * tile_stride;
+ tile_start_y = 0;
+ }
+ }
+ }
+}
+
+
+void spice_pixman_blit(pixman_image_t *dest,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height)
+{
+ uint32_t *bits, *src_bits;
+ int stride, depth, src_depth;
+ int src_width, src_height, src_stride;
+ uint8_t *byte_line;
+ uint8_t *src_line;
+ int byte_width;
+
+ if (!src) {
+ fprintf(stderr, "missing src!");
+ return;
+ }
+
+ bits = pixman_image_get_data(dest);
+ stride = pixman_image_get_stride(dest);
+ depth = spice_pixman_image_get_bpp(dest);
+ /* stride is in bytes, depth in bits */
+
+ src_bits = pixman_image_get_data(src);
+ src_stride = pixman_image_get_stride(src);
+ src_width = pixman_image_get_width(src);
+ src_height = pixman_image_get_height(src);
+ src_depth = spice_pixman_image_get_bpp(src);
+
+ /* Clip source */
+ if (src_x < 0) {
+ width += src_x;
+ dest_x -= src_x;
+ src_x = 0;
+ }
+ if (src_y < 0) {
+ height += src_y;
+ dest_y -= src_y;
+ src_y = 0;
+ }
+ if (src_x + width > src_width) {
+ width = src_width - src_x;
+ }
+ if (src_y + height > src_height) {
+ height = src_height - src_y;
+ }
+
+ if (width <= 0 || height <= 0) {
+ return;
+ }
+
+ spice_assert(src_x >= 0);
+ spice_assert(src_y >= 0);
+ spice_assert(dest_x >= 0);
+ spice_assert(dest_y >= 0);
+ spice_assert(width > 0);
+ spice_assert(height > 0);
+ spice_assert(dest_x + width <= pixman_image_get_width(dest));
+ spice_assert(dest_y + height <= pixman_image_get_height(dest));
+ spice_assert(src_x + width <= pixman_image_get_width(src));
+ spice_assert(src_y + height <= pixman_image_get_height(src));
+ spice_assert(depth == src_depth);
+
+ if (pixman_blt(src_bits,
+ bits,
+ src_stride / 4,
+ stride / 4,
+ depth, depth,
+ src_x, src_y,
+ dest_x, dest_y,
+ width, height)) {
+ return;
+ }
+
+ if (depth == 8) {
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x;
+ byte_width = width;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x;
+ } else if (depth == 16) {
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 2;
+ byte_width = width * 2;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 2;
+ } else {
+ spice_assert (depth == 32);
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 4;
+ byte_width = width * 4;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 4;
+ }
+
+ while (height--) {
+ memcpy(byte_line, src_line, byte_width);
+ byte_line += stride;
+ src_line += src_stride;
+ }
+}
+
+void spice_pixman_blit_rop (pixman_image_t *dest,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height,
+ SpiceROP rop)
+{
+ uint32_t *bits, *src_bits;
+ int stride, depth, src_depth;
+ int src_width, src_height, src_stride;
+ uint8_t *byte_line;
+ uint8_t *src_line;
+
+ bits = pixman_image_get_data(dest);
+ stride = pixman_image_get_stride(dest);
+ depth = spice_pixman_image_get_bpp(dest);
+ /* stride is in bytes, depth in bits */
+
+ src_bits = pixman_image_get_data(src);
+ src_stride = pixman_image_get_stride(src);
+ src_width = pixman_image_get_width(src);
+ src_height = pixman_image_get_height(src);
+ src_depth = spice_pixman_image_get_bpp(src);
+
+ /* Clip source */
+ if (src_x < 0) {
+ width += src_x;
+ dest_x -= src_x;
+ src_x = 0;
+ }
+ if (src_y < 0) {
+ height += src_y;
+ dest_y -= src_y;
+ src_y = 0;
+ }
+ if (src_x + width > src_width) {
+ width = src_width - src_x;
+ }
+ if (src_y + height > src_height) {
+ height = src_height - src_y;
+ }
+
+ if (width <= 0 || height <= 0) {
+ return;
+ }
+
+ spice_assert(src_x >= 0);
+ spice_assert(src_y >= 0);
+ spice_assert(dest_x >= 0);
+ spice_assert(dest_y >= 0);
+ spice_assert(width > 0);
+ spice_assert(height > 0);
+ spice_assert(dest_x + width <= pixman_image_get_width(dest));
+ spice_assert(dest_y + height <= pixman_image_get_height(dest));
+ spice_assert(src_x + width <= pixman_image_get_width(src));
+ spice_assert(src_y + height <= pixman_image_get_height(src));
+ spice_assert(depth == src_depth);
+
+ if (depth == 8) {
+ copy_rop_8_func_t rop_func = copy_rops_8[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x;
+
+ while (height--) {
+ rop_func((uint8_t *)byte_line, (uint8_t *)src_line, width);
+ byte_line += stride;
+ src_line += src_stride;
+ }
+ } else if (depth == 16) {
+ copy_rop_16_func_t rop_func = copy_rops_16[rop];
+
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 2;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 2;
+
+ while (height--) {
+ rop_func((uint16_t *)byte_line, (uint16_t *)src_line, width);
+ byte_line += stride;
+ src_line += src_stride;
+ }
+ } else {
+ copy_rop_32_func_t rop_func = copy_rops_32[rop];
+
+ spice_assert (depth == 32);
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 4;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 4;
+
+ while (height--) {
+ rop_func((uint32_t *)byte_line, (uint32_t *)src_line, width);
+ byte_line += stride;
+ src_line += src_stride;
+ }
+ }
+
+}
+
+void spice_pixman_blit_colorkey (pixman_image_t *dest,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height,
+ uint32_t transparent_color)
+{
+ uint32_t *bits, *src_bits;
+ int stride, depth;
+ int src_width, src_height, src_stride;
+ uint8_t *byte_line;
+ uint8_t *src_line;
+ int x;
+
+ bits = pixman_image_get_data(dest);
+ stride = pixman_image_get_stride(dest);
+ depth = spice_pixman_image_get_bpp(dest);
+ /* stride is in bytes, depth in bits */
+
+ src_bits = pixman_image_get_data(src);
+ src_stride = pixman_image_get_stride(src);
+ src_width = pixman_image_get_width(src);
+ src_height = pixman_image_get_height(src);
+
+ /* Clip source */
+ if (src_x < 0) {
+ width += src_x;
+ dest_x -= src_x;
+ src_x = 0;
+ }
+ if (src_y < 0) {
+ height += src_y;
+ dest_y -= src_y;
+ src_y = 0;
+ }
+ if (src_x + width > src_width) {
+ width = src_width - src_x;
+ }
+ if (src_y + height > src_height) {
+ height = src_height - src_y;
+ }
+
+ if (width <= 0 || height <= 0) {
+ return;
+ }
+
+ spice_assert(src_x >= 0);
+ spice_assert(src_y >= 0);
+ spice_assert(dest_x >= 0);
+ spice_assert(dest_y >= 0);
+ spice_assert(width > 0);
+ spice_assert(height > 0);
+ spice_assert(dest_x + width <= pixman_image_get_width(dest));
+ spice_assert(dest_y + height <= pixman_image_get_height(dest));
+ spice_assert(src_x + width <= pixman_image_get_width(src));
+ spice_assert(src_y + height <= pixman_image_get_height(src));
+ spice_assert(depth == spice_pixman_image_get_bpp(src));
+
+ if (depth == 8) {
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x;
+
+ while (height--) {
+ uint8_t *d = (uint8_t *)byte_line;
+ uint8_t *s = (uint8_t *)src_line;
+ for (x = 0; x < width; x++) {
+ uint8_t val = *s;
+ if (val != (uint8_t)transparent_color) {
+ *d = val;
+ }
+ s++; d++;
+ }
+
+ byte_line += stride;
+ src_line += src_stride;
+ }
+ } else if (depth == 16) {
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 2;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 2;
+
+ while (height--) {
+ uint16_t *d = (uint16_t *)byte_line;
+ uint16_t *s = (uint16_t *)src_line;
+
+ for (x = 0; x < width; x++) {
+ uint16_t val = *s;
+ if (val != (uint16_t)transparent_color) {
+ *d = val;
+ }
+ s++; d++;
+ }
+
+ byte_line += stride;
+ src_line += src_stride;
+ }
+ } else {
+ spice_assert (depth == 32);
+ byte_line = ((uint8_t *)bits) + stride * dest_y + dest_x * 4;
+ src_line = ((uint8_t *)src_bits) + src_stride * src_y + src_x * 4;
+
+ while (height--) {
+ uint32_t *d = (uint32_t *)byte_line;
+ uint32_t *s = (uint32_t *)src_line;
+
+ transparent_color &= 0xffffff;
+ for (x = 0; x < width; x++) {
+ uint32_t val = *s;
+ if ((0xffffff & val) != transparent_color) {
+ *d = val;
+ }
+ s++; d++;
+ }
+
+ byte_line += stride;
+ src_line += src_stride;
+ }
+ }
+}
+
+static void copy_bits_up(uint8_t *data, const int stride, int bpp,
+ const int src_x, const int src_y,
+ const int width, const int height,
+ const int dest_x, const int dest_y)
+{
+ uint8_t *src = data + src_y * stride + src_x * bpp;
+ uint8_t *dest = data + dest_y * stride + dest_x * bpp;
+ uint8_t *end = dest + height * stride;
+ for (; dest != end; dest += stride, src += stride) {
+ memcpy(dest, src, width * bpp);
+ }
+}
+
+static void copy_bits_down(uint8_t *data, const int stride, int bpp,
+ const int src_x, const int src_y,
+ const int width, const int height,
+ const int dest_x, const int dest_y)
+{
+ uint8_t *src = data + (src_y + height - 1) * stride + src_x * bpp;
+ uint8_t *end = data + (dest_y - 1) * stride + dest_x * bpp;
+ uint8_t *dest = end + height * stride;
+
+ for (; dest != end; dest -= stride, src -= stride) {
+ memcpy(dest, src, width * bpp);
+ }
+}
+
+static void copy_bits_same_line(uint8_t *data, const int stride, int bpp,
+ const int src_x, const int src_y,
+ const int width, const int height,
+ const int dest_x, const int dest_y)
+{
+ uint8_t *src = data + src_y * stride + src_x * bpp;
+ uint8_t *dest = data + dest_y * stride + dest_x * bpp;
+ uint8_t *end = dest + height * stride;
+ for (; dest != end; dest += stride, src += stride) {
+ memmove(dest, src, width * bpp);
+ }
+}
+
+void spice_pixman_copy_rect (pixman_image_t *image,
+ int src_x, int src_y,
+ int width, int height,
+ int dest_x, int dest_y)
+{
+ uint8_t *data;
+ int stride;
+ int bpp;
+
+ data = (uint8_t *)pixman_image_get_data(image);
+ stride = pixman_image_get_stride(image);
+ bpp = spice_pixman_image_get_bpp(image) / 8;
+
+ if (dest_y > src_y) {
+ copy_bits_down(data, stride, bpp,
+ src_x, src_y,
+ width, height,
+ dest_x, dest_y);
+ } else if (dest_y < src_y) {
+ copy_bits_up(data, stride, bpp,
+ src_x, src_y,
+ width, height,
+ dest_x, dest_y);
+ } else {
+ copy_bits_same_line(data, stride, bpp,
+ src_x, src_y,
+ width, height,
+ dest_x, dest_y);
+ }
+}
+
+pixman_bool_t spice_pixman_region32_init_rects (pixman_region32_t *region,
+ const SpiceRect *rects,
+ int count)
+{
+ /* These types are compatible, so just cast */
+ return pixman_region32_init_rects(region, (pixman_box32_t *)rects, count);
+}
+
+pixman_format_code_t spice_surface_format_to_pixman(uint32_t surface_format)
+{
+ switch (surface_format) {
+ case SPICE_SURFACE_FMT_1_A:
+ return PIXMAN_a1;
+ case SPICE_SURFACE_FMT_8_A:
+ return PIXMAN_a8;
+ case SPICE_SURFACE_FMT_16_555:
+ return PIXMAN_x1r5g5b5;
+ case SPICE_SURFACE_FMT_16_565:
+ return PIXMAN_r5g6b5;
+ case SPICE_SURFACE_FMT_32_xRGB:
+ return PIXMAN_x8r8g8b8;
+ case SPICE_SURFACE_FMT_32_ARGB:
+ return PIXMAN_a8r8g8b8;
+ default:
+ printf("Unknown surface format %d\n", surface_format);
+ spice_abort();
+ break;
+ }
+ return (pixman_format_code_t)0; /* Not reached */
+}
+
+/* Returns the "spice native" pixman version of a specific bitmap format.
+ * This isn't bitwise the same as the bitmap format, for instance we
+ * typically convert indexed to real color modes and use the standard
+ * surface modes rather than weird things like 24bit
+ */
+pixman_format_code_t spice_bitmap_format_to_pixman(int bitmap_format,
+ uint32_t palette_surface_format)
+{
+ switch (bitmap_format) {
+ case SPICE_BITMAP_FMT_1BIT_LE:
+ case SPICE_BITMAP_FMT_1BIT_BE:
+ case SPICE_BITMAP_FMT_4BIT_LE:
+ case SPICE_BITMAP_FMT_4BIT_BE:
+ case SPICE_BITMAP_FMT_8BIT:
+ /* Indexed mode palettes are the same as their destination canvas format */
+ return spice_surface_format_to_pixman(palette_surface_format);
+
+ case SPICE_BITMAP_FMT_16BIT:
+ return PIXMAN_x1r5g5b5;
+
+ case SPICE_BITMAP_FMT_24BIT:
+ case SPICE_BITMAP_FMT_32BIT:
+ return PIXMAN_x8r8g8b8;
+
+ case SPICE_BITMAP_FMT_RGBA:
+ return PIXMAN_a8r8g8b8;
+
+ case SPICE_BITMAP_FMT_8BIT_A:
+ return PIXMAN_a8;
+
+ case SPICE_BITMAP_FMT_INVALID:
+ default:
+ printf("Unknown bitmap format %d\n", bitmap_format);
+ spice_abort();
+ return PIXMAN_a8r8g8b8;
+ }
+}
+
+/* Tries to view a spice bitmap as a pixman_image_t without copying,
+ * will often fail due to unhandled formats or strides.
+ */
+pixman_image_t *spice_bitmap_try_as_pixman(int src_format,
+ int flags,
+ int width,
+ int height,
+ uint8_t *data,
+ int stride)
+{
+ pixman_format_code_t pixman_format;
+
+ /* Pixman stride must be multiple of 4 */
+ if (stride % 4 != 0) {
+ return NULL;
+ }
+
+ switch (src_format) {
+ case SPICE_BITMAP_FMT_32BIT:
+ pixman_format = PIXMAN_LE_x8r8g8b8;
+ break;
+ case SPICE_BITMAP_FMT_RGBA:
+ pixman_format = PIXMAN_LE_a8r8g8b8;
+ break;
+ case SPICE_BITMAP_FMT_24BIT:
+ pixman_format = PIXMAN_LE_r8g8b8;
+ break;
+ case SPICE_BITMAP_FMT_16BIT:
+#ifdef WORDS_BIGENDIAN
+ return NULL;
+#else
+ pixman_format = PIXMAN_x1r5g5b5;
+#endif
+ break;
+
+ default:
+ return NULL;
+ }
+
+ if (!(flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
+ data += stride * (height - 1);
+ stride = -stride;
+ }
+
+ return pixman_image_create_bits (pixman_format,
+ width,
+ height,
+ (uint32_t *)data,
+ stride);
+}
+
+#ifdef WORDS_BIGENDIAN
+#define UINT16_FROM_LE(x) SPICE_BYTESWAP16(x)
+#define UINT32_FROM_LE(x) SPICE_BYTESWAP32(x)
+#else
+#define UINT16_FROM_LE(x) (x)
+#define UINT32_FROM_LE(x) (x)
+#endif
+
+static inline uint32_t rgb_16_555_to_32(uint16_t color)
+{
+ uint32_t ret;
+
+ ret = ((color & 0x001f) << 3) | ((color & 0x001c) >> 2);
+ ret |= ((color & 0x03e0) << 6) | ((color & 0x0380) << 1);
+ ret |= ((color & 0x7c00) << 9) | ((color & 0x7000) << 4);
+
+ return ret;
+}
+
+static inline uint16_t rgb_32_to_16_555(uint32_t color)
+{
+ return
+ (((color) >> 3) & 0x001f) |
+ (((color) >> 6) & 0x03e0) |
+ (((color) >> 9) & 0x7c00);
+}
+
+
+static void bitmap_32_to_32(uint8_t* dest, int dest_stride,
+ uint8_t* src, int src_stride,
+ int width, uint8_t* end)
+{
+#ifdef WORDS_BIGENDIAN
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ uint32_t* src_line = (uint32_t *)src;
+ uint32_t* src_line_end = src_line + width;
+ uint32_t* dest_line = (uint32_t *)dest;
+
+ for (; src_line < src_line_end; ++dest_line, ++src_line) {
+ *dest_line = UINT32_FROM_LE(*src_line);
+ }
+ }
+#else
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ memcpy(dest, src, width * 4);
+ }
+#endif
+}
+
+static void bitmap_8_to_8(uint8_t* dest, int dest_stride,
+ uint8_t* src, int src_stride,
+ int width, uint8_t* end)
+{
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ memcpy(dest, src, width);
+ }
+}
+
+static void bitmap_24_to_32(uint8_t* dest, int dest_stride,
+ uint8_t* src, int src_stride,
+ int width, uint8_t* end)
+{
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ uint8_t* src_line = src;
+ uint8_t* src_line_end = src_line + width * 3;
+ uint32_t* dest_line = (uint32_t *)dest;
+
+ for (; src_line < src_line_end; ++dest_line) {
+ uint32_t r, g, b;
+ b = *(src_line++);
+ g = *(src_line++);
+ r = *(src_line++);
+ *dest_line = (r << 16) | (g << 8) | (b);
+ }
+ }
+}
+
+static void bitmap_16_to_16_555(uint8_t* dest, int dest_stride,
+ uint8_t* src, int src_stride,
+ int width, uint8_t* end)
+{
+#ifdef WORDS_BIGENDIAN
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ uint16_t* src_line = (uint16_t *)src;
+ uint16_t* src_line_end = src_line + width;
+ uint16_t* dest_line = (uint16_t *)dest;
+
+ for (; src_line < src_line_end; ++dest_line, ++src_line) {
+ *dest_line = UINT16_FROM_LE(*src_line);
+ }
+ }
+#else
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ memcpy(dest, src, width * 2);
+ }
+#endif
+}
+
+static void bitmap_8_32_to_32(uint8_t *dest, int dest_stride,
+ uint8_t *src, int src_stride,
+ int width, uint8_t *end,
+ SpicePalette *palette)
+{
+ uint32_t local_ents[256];
+ uint32_t *ents;
+ int n_ents;
+#ifdef WORDS_BIGENDIAN
+ int i;
+#endif
+
+ if (!palette) {
+ spice_error("No palette");
+ return;
+ }
+
+ n_ents = MIN(palette->num_ents, 256);
+ ents = palette->ents;
+
+ if (n_ents < 255
+#ifdef WORDS_BIGENDIAN
+ || TRUE
+#endif
+ ) {
+ memcpy(local_ents, ents, n_ents*4);
+ ents = local_ents;
+
+#ifdef WORDS_BIGENDIAN
+ for (i = 0; i < n_ents; i++) {
+ ents[i] = UINT32_FROM_LE(ents[i]);
+ }
+#endif
+ }
+
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ uint32_t *dest_line = (uint32_t*)dest;
+ uint8_t *src_line = src;
+ uint8_t *src_line_end = src_line + width;
+
+ while (src_line < src_line_end) {
+ *(dest_line++) = ents[*(src_line++)];
+ }
+ }
+}
+
+static void bitmap_8_16_to_16_555(uint8_t *dest, int dest_stride,
+ uint8_t *src, int src_stride,
+ int width, uint8_t *end,
+ SpicePalette *palette)
+{
+ uint32_t local_ents[256];
+ uint32_t *ents;
+ int n_ents;
+#ifdef WORDS_BIGENDIAN
+ int i;
+#endif
+
+ if (!palette) {
+ spice_error("No palette");
+ return;
+ }
+
+ n_ents = MIN(palette->num_ents, 256);
+ ents = palette->ents;
+
+ if (n_ents < 255
+#ifdef WORDS_BIGENDIAN
+ || TRUE
+#endif
+ ) {
+ memcpy(local_ents, ents, n_ents*4);
+ ents = local_ents;
+
+#ifdef WORDS_BIGENDIAN
+ for (i = 0; i < n_ents; i++) {
+ ents[i] = UINT32_FROM_LE(ents[i]);
+ }
+#endif
+ }
+
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ uint16_t *dest_line = (uint16_t*)dest;
+ uint8_t *src_line = src;
+ uint8_t *src_line_end = src_line + width;
+
+ while (src_line < src_line_end) {
+ *(dest_line++) = ents[*(src_line++)];
+ }
+ }
+}
+
+static void bitmap_4be_32_to_32(uint8_t* dest, int dest_stride,
+ uint8_t* src, int src_stride,
+ int width, uint8_t* end,
+ SpicePalette *palette)
+{
+ uint32_t local_ents[16];
+ uint32_t *ents;
+ int n_ents;
+#ifdef WORDS_BIGENDIAN
+ int i;
+#endif
+
+ if (!palette) {
+ spice_error("No palette");
+ return;
+ }
+
+ n_ents = MIN(palette->num_ents, 16);
+ ents = palette->ents;
+
+ if (n_ents < 16
+#ifdef WORDS_BIGENDIAN
+ || TRUE
+#endif
+ ) {
+ memcpy(local_ents, ents, n_ents*4);
+ ents = local_ents;
+
+#ifdef WORDS_BIGENDIAN
+ for (i = 0; i < n_ents; i++) {
+ ents[i] = UINT32_FROM_LE(ents[i]);
+ }
+#endif
+ }
+
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ uint32_t *dest_line = (uint32_t *)dest;
+ uint8_t *row = src;
+ int i;
+
+ for (i = 0; i < (width >> 1); i++) {
+ *(dest_line++) = ents[(*row >> 4) & 0x0f];
+ *(dest_line++) = ents[*(row++) & 0x0f];
+ }
+ if (width & 1) {
+ *(dest_line) = ents[(*row >> 4) & 0x0f];
+ }
+ }
+}
+
+static void bitmap_4be_16_to_16_555(uint8_t* dest, int dest_stride,
+ uint8_t* src, int src_stride,
+ int width, uint8_t* end,
+ SpicePalette *palette)
+{
+ uint32_t local_ents[16];
+ uint32_t *ents;
+ int n_ents;
+#ifdef WORDS_BIGENDIAN
+ int i;
+#endif
+
+ if (!palette) {
+ spice_error("No palette");
+ return;
+ }
+
+ n_ents = MIN(palette->num_ents, 16);
+ ents = palette->ents;
+
+ if (n_ents < 16
+#ifdef WORDS_BIGENDIAN
+ || TRUE
+#endif
+ ) {
+ memcpy(local_ents, ents, n_ents*4);
+ ents = local_ents;
+
+#ifdef WORDS_BIGENDIAN
+ for (i = 0; i < n_ents; i++) {
+ ents[i] = UINT32_FROM_LE(ents[i]);
+ }
+#endif
+ }
+
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ uint16_t *dest_line = (uint16_t *)dest;
+ uint8_t *row = src;
+ int i;
+
+ for (i = 0; i < (width >> 1); i++) {
+ *(dest_line++) = ents[(*row >> 4) & 0x0f];
+ *(dest_line++) = ents[*(row++) & 0x0f];
+ }
+ if (width & 1) {
+ *(dest_line) = ents[(*row >> 4) & 0x0f];
+ }
+ }
+}
+
+static inline int test_bit_be(void* addr, int bit)
+{
+ return !!(((uint8_t*)addr)[bit >> 3] & (0x80 >> (bit & 0x07)));
+}
+
+static void bitmap_1be_32_to_32(uint8_t* dest, int dest_stride,
+ uint8_t* src, int src_stride,
+ int width, uint8_t* end,
+ SpicePalette *palette)
+{
+ uint32_t fore_color;
+ uint32_t back_color;
+
+ spice_assert(palette != NULL);
+
+ if (!palette) {
+ return;
+ }
+
+ fore_color = UINT32_FROM_LE(palette->ents[1]);
+ back_color = UINT32_FROM_LE(palette->ents[0]);
+
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ uint32_t* dest_line = (uint32_t*)dest;
+ int i;
+
+ for (i = 0; i < width; i++) {
+ if (test_bit_be(src, i)) {
+ *(dest_line++) = fore_color;
+ } else {
+ *(dest_line++) = back_color;
+ }
+ }
+ }
+}
+
+
+static void bitmap_1be_16_to_16_555(uint8_t* dest, int dest_stride,
+ uint8_t* src, int src_stride,
+ int width, uint8_t* end,
+ SpicePalette *palette)
+{
+ uint16_t fore_color;
+ uint16_t back_color;
+
+ spice_assert(palette != NULL);
+
+ if (!palette) {
+ return;
+ }
+
+ fore_color = (uint16_t) UINT32_FROM_LE(palette->ents[1]);
+ back_color = (uint16_t) UINT32_FROM_LE(palette->ents[0]);
+
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ uint16_t* dest_line = (uint16_t*)dest;
+ int i;
+
+ for (i = 0; i < width; i++) {
+ if (test_bit_be(src, i)) {
+ *(dest_line++) = fore_color;
+ } else {
+ *(dest_line++) = back_color;
+ }
+ }
+ }
+}
+
+#ifdef NOT_USED_ATM
+
+static void bitmap_16_to_32(uint8_t* dest, int dest_stride,
+ uint8_t* src, int src_stride,
+ int width, uint8_t* end)
+{
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ uint16_t* src_line = (uint16_t*)src;
+ uint16_t* src_line_end = src_line + width;
+ uint32_t* dest_line = (uint32_t*)dest;
+
+ for (; src_line < src_line_end; ++dest_line, src_line++) {
+ *dest_line = rgb_16_555_to_32(UINT16_FROM_LE(*src_line));
+ }
+ }
+}
+
+static void bitmap_32_to_16_555(uint8_t* dest, int dest_stride,
+ uint8_t* src, int src_stride,
+ int width, uint8_t* end)
+{
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ uint32_t* src_line = (uint32_t *)src;
+ uint32_t* src_line_end = src_line + width;
+ uint16_t* dest_line = (uint16_t *)dest;
+
+ for (; src_line < src_line_end; ++dest_line, ++src_line) {
+ *dest_line = rgb_32_to_16_555(UINT16_FROM_LE(*src_line));
+ }
+ }
+}
+
+
+static void bitmap_24_to_16_555(uint8_t* dest, int dest_stride,
+ uint8_t* src, int src_stride,
+ int width, uint8_t* end)
+{
+ for (; src != end; src += src_stride, dest += dest_stride) {
+ uint8_t* src_line = src;
+ uint8_t* src_line_end = src_line + width * 3;
+ uint16_t* dest_line = (uint16_t *)dest;
+
+ for (; src_line < src_line_end; ++dest_line) {
+ uint8_t r, g, b;
+ b = *(src_line++);
+ g = *(src_line++);
+ r = *(src_line++);
+ *dest_line = rgb_32_to_16_555(r << 24 | g << 16 | b);
+ }
+ }
+}
+
+#endif
+
+/* This assumes that the dest, if set is the same format as
+ spice_bitmap_format_to_pixman would have picked */
+pixman_image_t *spice_bitmap_to_pixman(pixman_image_t *dest_image,
+ int src_format,
+ int flags,
+ int width,
+ int height,
+ uint8_t *src,
+ int src_stride,
+ uint32_t palette_surface_format,
+ SpicePalette *palette)
+{
+ uint8_t* dest;
+ int dest_stride;
+ uint8_t* end;
+
+ if (dest_image == NULL) {
+ pixman_format_code_t dest_format;
+
+ dest_format = spice_bitmap_format_to_pixman(src_format,
+ palette_surface_format);
+ dest_image = pixman_image_create_bits (dest_format,
+ width, height,
+ NULL, 0);
+ }
+
+ dest = (uint8_t *)pixman_image_get_data(dest_image);
+ dest_stride = pixman_image_get_stride(dest_image);
+ if (!(flags & SPICE_BITMAP_FLAGS_TOP_DOWN)) {
+ spice_assert(height > 0);
+ dest += dest_stride * (height - 1);
+ dest_stride = -dest_stride;
+ }
+ end = src + (height * src_stride);
+
+ switch (src_format) {
+ case SPICE_BITMAP_FMT_32BIT:
+ case SPICE_BITMAP_FMT_RGBA:
+ bitmap_32_to_32(dest, dest_stride, src, src_stride, width, end);
+ break;
+ case SPICE_BITMAP_FMT_8BIT_A:
+ bitmap_8_to_8(dest, dest_stride, src, src_stride, width, end);
+ break;
+ case SPICE_BITMAP_FMT_24BIT:
+ bitmap_24_to_32(dest, dest_stride, src, src_stride, width, end);
+ break;
+ case SPICE_BITMAP_FMT_16BIT:
+ bitmap_16_to_16_555(dest, dest_stride, src, src_stride, width, end);
+ break;
+ case SPICE_BITMAP_FMT_8BIT:
+ if (palette_surface_format == SPICE_SURFACE_FMT_32_ARGB ||
+ palette_surface_format == SPICE_SURFACE_FMT_32_xRGB) {
+ bitmap_8_32_to_32(dest, dest_stride, src, src_stride, width, end, palette);
+ } else if (palette_surface_format == SPICE_SURFACE_FMT_16_555) {
+ bitmap_8_16_to_16_555(dest, dest_stride, src, src_stride, width, end, palette);
+ } else {
+ spice_error("Unsupported palette format");
+ }
+ break;
+ case SPICE_BITMAP_FMT_4BIT_BE:
+ if (palette_surface_format == SPICE_SURFACE_FMT_32_ARGB ||
+ palette_surface_format == SPICE_SURFACE_FMT_32_xRGB) {
+ bitmap_4be_32_to_32(dest, dest_stride, src, src_stride, width, end, palette);
+ } else if (palette_surface_format == SPICE_SURFACE_FMT_16_555) {
+ bitmap_4be_16_to_16_555(dest, dest_stride, src, src_stride, width, end, palette);
+ } else {
+ spice_error("Unsupported palette format");
+ }
+ break;
+ case SPICE_BITMAP_FMT_1BIT_BE:
+ if (palette_surface_format == SPICE_SURFACE_FMT_32_ARGB ||
+ palette_surface_format == SPICE_SURFACE_FMT_32_xRGB) {
+ bitmap_1be_32_to_32(dest, dest_stride, src, src_stride, width, end, palette);
+ } else if (palette_surface_format == SPICE_SURFACE_FMT_16_555) {
+ bitmap_1be_16_to_16_555(dest, dest_stride, src, src_stride, width, end, palette);
+ } else {
+ spice_error("Unsupported palette format");
+ }
+ break;
+ default:
+ spice_error("Unsupported bitmap format");
+ break;
+ }
+
+ return dest_image;
+}
+
+static int pixman_format_compatible (pixman_format_code_t dest_format,
+ pixman_format_code_t src_format)
+{
+ if (dest_format == src_format) {
+ return TRUE;
+ }
+
+ if (src_format == PIXMAN_a8r8g8b8 &&
+ dest_format == PIXMAN_x8r8g8b8) {
+ /* This is the same, we just ignore the alphas */
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+pixman_image_t *spice_bitmap_convert_to_pixman(pixman_format_code_t dest_format,
+ pixman_image_t *dest_image,
+ int src_format,
+ int flags,
+ int width,
+ int height,
+ uint8_t *src,
+ int src_stride,
+ uint32_t palette_surface_format,
+ SpicePalette *palette)
+{
+ pixman_image_t *src_image;
+ pixman_format_code_t native_format;
+
+ if (dest_image == NULL) {
+ dest_image = pixman_image_create_bits (dest_format,
+ width, height,
+ NULL, 0);
+ }
+
+ native_format =
+ spice_bitmap_format_to_pixman(src_format, palette_surface_format);
+
+ if (pixman_format_compatible (dest_format, native_format)) {
+ return spice_bitmap_to_pixman(dest_image,
+ src_format,
+ flags, width,height,
+ src, src_stride,
+ palette_surface_format, palette);
+ }
+
+ src_image = spice_bitmap_try_as_pixman(src_format,
+ flags, width,height,
+ src, src_stride);
+
+ /* Can't convert directly, need a temporary copy
+ * Hopefully most bitmap reads should not need conversion (i.e.
+ * hit the spice_bitmap_to_pixmap case above) or work with the
+ * try_as_pixmap case, but in case some specific combination
+ * shows up here commonly we might want to add non-temporary
+ * conversion special casing here */
+ if (src_image == NULL) {
+ src_image = spice_bitmap_to_pixman(NULL,
+ src_format,
+ flags, width,height,
+ src, src_stride,
+ palette_surface_format, palette);
+ }
+
+ pixman_image_composite32 (PIXMAN_OP_SRC,
+ src_image, NULL, dest_image,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ width, height);
+
+ pixman_image_unref (src_image);
+
+ return dest_image;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H__PIXMAN_UTILS
+#define _H__PIXMAN_UTILS
+
+#include <spice/types.h>
+#include <spice/macros.h>
+#include <stdlib.h>
+#define PIXMAN_DONT_DEFINE_STDINT
+#include <pixman.h>
+
+#include "draw.h"
+
+#ifdef WORDS_BIGENDIAN
+# define PIXMAN_LE_x8r8g8b8 PIXMAN_b8g8r8x8
+# define PIXMAN_LE_a8r8g8b8 PIXMAN_b8g8r8a8
+# define PIXMAN_LE_r8g8b8 PIXMAN_b8g8r8
+#else
+# define PIXMAN_LE_x8r8g8b8 PIXMAN_x8r8g8b8
+# define PIXMAN_LE_a8r8g8b8 PIXMAN_a8r8g8b8
+# define PIXMAN_LE_r8g8b8 PIXMAN_r8g8b8
+#endif
+
+SPICE_BEGIN_DECLS
+
+/* This lists all possible 2 argument binary raster ops.
+ * This enum has the same values as the X11 GXcopy type
+ * and same as the GL constants (GL_AND etc) if you
+ * or it with 0x1500. However it is not exactly the
+ * same as the win32 ROP2 type (they use another order).
+ */
+typedef enum {
+ SPICE_ROP_CLEAR, /* 0x0 0 */
+ SPICE_ROP_AND, /* 0x1 src AND dst */
+ SPICE_ROP_AND_REVERSE, /* 0x2 src AND NOT dst */
+ SPICE_ROP_COPY, /* 0x3 src */
+ SPICE_ROP_AND_INVERTED, /* 0x4 (NOT src) AND dst */
+ SPICE_ROP_NOOP, /* 0x5 dst */
+ SPICE_ROP_XOR, /* 0x6 src XOR dst */
+ SPICE_ROP_OR, /* 0x7 src OR dst */
+ SPICE_ROP_NOR, /* 0x8 (NOT src) AND (NOT dst) */
+ SPICE_ROP_EQUIV, /* 0x9 (NOT src) XOR dst */
+ SPICE_ROP_INVERT, /* 0xa NOT dst */
+ SPICE_ROP_OR_REVERSE, /* 0xb src OR (NOT dst) */
+ SPICE_ROP_COPY_INVERTED, /* 0xc NOT src */
+ SPICE_ROP_OR_INVERTED, /* 0xd (NOT src) OR dst */
+ SPICE_ROP_NAND, /* 0xe (NOT src) OR (NOT dst) */
+ SPICE_ROP_SET /* 0xf 1 */
+} SpiceROP;
+
+
+int spice_pixman_image_get_bpp(pixman_image_t *image);
+
+pixman_format_code_t spice_surface_format_to_pixman(uint32_t surface_format);
+pixman_format_code_t spice_bitmap_format_to_pixman(int bitmap_format,
+ uint32_t palette_surface_format);
+pixman_image_t *spice_bitmap_try_as_pixman(int src_format, int flags,
+ int width, int height,
+ uint8_t *data, int stride);
+pixman_image_t *spice_bitmap_to_pixman(pixman_image_t *dest_image,
+ int src_format, int flags,
+ int width, int height,
+ uint8_t *src, int src_stride,
+ uint32_t palette_surface_format,
+ SpicePalette *palette);
+pixman_image_t *spice_bitmap_convert_to_pixman(pixman_format_code_t dest_format,
+ pixman_image_t *dest_image,
+ int src_format, int flags,
+ int width, int height,
+ uint8_t *src, int src_stride,
+ uint32_t palette_surface_format,
+ SpicePalette *palette);
+
+void spice_pixman_region32_init_from_bitmap(pixman_region32_t *region,
+ uint32_t *data,
+ int width, int height,
+ int stride);
+pixman_bool_t spice_pixman_region32_init_rects(pixman_region32_t *region,
+ const SpiceRect *rects,
+ int count);
+void spice_pixman_fill_rect(pixman_image_t *dest,
+ int x, int y,
+ int w, int h,
+ uint32_t value);
+void spice_pixman_fill_rect_rop(pixman_image_t *dest,
+ int x, int y,
+ int w, int h,
+ uint32_t value,
+ SpiceROP rop);
+void spice_pixman_tile_rect(pixman_image_t *dest,
+ int x, int y,
+ int w, int h,
+ pixman_image_t *tile,
+ int offset_x,
+ int offset_y);
+void spice_pixman_tile_rect_rop(pixman_image_t *dest,
+ int x, int y,
+ int w, int h,
+ pixman_image_t *tile,
+ int offset_x,
+ int offset_y,
+ SpiceROP rop);
+void spice_pixman_blit(pixman_image_t *dest,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int w, int h);
+void spice_pixman_blit_rop(pixman_image_t *dest,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int w, int h,
+ SpiceROP rop);
+void spice_pixman_blit_colorkey(pixman_image_t *dest,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height,
+ uint32_t transparent_color);
+void spice_pixman_copy_rect(pixman_image_t *image,
+ int src_x, int src_y,
+ int w, int h,
+ int dest_x, int dest_y);
+
+SPICE_END_DECLS
+
+#endif /* _H__PIXMAN_UTILS */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+// Red Hat image compression based on SFALIC by Roman Starosolski
+// http://sun.iinf.polsl.gliwice.pl/~rstaros/sfalic/index.html
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+
+#include "quic.h"
+#include "spice_common.h"
+#include "bitops.h"
+
+#define RLE
+#define RLE_STAT
+#define PRED_1
+//#define RLE_PRED_1
+#define RLE_PRED_2
+//#define RLE_PRED_3
+#define QUIC_RGB
+
+/* ASCII "QUIC" */
+#define QUIC_MAGIC 0x43495551
+#define QUIC_VERSION_MAJOR 0U
+#define QUIC_VERSION_MINOR 1U
+#define QUIC_VERSION ((QUIC_VERSION_MAJOR << 16) | (QUIC_VERSION_MAJOR & 0xffff))
+
+typedef uint8_t BYTE;
+
+/* maximum number of codes in family */
+#define MAXNUMCODES 8
+
+/* model evolution, warning: only 1,3 and 5 allowed */
+#define DEFevol 3
+#define MINevol 0
+#define MAXevol 5
+
+/* starting wait mask index */
+#define DEFwmistart 0
+#define MINwmistart 0
+
+/* codeword length limit */
+#define DEFmaxclen 26
+
+/* target wait mask index */
+#define DEFwmimax 6
+
+/* number of symbols to encode before increasing wait mask index */
+#define DEFwminext 2048
+#define MINwminext 1
+#define MAXwminext 100000000
+
+typedef struct QuicFamily {
+ unsigned int nGRcodewords[MAXNUMCODES]; /* indexed by code number, contains number of
+ unmodified GR codewords in the code */
+ unsigned int notGRcwlen[MAXNUMCODES]; /* indexed by code number, contains codeword
+ length of the not-GR codeword */
+ unsigned int notGRprefixmask[MAXNUMCODES]; /* indexed by code number, contains mask to
+ determine if the codeword is GR or not-GR */
+ unsigned int notGRsuffixlen[MAXNUMCODES]; /* indexed by code number, contains suffix
+ length of the not-GR codeword */
+
+ unsigned int golomb_code_len[256][MAXNUMCODES];
+ unsigned int golomb_code[256][MAXNUMCODES];
+
+ /* array for translating distribution U to L for depths up to 8 bpp,
+ initialized by decorelateinit() */
+ BYTE xlatU2L[256];
+
+ /* array for translating distribution L to U for depths up to 8 bpp,
+ initialized by corelateinit() */
+ unsigned int xlatL2U[256];
+} QuicFamily;
+
+static QuicFamily family_8bpc;
+static QuicFamily family_5bpc;
+
+typedef unsigned COUNTER; /* counter in the array of counters in bucket of the data model */
+
+typedef struct s_bucket {
+ COUNTER *pcounters; /* pointer to array of counters */
+ unsigned int bestcode; /* best code so far */
+} s_bucket;
+
+typedef struct Encoder Encoder;
+
+typedef struct CommonState {
+ Encoder *encoder;
+
+ unsigned int waitcnt;
+ unsigned int tabrand_seed;
+ unsigned int wm_trigger;
+ unsigned int wmidx;
+ unsigned int wmileft;
+
+#ifdef RLE_STAT
+ int melcstate; /* index to the state array */
+
+ int melclen; /* contents of the state array location
+ indexed by melcstate: the "expected"
+ run length is 2^melclen, shorter runs are
+ encoded by a 1 followed by the run length
+ in binary representation, wit a fixed length
+ of melclen bits */
+
+ unsigned long melcorder; /* 2^ melclen */
+#endif
+} CommonState;
+
+
+#define MAX_CHANNELS 4
+
+typedef struct FamilyStat {
+ s_bucket **buckets_ptrs;
+ s_bucket *buckets_buf;
+ COUNTER *counters;
+} FamilyStat;
+
+typedef struct Channel {
+ Encoder *encoder;
+
+ int correlate_row_width;
+ BYTE *correlate_row;
+
+ s_bucket **_buckets_ptrs;
+
+ FamilyStat family_stat_8bpc;
+ FamilyStat family_stat_5bpc;
+
+ CommonState state;
+} Channel;
+
+struct Encoder {
+ QuicUsrContext *usr;
+ QuicImageType type;
+ unsigned int width;
+ unsigned int height;
+ unsigned int num_channels;
+
+ unsigned int n_buckets_8bpc;
+ unsigned int n_buckets_5bpc;
+
+ unsigned int io_available_bits;
+ uint32_t io_word;
+ uint32_t io_next_word;
+ uint32_t *io_now;
+ uint32_t *io_end;
+ uint32_t io_words_count;
+
+ int rows_completed;
+
+ Channel channels[MAX_CHANNELS];
+
+ CommonState rgb_state;
+};
+
+/* target wait mask index */
+static int wmimax = DEFwmimax;
+
+/* number of symbols to encode before increasing wait mask index */
+static int wminext = DEFwminext;
+
+/* model evolution mode */
+static int evol = DEFevol;
+
+/* bppmask[i] contains i ones as lsb-s */
+static const unsigned long int bppmask[33] = {
+ 0x00000000, /* [0] */
+ 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
+ 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
+ 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
+ 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
+ 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
+ 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
+ 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
+ 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff /* [32] */
+};
+
+#define bitat(n) (1u<<(n))
+
+
+#define TABRAND_TABSIZE 256
+#define TABRAND_SEEDMASK 0x0ff
+
+static const unsigned int tabrand_chaos[TABRAND_TABSIZE] = {
+ 0x02c57542, 0x35427717, 0x2f5a2153, 0x9244f155, 0x7bd26d07, 0x354c6052, 0x57329b28, 0x2993868e,
+ 0x6cd8808c, 0x147b46e0, 0x99db66af, 0xe32b4cac, 0x1b671264, 0x9d433486, 0x62a4c192, 0x06089a4b,
+ 0x9e3dce44, 0xdaabee13, 0x222425ea, 0xa46f331d, 0xcd589250, 0x8bb81d7f, 0xc8b736b9, 0x35948d33,
+ 0xd7ac7fd0, 0x5fbe2803, 0x2cfbc105, 0x013dbc4e, 0x7a37820f, 0x39f88e9e, 0xedd58794, 0xc5076689,
+ 0xfcada5a4, 0x64c2f46d, 0xb3ba3243, 0x8974b4f9, 0x5a05aebd, 0x20afcd00, 0x39e2b008, 0x88a18a45,
+ 0x600bde29, 0xf3971ace, 0xf37b0a6b, 0x7041495b, 0x70b707ab, 0x06beffbb, 0x4206051f, 0xe13c4ee3,
+ 0xc1a78327, 0x91aa067c, 0x8295f72a, 0x732917a6, 0x1d871b4d, 0x4048f136, 0xf1840e7e, 0x6a6048c1,
+ 0x696cb71a, 0x7ff501c3, 0x0fc6310b, 0x57e0f83d, 0x8cc26e74, 0x11a525a2, 0x946934c7, 0x7cd888f0,
+ 0x8f9d8604, 0x4f86e73b, 0x04520316, 0xdeeea20c, 0xf1def496, 0x67687288, 0xf540c5b2, 0x22401484,
+ 0x3478658a, 0xc2385746, 0x01979c2c, 0x5dad73c8, 0x0321f58b, 0xf0fedbee, 0x92826ddf, 0x284bec73,
+ 0x5b1a1975, 0x03df1e11, 0x20963e01, 0xa17cf12b, 0x740d776e, 0xa7a6bf3c, 0x01b5cce4, 0x1118aa76,
+ 0xfc6fac0a, 0xce927e9b, 0x00bf2567, 0x806f216c, 0xbca69056, 0x795bd3e9, 0xc9dc4557, 0x8929b6c2,
+ 0x789d52ec, 0x3f3fbf40, 0xb9197368, 0xa38c15b5, 0xc3b44fa8, 0xca8333b0, 0xb7e8d590, 0xbe807feb,
+ 0xbf5f8360, 0xd99e2f5c, 0x372928e1, 0x7c757c4c, 0x0db5b154, 0xc01ede02, 0x1fc86e78, 0x1f3985be,
+ 0xb4805c77, 0x00c880fa, 0x974c1b12, 0x35ab0214, 0xb2dc840d, 0x5b00ae37, 0xd313b026, 0xb260969d,
+ 0x7f4c8879, 0x1734c4d3, 0x49068631, 0xb9f6a021, 0x6b863e6f, 0xcee5debf, 0x29f8c9fb, 0x53dd6880,
+ 0x72b61223, 0x1f67a9fd, 0x0a0f6993, 0x13e59119, 0x11cca12e, 0xfe6b6766, 0x16b6effc, 0x97918fc4,
+ 0xc2b8a563, 0x94f2f741, 0x0bfa8c9a, 0xd1537ae8, 0xc1da349c, 0x873c60ca, 0x95005b85, 0x9b5c080e,
+ 0xbc8abbd9, 0xe1eab1d2, 0x6dac9070, 0x4ea9ebf1, 0xe0cf30d4, 0x1ef5bd7b, 0xd161043e, 0x5d2fa2e2,
+ 0xff5d3cae, 0x86ed9f87, 0x2aa1daa1, 0xbd731a34, 0x9e8f4b22, 0xb1c2c67a, 0xc21758c9, 0xa182215d,
+ 0xccb01948, 0x8d168df7, 0x04238cfe, 0x368c3dbc, 0x0aeadca5, 0xbad21c24, 0x0a71fee5, 0x9fc5d872,
+ 0x54c152c6, 0xfc329483, 0x6783384a, 0xeddb3e1c, 0x65f90e30, 0x884ad098, 0xce81675a, 0x4b372f7d,
+ 0x68bf9a39, 0x43445f1e, 0x40f8d8cb, 0x90d5acb6, 0x4cd07282, 0x349eeb06, 0x0c9d5332, 0x520b24ef,
+ 0x80020447, 0x67976491, 0x2f931ca3, 0xfe9b0535, 0xfcd30220, 0x61a9e6cc, 0xa487d8d7, 0x3f7c5dd1,
+ 0x7d0127c5, 0x48f51d15, 0x60dea871, 0xc9a91cb7, 0x58b53bb3, 0x9d5e0b2d, 0x624a78b4, 0x30dbee1b,
+ 0x9bdf22e7, 0x1df5c299, 0x2d5643a7, 0xf4dd35ff, 0x03ca8fd6, 0x53b47ed8, 0x6f2c19aa, 0xfeb0c1f4,
+ 0x49e54438, 0x2f2577e6, 0xbf876969, 0x72440ea9, 0xfa0bafb8, 0x74f5b3a0, 0x7dd357cd, 0x89ce1358,
+ 0x6ef2cdda, 0x1e7767f3, 0xa6be9fdb, 0x4f5f88f8, 0xba994a3a, 0x08ca6b65, 0xe0893818, 0x9e00a16a,
+ 0xf42bfc8f, 0x9972eedc, 0x749c8b51, 0x32c05f5e, 0xd706805f, 0x6bfbb7cf, 0xd9210a10, 0x31a1db97,
+ 0x923a9559, 0x37a7a1f6, 0x059f8861, 0xca493e62, 0x65157e81, 0x8f6467dd, 0xab85ff9f, 0x9331aff2,
+ 0x8616b9f5, 0xedbd5695, 0xee7e29b1, 0x313ac44f, 0xb903112f, 0x432ef649, 0xdc0a36c0, 0x61cf2bba,
+ 0x81474925, 0xa8b6c7ad, 0xee5931de, 0xb2f8158d, 0x59fb7409, 0x2e3dfaed, 0x9af25a3f, 0xe1fed4d5,
+};
+
+static unsigned int stabrand(void)
+{
+ //spice_assert( !(TABRAND_SEEDMASK & TABRAND_TABSIZE));
+ //spice_assert( TABRAND_SEEDMASK + 1 == TABRAND_TABSIZE );
+
+ return TABRAND_SEEDMASK;
+}
+
+static unsigned int tabrand(unsigned int *tabrand_seed)
+{
+ return tabrand_chaos[++*tabrand_seed & TABRAND_SEEDMASK];
+}
+
+static const unsigned short besttrigtab[3][11] = { /* array of wm_trigger for waitmask and evol,
+ used by set_wm_trigger() */
+ /* 1 */ { 550, 900, 800, 700, 500, 350, 300, 200, 180, 180, 160},
+ /* 3 */ { 110, 550, 900, 800, 550, 400, 350, 250, 140, 160, 140},
+ /* 5 */ { 100, 120, 550, 900, 700, 500, 400, 300, 220, 250, 160}
+};
+
+/* set wm_trigger knowing waitmask (param) and evol (glob)*/
+static void set_wm_trigger(CommonState *state)
+{
+ unsigned int wm = state->wmidx;
+ if (wm > 10) {
+ wm = 10;
+ }
+
+ spice_assert(evol < 6);
+
+ state->wm_trigger = besttrigtab[evol / 2][wm];
+
+ spice_assert(state->wm_trigger <= 2000);
+ spice_assert(state->wm_trigger >= 1);
+}
+
+static int ceil_log_2(int val) /* ceil(log_2(val)) */
+{
+ int result;
+
+ //spice_assert(val>0);
+
+ if (val == 1) {
+ return 0;
+ }
+
+ result = 1;
+ val -= 1;
+ while (val >>= 1) {
+ result++;
+ }
+
+ return result;
+}
+
+/* number of leading zeroes in the byte, used by cntlzeroes(uint)*/
+static const BYTE lzeroes[256] = {
+ 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* count leading zeroes */
+static unsigned int cnt_l_zeroes(const unsigned int bits)
+{
+ if (bits & 0xff800000) {
+ return lzeroes[bits >> 24];
+ } else if (bits & 0xffff8000) {
+ return 8 + lzeroes[(bits >> 16) & 0x000000ff];
+ } else if (bits & 0xffffff80) {
+ return 16 + lzeroes[(bits >> 8) & 0x000000ff];
+ } else {
+ return 24 + lzeroes[bits & 0x000000ff];
+ }
+}
+
+#define QUIC_FAMILY_8BPC
+#include "quic_family_tmpl.c"
+
+#ifdef QUIC_RGB
+#define QUIC_FAMILY_5BPC
+#include "quic_family_tmpl.c"
+#endif
+
+static void decorelate_init(QuicFamily *family, int bpc)
+{
+ const unsigned int pixelbitmask = bppmask[bpc];
+ const unsigned int pixelbitmaskshr = pixelbitmask >> 1;
+ unsigned int s;
+
+ //spice_assert(bpc <= 8);
+
+ for (s = 0; s <= pixelbitmask; s++) {
+ if (s <= pixelbitmaskshr) {
+ family->xlatU2L[s] = s << 1;
+ } else {
+ family->xlatU2L[s] = ((pixelbitmask - s) << 1) + 1;
+ }
+ }
+}
+
+static void corelate_init(QuicFamily *family, int bpc)
+{
+ const unsigned long int pixelbitmask = bppmask[bpc];
+ unsigned long int s;
+
+ //spice_assert(bpc <= 8);
+
+ for (s = 0; s <= pixelbitmask; s++) {
+ if (s & 0x01) {
+ family->xlatL2U[s] = pixelbitmask - (s >> 1);
+ } else {
+ family->xlatL2U[s] = (s >> 1);
+ }
+ }
+}
+
+static void golomb_coding_slow(QuicFamily *family, const BYTE n, const unsigned int l,
+ unsigned int * const codeword,
+ unsigned int * const codewordlen)
+{
+ if (n < family->nGRcodewords[l]) {
+ (*codeword) = bitat(l) | (n & bppmask[l]);
+ (*codewordlen) = (n >> l) + l + 1;
+ } else {
+ (*codeword) = n - family->nGRcodewords[l];
+ (*codewordlen) = family->notGRcwlen[l];
+ }
+}
+
+static void family_init(QuicFamily *family, int bpc, int limit)
+{
+ int l, b;
+
+ for (l = 0; l < bpc; l++) { /* fill arrays indexed by code number */
+ int altprefixlen, altcodewords;
+
+ altprefixlen = limit - bpc;
+ if (altprefixlen > (int)(bppmask[bpc - l])) {
+ altprefixlen = bppmask[bpc - l];
+ }
+
+ altcodewords = bppmask[bpc] + 1 - (altprefixlen << l);
+
+ family->nGRcodewords[l] = (altprefixlen << l);
+ family->notGRsuffixlen[l] = ceil_log_2(altcodewords); /* needed for decoding only */
+ family->notGRcwlen[l] = altprefixlen + family->notGRsuffixlen[l];
+ family->notGRprefixmask[l] = bppmask[32 - altprefixlen]; /* needed for decoding only */
+
+ for (b = 0; b < 256; b++) {
+ unsigned int code, len;
+ golomb_coding_slow(family, b, l, &code, &len);
+ family->golomb_code[b][l] = code;
+ family->golomb_code_len[b][l] = len;
+ }
+ }
+
+ decorelate_init(family, bpc);
+ corelate_init(family, bpc);
+}
+
+static void more_io_words(Encoder *encoder)
+{
+ uint32_t *io_ptr;
+ int num_io_words = encoder->usr->more_space(encoder->usr, &io_ptr, encoder->rows_completed);
+ if (num_io_words <= 0) {
+ encoder->usr->error(encoder->usr, "%s: no more words\n", __FUNCTION__);
+ }
+ spice_assert(io_ptr);
+ encoder->io_words_count += num_io_words;
+ encoder->io_now = io_ptr;
+ encoder->io_end = encoder->io_now + num_io_words;
+}
+
+static void __write_io_word(Encoder *encoder)
+{
+ more_io_words(encoder);
+ *(encoder->io_now++) = encoder->io_word;
+}
+
+static void (*__write_io_word_ptr)(Encoder *encoder) = __write_io_word;
+
+static inline void write_io_word(Encoder *encoder)
+{
+ if (encoder->io_now == encoder->io_end) {
+ __write_io_word_ptr(encoder); //disable inline optimizations
+ return;
+ }
+ *(encoder->io_now++) = encoder->io_word;
+}
+
+static inline void encode(Encoder *encoder, unsigned int word, unsigned int len)
+{
+ int delta;
+
+ spice_assert(len > 0 && len < 32);
+ spice_assert(!(word & ~bppmask[len]));
+ if ((delta = ((int)encoder->io_available_bits - len)) >= 0) {
+ encoder->io_available_bits = delta;
+ encoder->io_word |= word << encoder->io_available_bits;
+ return;
+ }
+ delta = -delta;
+ encoder->io_word |= word >> delta;
+ write_io_word(encoder);
+ encoder->io_available_bits = 32 - delta;
+ encoder->io_word = word << encoder->io_available_bits;
+
+ spice_assert(encoder->io_available_bits < 32);
+ spice_assert((encoder->io_word & bppmask[encoder->io_available_bits]) == 0);
+}
+
+static inline void encode_32(Encoder *encoder, unsigned int word)
+{
+ encode(encoder, word >> 16, 16);
+ encode(encoder, word & 0x0000ffff, 16);
+}
+
+static inline void flush(Encoder *encoder)
+{
+ if (encoder->io_available_bits > 0 && encoder->io_available_bits != 32) {
+ encode(encoder, 0, encoder->io_available_bits);
+ }
+ encode_32(encoder, 0);
+ encode(encoder, 0, 1);
+}
+
+static void __read_io_word(Encoder *encoder)
+{
+ more_io_words(encoder);
+ encoder->io_next_word = GUINT32_FROM_LE(*(encoder->io_now++));
+}
+
+static void (*__read_io_word_ptr)(Encoder *encoder) = __read_io_word;
+
+
+static inline void read_io_word(Encoder *encoder)
+{
+ if (encoder->io_now == encoder->io_end) {
+ __read_io_word_ptr(encoder); //disable inline optimizations
+ return;
+ }
+ spice_assert(encoder->io_now < encoder->io_end);
+ encoder->io_next_word = GUINT32_FROM_LE(*(encoder->io_now++));
+}
+
+static inline void decode_eatbits(Encoder *encoder, int len)
+{
+ int delta;
+
+ spice_assert(len > 0 && len < 32);
+ encoder->io_word <<= len;
+
+ if ((delta = ((int)encoder->io_available_bits - len)) >= 0) {
+ encoder->io_available_bits = delta;
+ encoder->io_word |= encoder->io_next_word >> encoder->io_available_bits;
+ return;
+ }
+
+ delta = -delta;
+ encoder->io_word |= encoder->io_next_word << delta;
+ read_io_word(encoder);
+ encoder->io_available_bits = 32 - delta;
+ encoder->io_word |= (encoder->io_next_word >> encoder->io_available_bits);
+}
+
+static inline void decode_eat32bits(Encoder *encoder)
+{
+ decode_eatbits(encoder, 16);
+ decode_eatbits(encoder, 16);
+}
+
+#ifdef RLE
+
+#ifdef RLE_STAT
+
+static inline void encode_ones(Encoder *encoder, unsigned int n)
+{
+ unsigned int count;
+
+ for (count = n >> 5; count; count--) {
+ encode(encoder, ~0U, 32);
+ }
+
+ if ((n &= 0x1f)) {
+ encode(encoder, (1U << n) - 1, n);
+ }
+}
+
+#define MELCSTATES 32 /* number of melcode states */
+
+static const int J[MELCSTATES] = {
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+static void encoder_init_rle(CommonState *state)
+{
+ state->melcstate = 0;
+ state->melclen = J[0];
+ state->melcorder = 1 << state->melclen;
+}
+
+#ifdef QUIC_RGB
+
+static void encode_run(Encoder *encoder, unsigned int runlen) //todo: try use end of line
+{
+ int hits = 0;
+
+ while (runlen >= encoder->rgb_state.melcorder) {
+ hits++;
+ runlen -= encoder->rgb_state.melcorder;
+ if (encoder->rgb_state.melcstate < MELCSTATES - 1) {
+ encoder->rgb_state.melclen = J[++encoder->rgb_state.melcstate];
+ encoder->rgb_state.melcorder = (1L << encoder->rgb_state.melclen);
+ }
+ }
+
+ /* send the required number of "hit" bits (one per occurrence
+ of a run of length melcorder). This number is never too big:
+ after 31 such "hit" bits, each "hit" would represent a run of 32K
+ pixels.
+ */
+ encode_ones(encoder, hits);
+
+ encode(encoder, runlen, encoder->rgb_state.melclen + 1);
+
+ /* adjust melcoder parameters */
+ if (encoder->rgb_state.melcstate) {
+ encoder->rgb_state.melclen = J[--encoder->rgb_state.melcstate];
+ encoder->rgb_state.melcorder = (1L << encoder->rgb_state.melclen);
+ }
+}
+
+#endif
+
+static void encode_channel_run(Encoder *encoder, Channel *channel, unsigned int runlen)
+{
+ //todo: try use end of line
+ int hits = 0;
+
+ while (runlen >= channel->state.melcorder) {
+ hits++;
+ runlen -= channel->state.melcorder;
+ if (channel->state.melcstate < MELCSTATES - 1) {
+ channel->state.melclen = J[++channel->state.melcstate];
+ channel->state.melcorder = (1L << channel->state.melclen);
+ }
+ }
+
+ /* send the required number of "hit" bits (one per occurrence
+ of a run of length melcorder). This number is never too big:
+ after 31 such "hit" bits, each "hit" would represent a run of 32K
+ pixels.
+ */
+ encode_ones(encoder, hits);
+
+ encode(encoder, runlen, channel->state.melclen + 1);
+
+ /* adjust melcoder parameters */
+ if (channel->state.melcstate) {
+ channel->state.melclen = J[--channel->state.melcstate];
+ channel->state.melcorder = (1L << channel->state.melclen);
+ }
+}
+
+/* decoding routine: reads bits from the input and returns a run length. */
+/* argument is the number of pixels left to end-of-line (bound on run length) */
+
+#ifdef QUIC_RGB
+static int decode_run(Encoder *encoder)
+{
+ int runlen = 0;
+
+ do {
+ register int temp, hits;
+ temp = lzeroes[(BYTE)(~(encoder->io_word >> 24))];/* number of leading ones in the
+ input stream, up to 8 */
+ for (hits = 1; hits <= temp; hits++) {
+ runlen += encoder->rgb_state.melcorder;
+
+ if (encoder->rgb_state.melcstate < MELCSTATES - 1) {
+ encoder->rgb_state.melclen = J[++encoder->rgb_state.melcstate];
+ encoder->rgb_state.melcorder = (1U << encoder->rgb_state.melclen);
+ }
+ }
+ if (temp != 8) {
+ decode_eatbits(encoder, temp + 1); /* consume the leading
+ 0 of the remainder encoding */
+ break;
+ }
+ decode_eatbits(encoder, 8);
+ } while (1);
+
+ /* read the length of the remainder */
+ if (encoder->rgb_state.melclen) {
+ runlen += encoder->io_word >> (32 - encoder->rgb_state.melclen);
+ decode_eatbits(encoder, encoder->rgb_state.melclen);
+ }
+
+ /* adjust melcoder parameters */
+ if (encoder->rgb_state.melcstate) {
+ encoder->rgb_state.melclen = J[--encoder->rgb_state.melcstate];
+ encoder->rgb_state.melcorder = (1U << encoder->rgb_state.melclen);
+ }
+
+ return runlen;
+}
+
+#endif
+
+static int decode_channel_run(Encoder *encoder, Channel *channel)
+{
+ int runlen = 0;
+
+ do {
+ register int temp, hits;
+ temp = lzeroes[(BYTE)(~(encoder->io_word >> 24))];/* number of leading ones in the
+ input stream, up to 8 */
+ for (hits = 1; hits <= temp; hits++) {
+ runlen += channel->state.melcorder;
+
+ if (channel->state.melcstate < MELCSTATES - 1) {
+ channel->state.melclen = J[++channel->state.melcstate];
+ channel->state.melcorder = (1U << channel->state.melclen);
+ }
+ }
+ if (temp != 8) {
+ decode_eatbits(encoder, temp + 1); /* consume the leading
+ 0 of the remainder encoding */
+ break;
+ }
+ decode_eatbits(encoder, 8);
+ } while (1);
+
+ /* read the length of the remainder */
+ if (channel->state.melclen) {
+ runlen += encoder->io_word >> (32 - channel->state.melclen);
+ decode_eatbits(encoder, channel->state.melclen);
+ }
+
+ /* adjust melcoder parameters */
+ if (channel->state.melcstate) {
+ channel->state.melclen = J[--channel->state.melcstate];
+ channel->state.melcorder = (1U << channel->state.melclen);
+ }
+
+ return runlen;
+}
+
+#else
+
+static inline void encode_run(Encoder *encoder, unsigned int len)
+{
+ int odd = len & 1U;
+ int msb;
+
+ len &= ~1U;
+
+ while ((msb = spice_bit_find_msb(len))) {
+ len &= ~(1 << (msb - 1));
+ spice_assert(msb < 32);
+ encode(encoder, (1 << (msb)) - 1, msb);
+ encode(encoder, 0, 1);
+ }
+
+ if (odd) {
+ encode(encoder, 2, 2);
+ } else {
+ encode(encoder, 0, 1);
+ }
+}
+
+static inline unsigned int decode_run(Encoder *encoder)
+{
+ unsigned int len = 0;
+ int count;
+
+ do {
+ count = 0;
+ while (encoder->io_word & (1U << 31)) {
+ decode_eatbits(encoder, 1);
+ count++;
+ spice_assert(count < 32);
+ }
+ decode_eatbits(encoder, 1);
+ len += (1U << count) >> 1;
+ } while (count > 1);
+
+ return len;
+}
+
+#endif
+#endif
+
+static inline void init_decode_io(Encoder *encoder)
+{
+ encoder->io_next_word = encoder->io_word = GUINT32_FROM_LE(*(encoder->io_now++));
+ encoder->io_available_bits = 0;
+}
+
+#ifdef __GNUC__
+#define ATTR_PACKED __attribute__ ((__packed__))
+#else
+#define ATTR_PACKED
+#pragma pack(push)
+#pragma pack(1)
+#endif
+
+typedef struct ATTR_PACKED one_byte_pixel_t {
+ BYTE a;
+} one_byte_t;
+
+typedef struct ATTR_PACKED three_bytes_pixel_t {
+ BYTE a;
+ BYTE b;
+ BYTE c;
+} three_bytes_t;
+
+typedef struct ATTR_PACKED four_bytes_pixel_t {
+ BYTE a;
+ BYTE b;
+ BYTE c;
+ BYTE d;
+} four_bytes_t;
+
+typedef struct ATTR_PACKED rgb32_pixel_t {
+ BYTE b;
+ BYTE g;
+ BYTE r;
+ BYTE pad;
+} rgb32_pixel_t;
+
+typedef struct ATTR_PACKED rgb24_pixel_t {
+ BYTE b;
+ BYTE g;
+ BYTE r;
+} rgb24_pixel_t;
+
+typedef uint16_t rgb16_pixel_t;
+
+#ifndef __GNUC__
+#pragma pack(pop)
+#endif
+
+#undef ATTR_PACKED
+
+#define ONE_BYTE
+#include "quic_tmpl.c"
+
+#define FOUR_BYTE
+#include "quic_tmpl.c"
+
+#ifdef QUIC_RGB
+
+#define QUIC_RGB32
+#include "quic_rgb_tmpl.c"
+
+#define QUIC_RGB24
+#include "quic_rgb_tmpl.c"
+
+#define QUIC_RGB16
+#include "quic_rgb_tmpl.c"
+
+#define QUIC_RGB16_TO_32
+#include "quic_rgb_tmpl.c"
+
+#else
+
+#define THREE_BYTE
+#include "quic_tmpl.c"
+
+#endif
+
+static void fill_model_structures(SPICE_GNUC_UNUSED Encoder *encoder, FamilyStat *family_stat,
+ unsigned int rep_first, unsigned int first_size,
+ unsigned int rep_next, unsigned int mul_size,
+ unsigned int levels, unsigned int ncounters,
+ unsigned int nbuckets, unsigned int n_buckets_ptrs)
+{
+ unsigned int
+ bsize,
+ bstart,
+ bend = 0,
+ repcntr,
+ bnumber;
+
+ COUNTER * free_counter = family_stat->counters;/* first free location in the array of
+ counters */
+
+ bnumber = 0;
+
+ repcntr = rep_first + 1; /* first bucket */
+ bsize = first_size;
+
+ do { /* others */
+ if (bnumber) {
+ bstart = bend + 1;
+ } else {
+ bstart = 0;
+ }
+
+ if (!--repcntr) {
+ repcntr = rep_next;
+ bsize *= mul_size;
+ }
+
+ bend = bstart + bsize - 1;
+ if (bend + bsize >= levels) {
+ bend = levels - 1;
+ }
+
+ family_stat->buckets_buf[bnumber].pcounters = free_counter;
+ free_counter += ncounters;
+
+ spice_assert(bstart < n_buckets_ptrs);
+ {
+ unsigned int i;
+ spice_assert(bend < n_buckets_ptrs);
+ for (i = bstart; i <= bend; i++) {
+ family_stat->buckets_ptrs[i] = family_stat->buckets_buf + bnumber;
+ }
+ }
+
+ bnumber++;
+ } while (bend < levels - 1);
+
+ spice_assert(free_counter - family_stat->counters == nbuckets * ncounters);
+}
+
+static void find_model_params(Encoder *encoder,
+ const int bpc,
+ unsigned int *ncounters,
+ unsigned int *levels,
+ unsigned int *n_buckets_ptrs,
+ unsigned int *repfirst,
+ unsigned int *firstsize,
+ unsigned int *repnext,
+ unsigned int *mulsize,
+ unsigned int *nbuckets)
+{
+ unsigned int bsize; /* bucket size */
+ unsigned int bstart, bend = 0; /* bucket start and end, range : 0 to levels-1*/
+ unsigned int repcntr; /* helper */
+
+ /* The only valid values are 1, 3 and 5.
+ 0, 2 and 4 are obsolete and the rest of the
+ values are considered out of the range. */
+ spice_static_assert (evol == 1 || evol == 3 || evol == 5);
+ spice_assert(bpc <= 8 && bpc > 0);
+
+ *ncounters = 8;
+
+ *levels = 0x1 << bpc;
+
+ *n_buckets_ptrs = 0; /* ==0 means: not set yet */
+
+ switch (evol) { /* set repfirst firstsize repnext mulsize */
+ case 1: /* buckets contain following numbers of contexts: 1 1 1 2 2 4 4 8 8 ... */
+ *repfirst = 3;
+ *firstsize = 1;
+ *repnext = 2;
+ *mulsize = 2;
+ break;
+ case 3: /* 1 2 4 8 16 32 64 ... */
+ *repfirst = 1;
+ *firstsize = 1;
+ *repnext = 1;
+ *mulsize = 2;
+ break;
+ case 5: /* 1 4 16 64 256 1024 4096 16384 65536 */
+ *repfirst = 1;
+ *firstsize = 1;
+ *repnext = 1;
+ *mulsize = 4;
+ break;
+ default:
+ encoder->usr->error(encoder->usr, "findmodelparams(): evol out of range!!!\n");
+ return;
+ }
+
+ *nbuckets = 0;
+ repcntr = *repfirst + 1; /* first bucket */
+ bsize = *firstsize;
+
+ do { /* other buckets */
+ if (*nbuckets) { /* bucket start */
+ bstart = bend + 1;
+ } else {
+ bstart = 0;
+ }
+
+ if (!--repcntr) { /* bucket size */
+ repcntr = *repnext;
+ bsize *= *mulsize;
+ }
+
+ bend = bstart + bsize - 1; /* bucket end */
+ if (bend + bsize >= *levels) { /* if following bucked was bigger than current one */
+ bend = *levels - 1; /* concatenate them */
+ }
+
+ if (!*n_buckets_ptrs) { /* array size not set yet? */
+ *n_buckets_ptrs = *levels;
+ #if 0
+ if (bend == *levels - 1) { /* this bucket is last - all in the first array */
+ *n_buckets_ptrs = *levels;
+ } else if (bsize >= 256) { /* this bucket is allowed to reside in the 2nd table */
+ b_lo_ptrs = bstart;
+ spice_assert(bstart); /* previous bucket exists */
+ }
+ #endif
+ }
+
+ (*nbuckets)++;
+ } while (bend < *levels - 1);
+}
+
+static int init_model_structures(Encoder *encoder, FamilyStat *family_stat,
+ unsigned int rep_first, unsigned int first_size,
+ unsigned int rep_next, unsigned int mul_size,
+ unsigned int levels, unsigned int ncounters,
+ unsigned int n_buckets_ptrs, unsigned int n_buckets)
+{
+ family_stat->buckets_ptrs = (s_bucket **)encoder->usr->malloc(encoder->usr,
+ n_buckets_ptrs *
+ sizeof(s_bucket *));
+ if (!family_stat->buckets_ptrs) {
+ return FALSE;
+ }
+
+ family_stat->counters = (COUNTER *)encoder->usr->malloc(encoder->usr,
+ n_buckets * sizeof(COUNTER) *
+ MAXNUMCODES);
+ if (!family_stat->counters) {
+ goto error_1;
+ }
+
+ family_stat->buckets_buf = (s_bucket *)encoder->usr->malloc(encoder->usr,
+ n_buckets * sizeof(s_bucket));
+ if (!family_stat->buckets_buf) {
+ goto error_2;
+ }
+
+ fill_model_structures(encoder, family_stat, rep_first, first_size, rep_next, mul_size, levels,
+ ncounters, n_buckets, n_buckets_ptrs);
+
+ return TRUE;
+
+error_2:
+ encoder->usr->free(encoder->usr, family_stat->counters);
+
+error_1:
+ encoder->usr->free(encoder->usr, family_stat->buckets_ptrs);
+
+ return FALSE;
+}
+
+static void free_family_stat(QuicUsrContext *usr, FamilyStat *family_stat)
+{
+ usr->free(usr, family_stat->buckets_ptrs);
+ usr->free(usr, family_stat->counters);
+ usr->free(usr, family_stat->buckets_buf);
+}
+
+static int init_channel(Encoder *encoder, Channel *channel)
+{
+ unsigned int ncounters;
+ unsigned int levels;
+ unsigned int rep_first;
+ unsigned int first_size;
+ unsigned int rep_next;
+ unsigned int mul_size;
+ unsigned int n_buckets;
+ unsigned int n_buckets_ptrs;
+
+ channel->encoder = encoder;
+ channel->state.encoder = encoder;
+ channel->correlate_row_width = 0;
+ channel->correlate_row = NULL;
+
+ find_model_params(encoder, 8, &ncounters, &levels, &n_buckets_ptrs, &rep_first,
+ &first_size, &rep_next, &mul_size, &n_buckets);
+ encoder->n_buckets_8bpc = n_buckets;
+ if (!init_model_structures(encoder, &channel->family_stat_8bpc, rep_first, first_size,
+ rep_next, mul_size, levels, ncounters, n_buckets_ptrs,
+ n_buckets)) {
+ return FALSE;
+ }
+
+ find_model_params(encoder, 5, &ncounters, &levels, &n_buckets_ptrs, &rep_first,
+ &first_size, &rep_next, &mul_size, &n_buckets);
+ encoder->n_buckets_5bpc = n_buckets;
+ if (!init_model_structures(encoder, &channel->family_stat_5bpc, rep_first, first_size,
+ rep_next, mul_size, levels, ncounters, n_buckets_ptrs,
+ n_buckets)) {
+ free_family_stat(encoder->usr, &channel->family_stat_8bpc);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void destroy_channel(Channel *channel)
+{
+ QuicUsrContext *usr = channel->encoder->usr;
+ if (channel->correlate_row) {
+ usr->free(usr, channel->correlate_row - 1);
+ }
+ free_family_stat(usr, &channel->family_stat_8bpc);
+ free_family_stat(usr, &channel->family_stat_5bpc);
+}
+
+static int init_encoder(Encoder *encoder, QuicUsrContext *usr)
+{
+ int i;
+
+ encoder->usr = usr;
+ encoder->rgb_state.encoder = encoder;
+
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (!init_channel(encoder, &encoder->channels[i])) {
+ for (--i; i >= 0; i--) {
+ destroy_channel(&encoder->channels[i]);
+ }
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static int encoder_reste(Encoder *encoder, uint32_t *io_ptr, uint32_t *io_ptr_end)
+{
+ spice_assert(((uintptr_t)io_ptr % 4) == ((uintptr_t)io_ptr_end % 4));
+ spice_assert(io_ptr <= io_ptr_end);
+
+ encoder->rgb_state.waitcnt = 0;
+ encoder->rgb_state.tabrand_seed = stabrand();
+ encoder->rgb_state.wmidx = DEFwmistart;
+ encoder->rgb_state.wmileft = wminext;
+ set_wm_trigger(&encoder->rgb_state);
+
+#if defined(RLE) && defined(RLE_STAT)
+ encoder_init_rle(&encoder->rgb_state);
+#endif
+
+ encoder->io_words_count = io_ptr_end - io_ptr;
+ encoder->io_now = io_ptr;
+ encoder->io_end = io_ptr_end;
+ encoder->rows_completed = 0;
+
+ return TRUE;
+}
+
+static int encoder_reste_channels(Encoder *encoder, int channels, int width, int bpc)
+{
+ int i;
+
+ encoder->num_channels = channels;
+
+ for (i = 0; i < channels; i++) {
+ s_bucket *bucket;
+ s_bucket *end_bucket;
+
+ if (encoder->channels[i].correlate_row_width < width) {
+ encoder->channels[i].correlate_row_width = 0;
+ if (encoder->channels[i].correlate_row) {
+ encoder->usr->free(encoder->usr, encoder->channels[i].correlate_row - 1);
+ }
+ if (!(encoder->channels[i].correlate_row = (BYTE *)encoder->usr->malloc(encoder->usr,
+ width + 1))) {
+ return FALSE;
+ }
+ encoder->channels[i].correlate_row++;
+ encoder->channels[i].correlate_row_width = width;
+ }
+
+ if (bpc == 8) {
+ MEMCLEAR(encoder->channels[i].family_stat_8bpc.counters,
+ encoder->n_buckets_8bpc * sizeof(COUNTER) * MAXNUMCODES);
+ bucket = encoder->channels[i].family_stat_8bpc.buckets_buf;
+ end_bucket = bucket + encoder->n_buckets_8bpc;
+ for (; bucket < end_bucket; bucket++) {
+ bucket->bestcode = /*BPC*/ 8 - 1;
+ }
+ encoder->channels[i]._buckets_ptrs = encoder->channels[i].family_stat_8bpc.buckets_ptrs;
+ } else if (bpc == 5) {
+ MEMCLEAR(encoder->channels[i].family_stat_5bpc.counters,
+ encoder->n_buckets_5bpc * sizeof(COUNTER) * MAXNUMCODES);
+ bucket = encoder->channels[i].family_stat_5bpc.buckets_buf;
+ end_bucket = bucket + encoder->n_buckets_5bpc;
+ for (; bucket < end_bucket; bucket++) {
+ bucket->bestcode = /*BPC*/ 5 - 1;
+ }
+ encoder->channels[i]._buckets_ptrs = encoder->channels[i].family_stat_5bpc.buckets_ptrs;
+ } else {
+ encoder->usr->warn(encoder->usr, "%s: bad bpc %d\n", __FUNCTION__, bpc);
+ return FALSE;
+ }
+
+ encoder->channels[i].state.waitcnt = 0;
+ encoder->channels[i].state.tabrand_seed = stabrand();
+ encoder->channels[i].state.wmidx = DEFwmistart;
+ encoder->channels[i].state.wmileft = wminext;
+ set_wm_trigger(&encoder->channels[i].state);
+
+#if defined(RLE) && defined(RLE_STAT)
+ encoder_init_rle(&encoder->channels[i].state);
+#endif
+ }
+ return TRUE;
+}
+
+static void quic_image_params(Encoder *encoder, QuicImageType type, int *channels, int *bpc)
+{
+ spice_assert(channels && bpc);
+ switch (type) {
+ case QUIC_IMAGE_TYPE_GRAY:
+ *channels = 1;
+ *bpc = 8;
+ break;
+ case QUIC_IMAGE_TYPE_RGB16:
+ *channels = 3;
+ *bpc = 5;
+#ifndef QUIC_RGB
+ encoder->usr->error(encoder->usr, "not implemented\n");
+#endif
+ break;
+ case QUIC_IMAGE_TYPE_RGB24:
+ *channels = 3;
+ *bpc = 8;
+ break;
+ case QUIC_IMAGE_TYPE_RGB32:
+ *channels = 3;
+ *bpc = 8;
+ break;
+ case QUIC_IMAGE_TYPE_RGBA:
+ *channels = 4;
+ *bpc = 8;
+ break;
+ case QUIC_IMAGE_TYPE_INVALID:
+ default:
+ *channels = 0;
+ *bpc = 0;
+ encoder->usr->error(encoder->usr, "bad image type\n");
+ }
+}
+
+#define FILL_LINES() { \
+ if (line == lines_end) { \
+ int n = encoder->usr->more_lines(encoder->usr, &line); \
+ if (n <= 0 || line == NULL) { \
+ encoder->usr->error(encoder->usr, "more lines failed\n"); \
+ } \
+ lines_end = line + n * stride; \
+ } \
+}
+
+#define NEXT_LINE() { \
+ line += stride; \
+ FILL_LINES(); \
+}
+
+#define QUIC_COMPRESS_RGB(bits) \
+ encoder->channels[0].correlate_row[-1] = 0; \
+ encoder->channels[1].correlate_row[-1] = 0; \
+ encoder->channels[2].correlate_row[-1] = 0; \
+ quic_rgb##bits##_compress_row0(encoder, (rgb##bits##_pixel_t *)(line), width); \
+ encoder->rows_completed++; \
+ for (row = 1; row < height; row++) { \
+ prev = line; \
+ NEXT_LINE(); \
+ encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0]; \
+ encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0]; \
+ encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0]; \
+ quic_rgb##bits##_compress_row(encoder, (rgb##bits##_pixel_t *)prev, \
+ (rgb##bits##_pixel_t *)line, width); \
+ encoder->rows_completed++; \
+ }
+
+int quic_encode(QuicContext *quic, QuicImageType type, int width, int height,
+ uint8_t *line, unsigned int num_lines, int stride,
+ uint32_t *io_ptr, unsigned int num_io_words)
+{
+ Encoder *encoder = (Encoder *)quic;
+ uint32_t *io_ptr_end = io_ptr + num_io_words;
+ uint8_t *lines_end;
+ int row;
+ uint8_t *prev;
+ int channels;
+ int bpc;
+#ifndef QUIC_RGB
+ int i;
+#endif
+
+ lines_end = line + num_lines * stride;
+ if (line == NULL && lines_end != line) {
+ spice_warn_if_reached();
+ return QUIC_ERROR;
+ }
+
+ quic_image_params(encoder, type, &channels, &bpc);
+
+ if (!encoder_reste(encoder, io_ptr, io_ptr_end) ||
+ !encoder_reste_channels(encoder, channels, width, bpc)) {
+ return QUIC_ERROR;
+ }
+
+ encoder->io_word = 0;
+ encoder->io_available_bits = 32;
+
+ encode_32(encoder, QUIC_MAGIC);
+ encode_32(encoder, QUIC_VERSION);
+ encode_32(encoder, type);
+ encode_32(encoder, width);
+ encode_32(encoder, height);
+
+ FILL_LINES();
+
+ switch (type) {
+#ifdef QUIC_RGB
+ case QUIC_IMAGE_TYPE_RGB32:
+ spice_assert(ABS(stride) >= width * 4);
+ QUIC_COMPRESS_RGB(32);
+ break;
+ case QUIC_IMAGE_TYPE_RGB24:
+ spice_assert(ABS(stride) >= width * 3);
+ QUIC_COMPRESS_RGB(24);
+ break;
+ case QUIC_IMAGE_TYPE_RGB16:
+ spice_assert(ABS(stride) >= width * 2);
+ QUIC_COMPRESS_RGB(16);
+ break;
+ case QUIC_IMAGE_TYPE_RGBA:
+ spice_assert(ABS(stride) >= width * 4);
+
+ encoder->channels[0].correlate_row[-1] = 0;
+ encoder->channels[1].correlate_row[-1] = 0;
+ encoder->channels[2].correlate_row[-1] = 0;
+ quic_rgb32_compress_row0(encoder, (rgb32_pixel_t *)(line), width);
+
+ encoder->channels[3].correlate_row[-1] = 0;
+ quic_four_compress_row0(encoder, &encoder->channels[3], (four_bytes_t *)(line + 3), width);
+
+ encoder->rows_completed++;
+
+ for (row = 1; row < height; row++) {
+ prev = line;
+ NEXT_LINE();
+ encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
+ encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];
+ encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];
+ quic_rgb32_compress_row(encoder, (rgb32_pixel_t *)prev, (rgb32_pixel_t *)line, width);
+
+ encoder->channels[3].correlate_row[-1] = encoder->channels[3].correlate_row[0];
+ quic_four_compress_row(encoder, &encoder->channels[3], (four_bytes_t *)(prev + 3),
+ (four_bytes_t *)(line + 3), width);
+ encoder->rows_completed++;
+ }
+ break;
+#else
+ case QUIC_IMAGE_TYPE_RGB24:
+ spice_assert(ABS(stride) >= width * 3);
+ for (i = 0; i < 3; i++) {
+ encoder->channels[i].correlate_row[-1] = 0;
+ quic_three_compress_row0(encoder, &encoder->channels[i], (three_bytes_t *)(line + i),
+ width);
+ }
+ encoder->rows_completed++;
+ for (row = 1; row < height; row++) {
+ prev = line;
+ NEXT_LINE();
+ for (i = 0; i < 3; i++) {
+ encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
+ quic_three_compress_row(encoder, &encoder->channels[i], (three_bytes_t *)(prev + i),
+ (three_bytes_t *)(line + i), width);
+ }
+ encoder->rows_completed++;
+ }
+ break;
+ case QUIC_IMAGE_TYPE_RGB32:
+ case QUIC_IMAGE_TYPE_RGBA:
+ spice_assert(ABS(stride) >= width * 4);
+ for (i = 0; i < channels; i++) {
+ encoder->channels[i].correlate_row[-1] = 0;
+ quic_four_compress_row0(encoder, &encoder->channels[i], (four_bytes_t *)(line + i),
+ width);
+ }
+ encoder->rows_completed++;
+ for (row = 1; row < height; row++) {
+ prev = line;
+ NEXT_LINE();
+ for (i = 0; i < channels; i++) {
+ encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
+ quic_four_compress_row(encoder, &encoder->channels[i], (four_bytes_t *)(prev + i),
+ (four_bytes_t *)(line + i), width);
+ }
+ encoder->rows_completed++;
+ }
+ break;
+#endif
+ case QUIC_IMAGE_TYPE_GRAY:
+ spice_assert(ABS(stride) >= width);
+ encoder->channels[0].correlate_row[-1] = 0;
+ quic_one_compress_row0(encoder, &encoder->channels[0], (one_byte_t *)line, width);
+ encoder->rows_completed++;
+ for (row = 1; row < height; row++) {
+ prev = line;
+ NEXT_LINE();
+ encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
+ quic_one_compress_row(encoder, &encoder->channels[0], (one_byte_t *)prev,
+ (one_byte_t *)line, width);
+ encoder->rows_completed++;
+ }
+ break;
+ case QUIC_IMAGE_TYPE_INVALID:
+ default:
+ encoder->usr->error(encoder->usr, "bad image type\n");
+ }
+
+ flush(encoder);
+ encoder->io_words_count -= (encoder->io_end - encoder->io_now);
+
+ return encoder->io_words_count;
+}
+
+int quic_decode_begin(QuicContext *quic, uint32_t *io_ptr, unsigned int num_io_words,
+ QuicImageType *out_type, int *out_width, int *out_height)
+{
+ Encoder *encoder = (Encoder *)quic;
+ uint32_t *io_ptr_end = io_ptr + num_io_words;
+ QuicImageType type;
+ int width;
+ int height;
+ uint32_t magic;
+ uint32_t version;
+ int channels;
+ int bpc;
+
+ if (!encoder_reste(encoder, io_ptr, io_ptr_end)) {
+ return QUIC_ERROR;
+ }
+
+ init_decode_io(encoder);
+
+ magic = encoder->io_word;
+ decode_eat32bits(encoder);
+ if (magic != QUIC_MAGIC) {
+ encoder->usr->warn(encoder->usr, "bad magic\n");
+ return QUIC_ERROR;
+ }
+
+ version = encoder->io_word;
+ decode_eat32bits(encoder);
+ if (version != QUIC_VERSION) {
+ encoder->usr->warn(encoder->usr, "bad version\n");
+ return QUIC_ERROR;
+ }
+
+ type = (QuicImageType)encoder->io_word;
+ decode_eat32bits(encoder);
+
+ width = encoder->io_word;
+ decode_eat32bits(encoder);
+
+ height = encoder->io_word;
+ decode_eat32bits(encoder);
+
+ quic_image_params(encoder, type, &channels, &bpc);
+
+ if (!encoder_reste_channels(encoder, channels, width, bpc)) {
+ return QUIC_ERROR;
+ }
+
+ *out_width = encoder->width = width;
+ *out_height = encoder->height = height;
+ *out_type = encoder->type = type;
+ return QUIC_OK;
+}
+
+#ifndef QUIC_RGB
+static void clear_row(four_bytes_t *row, int width)
+{
+ four_bytes_t *end;
+ for (end = row + width; row < end; row++) {
+ row->a = 0;
+ }
+}
+
+#endif
+
+#ifdef QUIC_RGB
+
+static void uncompress_rgba(Encoder *encoder, uint8_t *buf, int stride)
+{
+ unsigned int row;
+ uint8_t *prev;
+
+ encoder->channels[0].correlate_row[-1] = 0;
+ encoder->channels[1].correlate_row[-1] = 0;
+ encoder->channels[2].correlate_row[-1] = 0;
+ quic_rgb32_uncompress_row0(encoder, (rgb32_pixel_t *)buf, encoder->width);
+
+ encoder->channels[3].correlate_row[-1] = 0;
+ quic_four_uncompress_row0(encoder, &encoder->channels[3], (four_bytes_t *)(buf + 3),
+ encoder->width);
+
+ encoder->rows_completed++;
+ for (row = 1; row < encoder->height; row++) {
+ prev = buf;
+ buf += stride;
+
+ encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
+ encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0];
+ encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0];
+ quic_rgb32_uncompress_row(encoder, (rgb32_pixel_t *)prev, (rgb32_pixel_t *)buf,
+ encoder->width);
+
+ encoder->channels[3].correlate_row[-1] = encoder->channels[3].correlate_row[0];
+ quic_four_uncompress_row(encoder, &encoder->channels[3], (four_bytes_t *)(prev + 3),
+ (four_bytes_t *)(buf + 3), encoder->width);
+
+ encoder->rows_completed++;
+ }
+}
+
+#endif
+
+static void uncompress_gray(Encoder *encoder, uint8_t *buf, int stride)
+{
+ unsigned int row;
+ uint8_t *prev;
+
+ encoder->channels[0].correlate_row[-1] = 0;
+ quic_one_uncompress_row0(encoder, &encoder->channels[0], (one_byte_t *)buf, encoder->width);
+ encoder->rows_completed++;
+ for (row = 1; row < encoder->height; row++) {
+ prev = buf;
+ buf += stride;
+ encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0];
+ quic_one_uncompress_row(encoder, &encoder->channels[0], (one_byte_t *)prev,
+ (one_byte_t *)buf, encoder->width);
+ encoder->rows_completed++;
+ }
+}
+
+#define QUIC_UNCOMPRESS_RGB(prefix, type) \
+ encoder->channels[0].correlate_row[-1] = 0; \
+ encoder->channels[1].correlate_row[-1] = 0; \
+ encoder->channels[2].correlate_row[-1] = 0; \
+ quic_rgb##prefix##_uncompress_row0(encoder, (type *)buf, encoder->width); \
+ encoder->rows_completed++; \
+ for (row = 1; row < encoder->height; row++) { \
+ prev = buf; \
+ buf += stride; \
+ encoder->channels[0].correlate_row[-1] = encoder->channels[0].correlate_row[0]; \
+ encoder->channels[1].correlate_row[-1] = encoder->channels[1].correlate_row[0]; \
+ encoder->channels[2].correlate_row[-1] = encoder->channels[2].correlate_row[0]; \
+ quic_rgb##prefix##_uncompress_row(encoder, (type *)prev, (type *)buf, \
+ encoder->width); \
+ encoder->rows_completed++; \
+ }
+
+int quic_decode(QuicContext *quic, QuicImageType type, uint8_t *buf, int stride)
+{
+ Encoder *encoder = (Encoder *)quic;
+ unsigned int row;
+ uint8_t *prev;
+#ifndef QUIC_RGB
+ int i;
+#endif
+
+ spice_assert(buf);
+
+ switch (encoder->type) {
+#ifdef QUIC_RGB
+ case QUIC_IMAGE_TYPE_RGB32:
+ case QUIC_IMAGE_TYPE_RGB24:
+ if (type == QUIC_IMAGE_TYPE_RGB32) {
+ spice_assert(ABS(stride) >= (int)encoder->width * 4);
+ QUIC_UNCOMPRESS_RGB(32, rgb32_pixel_t);
+ break;
+ } else if (type == QUIC_IMAGE_TYPE_RGB24) {
+ spice_assert(ABS(stride) >= (int)encoder->width * 3);
+ QUIC_UNCOMPRESS_RGB(24, rgb24_pixel_t);
+ break;
+ }
+ encoder->usr->warn(encoder->usr, "unsupported output format\n");
+ return QUIC_ERROR;
+ case QUIC_IMAGE_TYPE_RGB16:
+ if (type == QUIC_IMAGE_TYPE_RGB16) {
+ spice_assert(ABS(stride) >= (int)encoder->width * 2);
+ QUIC_UNCOMPRESS_RGB(16, rgb16_pixel_t);
+ } else if (type == QUIC_IMAGE_TYPE_RGB32) {
+ spice_assert(ABS(stride) >= (int)encoder->width * 4);
+ QUIC_UNCOMPRESS_RGB(16_to_32, rgb32_pixel_t);
+ } else {
+ encoder->usr->warn(encoder->usr, "unsupported output format\n");
+ return QUIC_ERROR;
+ }
+
+ break;
+ case QUIC_IMAGE_TYPE_RGBA:
+
+ if (type != QUIC_IMAGE_TYPE_RGBA) {
+ encoder->usr->warn(encoder->usr, "unsupported output format\n");
+ return QUIC_ERROR;
+ }
+ spice_assert(ABS(stride) >= (int)encoder->width * 4);
+ uncompress_rgba(encoder, buf, stride);
+ break;
+#else
+ case QUIC_IMAGE_TYPE_RGB24:
+ spice_assert(ABS(stride) >= (int)encoder->width * 3);
+ for (i = 0; i < 3; i++) {
+ encoder->channels[i].correlate_row[-1] = 0;
+ quic_three_uncompress_row0(encoder, &encoder->channels[i], (three_bytes_t *)(buf + i),
+ encoder->width);
+ }
+ encoder->rows_completed++;
+ for (row = 1; row < encoder->height; row++) {
+ prev = buf;
+ buf += stride;
+ for (i = 0; i < 3; i++) {
+ encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
+ quic_three_uncompress_row(encoder, &encoder->channels[i],
+ (three_bytes_t *)(prev + i),
+ (three_bytes_t *)(buf + i),
+ encoder->width);
+ }
+ encoder->rows_completed++;
+ }
+ break;
+ case QUIC_IMAGE_TYPE_RGB32:
+ spice_assert(ABS(stride) >= encoder->width * 4);
+ for (i = 0; i < 3; i++) {
+ encoder->channels[i].correlate_row[-1] = 0;
+ quic_four_uncompress_row0(encoder, &encoder->channels[i], (four_bytes_t *)(buf + i),
+ encoder->width);
+ }
+ clear_row((four_bytes_t *)(buf + 3), encoder->width);
+ encoder->rows_completed++;
+ for (row = 1; row < encoder->height; row++) {
+ prev = buf;
+ buf += stride;
+ for (i = 0; i < 3; i++) {
+ encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
+ quic_four_uncompress_row(encoder, &encoder->channels[i],
+ (four_bytes_t *)(prev + i),
+ (four_bytes_t *)(buf + i),
+ encoder->width);
+ }
+ clear_row((four_bytes_t *)(buf + 3), encoder->width);
+ encoder->rows_completed++;
+ }
+ break;
+ case QUIC_IMAGE_TYPE_RGBA:
+ spice_assert(ABS(stride) >= encoder->width * 4);
+ for (i = 0; i < 4; i++) {
+ encoder->channels[i].correlate_row[-1] = 0;
+ quic_four_uncompress_row0(encoder, &encoder->channels[i], (four_bytes_t *)(buf + i),
+ encoder->width);
+ }
+ encoder->rows_completed++;
+ for (row = 1; row < encoder->height; row++) {
+ prev = buf;
+ buf += stride;
+ for (i = 0; i < 4; i++) {
+ encoder->channels[i].correlate_row[-1] = encoder->channels[i].correlate_row[0];
+ quic_four_uncompress_row(encoder, &encoder->channels[i],
+ (four_bytes_t *)(prev + i),
+ (four_bytes_t *)(buf + i),
+ encoder->width);
+ }
+ encoder->rows_completed++;
+ }
+ break;
+#endif
+ case QUIC_IMAGE_TYPE_GRAY:
+
+ if (type != QUIC_IMAGE_TYPE_GRAY) {
+ encoder->usr->warn(encoder->usr, "unsupported output format\n");
+ return QUIC_ERROR;
+ }
+ spice_assert(ABS(stride) >= (int)encoder->width);
+ uncompress_gray(encoder, buf, stride);
+ break;
+ case QUIC_IMAGE_TYPE_INVALID:
+ default:
+ encoder->usr->error(encoder->usr, "bad image type\n");
+ }
+ return QUIC_OK;
+}
+
+QuicContext *quic_create(QuicUsrContext *usr)
+{
+ Encoder *encoder;
+
+ if (!usr || !usr->error || !usr->warn || !usr->info || !usr->malloc ||
+ !usr->free || !usr->more_space || !usr->more_lines) {
+ return NULL;
+ }
+
+ if (!(encoder = (Encoder *)usr->malloc(usr, sizeof(Encoder)))) {
+ return NULL;
+ }
+
+ if (!init_encoder(encoder, usr)) {
+ usr->free(usr, encoder);
+ return NULL;
+ }
+ return (QuicContext *)encoder;
+}
+
+void quic_destroy(QuicContext *quic)
+{
+ Encoder *encoder = (Encoder *)quic;
+ int i;
+
+ if (!quic) {
+ return;
+ }
+
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ destroy_channel(&encoder->channels[i]);
+ }
+ encoder->usr->free(encoder->usr, encoder);
+}
+
+SPICE_CONSTRUCTOR_FUNC(quic_global_init)
+{
+ family_init(&family_8bpc, 8, DEFmaxclen);
+ family_init(&family_5bpc, 5, DEFmaxclen);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __QUIC_H
+#define __QUIC_H
+
+#include <spice/macros.h>
+#include "quic_config.h"
+#include "macros.h"
+
+SPICE_BEGIN_DECLS
+
+typedef enum {
+ QUIC_IMAGE_TYPE_INVALID,
+ QUIC_IMAGE_TYPE_GRAY,
+ QUIC_IMAGE_TYPE_RGB16,
+ QUIC_IMAGE_TYPE_RGB24,
+ QUIC_IMAGE_TYPE_RGB32,
+ QUIC_IMAGE_TYPE_RGBA
+} QuicImageType;
+
+#define QUIC_ERROR -1
+#define QUIC_OK 0
+
+typedef void *QuicContext;
+
+typedef struct QuicUsrContext QuicUsrContext;
+struct QuicUsrContext {
+ SPICE_ATTR_PRINTF(2, 3) void (*error)(QuicUsrContext *usr, const char *fmt, ...);
+ SPICE_ATTR_PRINTF(2, 3) void (*warn)(QuicUsrContext *usr, const char *fmt, ...);
+ SPICE_ATTR_PRINTF(2, 3) void (*info)(QuicUsrContext *usr, const char *fmt, ...);
+ void *(*malloc)(QuicUsrContext *usr, int size);
+ void (*free)(QuicUsrContext *usr, void *ptr);
+ int (*more_space)(QuicUsrContext *usr, uint32_t **io_ptr, int rows_completed);
+ int (*more_lines)(QuicUsrContext *usr, uint8_t **lines); // on return the last line of previous
+ // lines bunch must still be valid
+};
+
+int quic_encode(QuicContext *quic, QuicImageType type, int width, int height,
+ uint8_t *lines, unsigned int num_lines, int stride,
+ uint32_t *io_ptr, unsigned int num_io_words);
+
+int quic_decode_begin(QuicContext *quic, uint32_t *io_ptr, unsigned int num_io_words,
+ QuicImageType *type, int *width, int *height);
+int quic_decode(QuicContext *quic, QuicImageType type, uint8_t *buf, int stride);
+
+
+QuicContext *quic_create(QuicUsrContext *usr);
+void quic_destroy(QuicContext *quic);
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __QUIC_CONFIG_H
+#define __QUIC_CONFIG_H
+
+#include <spice/types.h>
+#include <spice/macros.h>
+
+SPICE_BEGIN_DECLS
+
+#ifdef __GNUC__
+#include <string.h>
+#define MEMCLEAR(ptr, size) memset(ptr, 0, size)
+#else
+#ifdef QXLDD
+#include <windef.h>
+#include "os_dep.h"
+#define MEMCLEAR(ptr, size) RtlZeroMemory(ptr, size)
+#else
+#include <stddef.h>
+#include <string.h>
+#define MEMCLEAR(ptr, size) memset(ptr, 0, size)
+#endif // QXLDD
+#endif //__GNUC__
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef QUIC_FAMILY_8BPC
+#undef QUIC_FAMILY_8BPC
+#define FNAME(name) name##_8bpc
+#define VNAME(name) name##_8bpc
+#define BPC 8
+#endif
+
+
+#ifdef QUIC_FAMILY_5BPC
+#undef QUIC_FAMILY_5BPC
+#define FNAME(name) name##_5bpc
+#define VNAME(name) name##_5bpc
+#define BPC 5
+#endif
+
+static inline unsigned int FNAME(golomb_code)(const BYTE n, const unsigned int l)
+{
+ return VNAME(family).golomb_code[n][l];
+}
+
+static inline unsigned int FNAME(golomb_code_len)(const BYTE n, const unsigned int l)
+{
+ return VNAME(family).golomb_code_len[n][l];
+}
+
+static void FNAME(golomb_coding)(const BYTE n, const unsigned int l, unsigned int * const codeword,
+ unsigned int * const codewordlen)
+{
+ *codeword = FNAME(golomb_code)(n, l);
+ *codewordlen = FNAME(golomb_code_len)(n, l);
+}
+
+static unsigned int FNAME(golomb_decoding)(const unsigned int l, const unsigned int bits,
+ unsigned int * const codewordlen)
+{
+ if (bits > VNAME(family).notGRprefixmask[l]) { /*GR*/
+ const unsigned int zeroprefix = cnt_l_zeroes(bits); /* leading zeroes in codeword */
+ const unsigned int cwlen = zeroprefix + 1 + l; /* codeword length */
+ (*codewordlen) = cwlen;
+ return (zeroprefix << l) | ((bits >> (32 - cwlen)) & bppmask[l]);
+ } else { /* not-GR */
+ const unsigned int cwlen = VNAME(family).notGRcwlen[l];
+ (*codewordlen) = cwlen;
+ return VNAME(family).nGRcodewords[l] + ((bits) >> (32 - cwlen) &
+ bppmask[VNAME(family).notGRsuffixlen[l]]);
+ }
+}
+
+/* update the bucket using just encoded curval */
+static void FNAME(update_model)(CommonState *state, s_bucket * const bucket,
+ const BYTE curval)
+{
+ spice_static_assert(BPC >= 1);
+ spice_return_if_fail (bucket != NULL);
+
+ const unsigned int bpp = BPC;
+ COUNTER * const pcounters = bucket->pcounters;
+ unsigned int i;
+ unsigned int bestcode;
+ unsigned int bestcodelen;
+
+ /* update counters, find minimum */
+
+ bestcode = bpp - 1;
+ bestcodelen = (pcounters[bestcode] += FNAME(golomb_code_len)(curval, bestcode));
+
+ for (i = bpp - 2; i < bpp; i--) { /* NOTE: expression i<bpp for signed int i would be: i>=0 */
+ const unsigned int ithcodelen = (pcounters[i] += FNAME(golomb_code_len)(curval, i));
+
+ if (ithcodelen < bestcodelen) {
+ bestcode = i;
+ bestcodelen = ithcodelen;
+ }
+ }
+
+ bucket->bestcode = bestcode; /* store the found minimum */
+
+ if (bestcodelen > state->wm_trigger) { /* halving counters? */
+ for (i = 0; i < bpp; i++) {
+ pcounters[i] >>= 1;
+ }
+ }
+}
+
+static s_bucket *FNAME(find_bucket)(Channel *channel, const unsigned int val)
+{
+ spice_assert(val < (0x1U << BPC));
+
+ return channel->_buckets_ptrs[val];
+}
+
+#undef FNAME
+#undef VNAME
+#undef BPC
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef QUIC_RGB32
+#undef QUIC_RGB32
+#define PIXEL rgb32_pixel_t
+#define FNAME(name) quic_rgb32_##name
+#define golomb_coding golomb_coding_8bpc
+#define golomb_decoding golomb_decoding_8bpc
+#define update_model update_model_8bpc
+#define find_bucket find_bucket_8bpc
+#define family family_8bpc
+#define BPC 8
+#define BPC_MASK 0xffU
+#define COMPRESS_IMP
+#define SET_r(pix, val) ((pix)->r = val)
+#define GET_r(pix) ((pix)->r)
+#define SET_g(pix, val) ((pix)->g = val)
+#define GET_g(pix) ((pix)->g)
+#define SET_b(pix, val) ((pix)->b = val)
+#define GET_b(pix) ((pix)->b)
+#define UNCOMPRESS_PIX_START(pix) ((pix)->pad = 0)
+#endif
+
+#ifdef QUIC_RGB24
+#undef QUIC_RGB24
+#define PIXEL rgb24_pixel_t
+#define FNAME(name) quic_rgb24_##name
+#define golomb_coding golomb_coding_8bpc
+#define golomb_decoding golomb_decoding_8bpc
+#define update_model update_model_8bpc
+#define find_bucket find_bucket_8bpc
+#define family family_8bpc
+#define BPC 8
+#define BPC_MASK 0xffU
+#define COMPRESS_IMP
+#define SET_r(pix, val) ((pix)->r = val)
+#define GET_r(pix) ((pix)->r)
+#define SET_g(pix, val) ((pix)->g = val)
+#define GET_g(pix) ((pix)->g)
+#define SET_b(pix, val) ((pix)->b = val)
+#define GET_b(pix) ((pix)->b)
+#define UNCOMPRESS_PIX_START(pix)
+#endif
+
+#ifdef QUIC_RGB16
+#undef QUIC_RGB16
+#define PIXEL rgb16_pixel_t
+#define FNAME(name) quic_rgb16_##name
+#define golomb_coding golomb_coding_5bpc
+#define golomb_decoding golomb_decoding_5bpc
+#define update_model update_model_5bpc
+#define find_bucket find_bucket_5bpc
+#define family family_5bpc
+#define BPC 5
+#define BPC_MASK 0x1fU
+#define COMPRESS_IMP
+#define SET_r(pix, val) (*(pix) = (*(pix) & ~(0x1f << 10)) | ((val) << 10))
+#define GET_r(pix) ((*(pix) >> 10) & 0x1f)
+#define SET_g(pix, val) (*(pix) = (*(pix) & ~(0x1f << 5)) | ((val) << 5))
+#define GET_g(pix) ((*(pix) >> 5) & 0x1f)
+#define SET_b(pix, val) (*(pix) = (*(pix) & ~0x1f) | (val))
+#define GET_b(pix) (*(pix) & 0x1f)
+#define UNCOMPRESS_PIX_START(pix) (*(pix) = 0)
+#endif
+
+#ifdef QUIC_RGB16_TO_32
+#undef QUIC_RGB16_TO_32
+#define PIXEL rgb32_pixel_t
+#define FNAME(name) quic_rgb16_to_32_##name
+#define golomb_coding golomb_coding_5bpc
+#define golomb_decoding golomb_decoding_5bpc
+#define update_model update_model_5bpc
+#define find_bucket find_bucket_5bpc
+#define family family_5bpc
+#define BPC 5
+#define BPC_MASK 0x1fU
+
+#define SET_r(pix, val) ((pix)->r = ((val) << 3) | (((val) & 0x1f) >> 2))
+#define GET_r(pix) ((pix)->r >> 3)
+#define SET_g(pix, val) ((pix)->g = ((val) << 3) | (((val) & 0x1f) >> 2))
+#define GET_g(pix) ((pix)->g >> 3)
+#define SET_b(pix, val) ((pix)->b = ((val) << 3) | (((val) & 0x1f) >> 2))
+#define GET_b(pix) ((pix)->b >> 3)
+#define UNCOMPRESS_PIX_START(pix) ((pix)->pad = 0)
+#endif
+
+#define SAME_PIXEL(p1, p2) \
+ (GET_r(p1) == GET_r(p2) && GET_g(p1) == GET_g(p2) && \
+ GET_b(p1) == GET_b(p2))
+
+
+#define _PIXEL_A(channel, curr) ((unsigned int)GET_##channel((curr) - 1))
+#define _PIXEL_B(channel, prev) ((unsigned int)GET_##channel(prev))
+#define _PIXEL_C(channel, prev) ((unsigned int)GET_##channel((prev) - 1))
+
+/* a */
+
+#define DECORELATE_0(channel, curr, bpc_mask)\
+ family.xlatU2L[(unsigned)((int)GET_##channel(curr) - (int)_PIXEL_A(channel, curr)) & bpc_mask]
+
+#define CORELATE_0(channel, curr, correlate, bpc_mask)\
+ ((family.xlatL2U[correlate] + _PIXEL_A(channel, curr)) & bpc_mask)
+
+#ifdef PRED_1
+
+/* (a+b)/2 */
+#define DECORELATE(channel, prev, curr, bpc_mask, r) \
+ r = family.xlatU2L[(unsigned)((int)GET_##channel(curr) - (int)((_PIXEL_A(channel, curr) + \
+ _PIXEL_B(channel, prev)) >> 1)) & bpc_mask]
+
+#define CORELATE(channel, prev, curr, correlate, bpc_mask, r) \
+ SET_##channel(r, ((family.xlatL2U[correlate] + \
+ (int)((_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev)) >> 1)) & bpc_mask))
+#endif
+
+#ifdef PRED_2
+
+/* .75a+.75b-.5c */
+#define DECORELATE(channel, prev, curr, bpc_mask, r) { \
+ int p = ((int)(3 * (_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev))) - \
+ (int)(_PIXEL_C(channel, prev) << 1)) >> 2; \
+ if (p < 0) { \
+ p = 0; \
+ } else if ((unsigned)p > bpc_mask) { \
+ p = bpc_mask; \
+ } \
+ r = family.xlatU2L[(unsigned)((int)GET_##channel(curr) - p) & bpc_mask]; \
+}
+
+#define CORELATE(channel, prev, curr, correlate, bpc_mask, r) { \
+ const int p = ((int)(3 * (_PIXEL_A(channel, curr) + _PIXEL_B(channel, prev))) - \
+ (int)(_PIXEL_C(channel, prev) << 1) ) >> 2; \
+ const unsigned int s = family.xlatL2U[correlate]; \
+ if (!(p & ~bpc_mask)) { \
+ SET_##channel(r, (s + (unsigned)p) & bpc_mask); \
+ } else if (p < 0) { \
+ SET_##channel(r, s); \
+ } else { \
+ SET_##channel(r, (s + bpc_mask) & bpc_mask); \
+ } \
+}
+
+#endif
+
+
+#define COMPRESS_ONE_ROW0_0(channel) \
+ correlate_row_##channel[0] = family.xlatU2L[GET_##channel(cur_row)]; \
+ golomb_coding(correlate_row_##channel[0], find_bucket(channel_##channel, \
+ correlate_row_##channel[-1])->bestcode, \
+ &codeword, &codewordlen); \
+ encode(encoder, codeword, codewordlen);
+
+#define COMPRESS_ONE_ROW0(channel, index) \
+ correlate_row_##channel[index] = DECORELATE_0(channel, &cur_row[index], bpc_mask); \
+ golomb_coding(correlate_row_##channel[index], find_bucket(channel_##channel, \
+ correlate_row_##channel[index -1])->bestcode, \
+ &codeword, &codewordlen); \
+ encode(encoder, codeword, codewordlen);
+
+#define UPDATE_MODEL(index) \
+ update_model(&encoder->rgb_state, find_bucket(channel_r, correlate_row_r[index - 1]), \
+ correlate_row_r[index]); \
+ update_model(&encoder->rgb_state, find_bucket(channel_g, correlate_row_g[index - 1]), \
+ correlate_row_g[index]); \
+ update_model(&encoder->rgb_state, find_bucket(channel_b, correlate_row_b[index - 1]), \
+ correlate_row_b[index]);
+
+
+#ifdef RLE_PRED_1
+#define RLE_PRED_1_IMP \
+if (SAME_PIXEL(&cur_row[i - 1], &prev_row[i])) { \
+ if (run_index != i && SAME_PIXEL(&prev_row[i - 1], &prev_row[i]) && \
+ i + 1 < end && SAME_PIXEL(&prev_row[i], &prev_row[i + 1])) { \
+ goto do_run; \
+ } \
+}
+#else
+#define RLE_PRED_1_IMP
+#endif
+
+#ifdef RLE_PRED_2
+#define RLE_PRED_2_IMP \
+if (SAME_PIXEL(&prev_row[i - 1], &prev_row[i])) { \
+ if (run_index != i && i > 2 && SAME_PIXEL(&cur_row[i - 1], &cur_row[i - 2])) { \
+ goto do_run; \
+ } \
+}
+#else
+#define RLE_PRED_2_IMP
+#endif
+
+#ifdef RLE_PRED_3
+#define RLE_PRED_3_IMP \
+if (i > 1 && SAME_PIXEL(&cur_row[i - 1], &cur_row[i - 2]) && i != run_index) { \
+ goto do_run; \
+}
+#else
+#define RLE_PRED_3_IMP
+#endif
+
+#ifdef COMPRESS_IMP
+
+static void FNAME(compress_row0_seg)(Encoder *encoder, int i,
+ const PIXEL * const cur_row,
+ const int end,
+ const unsigned int waitmask,
+ SPICE_GNUC_UNUSED const unsigned int bpc,
+ const unsigned int bpc_mask)
+{
+ Channel * const channel_r = encoder->channels;
+ Channel * const channel_g = channel_r + 1;
+ Channel * const channel_b = channel_g + 1;
+
+ BYTE * const correlate_row_r = channel_r->correlate_row;
+ BYTE * const correlate_row_g = channel_g->correlate_row;
+ BYTE * const correlate_row_b = channel_b->correlate_row;
+ int stopidx;
+
+ spice_assert(end - i > 0);
+
+ if (!i) {
+ unsigned int codeword, codewordlen;
+
+ COMPRESS_ONE_ROW0_0(r);
+ COMPRESS_ONE_ROW0_0(g);
+ COMPRESS_ONE_ROW0_0(b);
+
+ if (encoder->rgb_state.waitcnt) {
+ encoder->rgb_state.waitcnt--;
+ } else {
+ encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
+ UPDATE_MODEL(0);
+ }
+ stopidx = ++i + encoder->rgb_state.waitcnt;
+ } else {
+ stopidx = i + encoder->rgb_state.waitcnt;
+ }
+
+ while (stopidx < end) {
+ for (; i <= stopidx; i++) {
+ unsigned int codeword, codewordlen;
+ COMPRESS_ONE_ROW0(r, i);
+ COMPRESS_ONE_ROW0(g, i);
+ COMPRESS_ONE_ROW0(b, i);
+ }
+
+ UPDATE_MODEL(stopidx);
+ stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
+ }
+
+ for (; i < end; i++) {
+ unsigned int codeword, codewordlen;
+
+ COMPRESS_ONE_ROW0(r, i);
+ COMPRESS_ONE_ROW0(g, i);
+ COMPRESS_ONE_ROW0(b, i);
+ }
+ encoder->rgb_state.waitcnt = stopidx - end;
+}
+
+static void FNAME(compress_row0)(Encoder *encoder, const PIXEL *cur_row,
+ unsigned int width)
+{
+ const unsigned int bpc = BPC;
+ const unsigned int bpc_mask = BPC_MASK;
+ int pos = 0;
+
+ while ((wmimax > (int)encoder->rgb_state.wmidx) && (encoder->rgb_state.wmileft <= width)) {
+ if (encoder->rgb_state.wmileft) {
+ FNAME(compress_row0_seg)(encoder, pos, cur_row, pos + encoder->rgb_state.wmileft,
+ bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask);
+ width -= encoder->rgb_state.wmileft;
+ pos += encoder->rgb_state.wmileft;
+ }
+
+ encoder->rgb_state.wmidx++;
+ set_wm_trigger(&encoder->rgb_state);
+ encoder->rgb_state.wmileft = wminext;
+ }
+
+ if (width) {
+ FNAME(compress_row0_seg)(encoder, pos, cur_row, pos + width,
+ bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask);
+ if (wmimax > (int)encoder->rgb_state.wmidx) {
+ encoder->rgb_state.wmileft -= width;
+ }
+ }
+
+ spice_assert((int)encoder->rgb_state.wmidx <= wmimax);
+ spice_assert(encoder->rgb_state.wmidx <= 32);
+ spice_assert(wminext > 0);
+}
+
+#define COMPRESS_ONE_0(channel) \
+ correlate_row_##channel[0] = family.xlatU2L[(unsigned)((int)GET_##channel(cur_row) - \
+ (int)GET_##channel(prev_row) ) & bpc_mask]; \
+ golomb_coding(correlate_row_##channel[0], \
+ find_bucket(channel_##channel, correlate_row_##channel[-1])->bestcode, \
+ &codeword, &codewordlen); \
+ encode(encoder, codeword, codewordlen);
+
+#define COMPRESS_ONE(channel, index) \
+ DECORELATE(channel, &prev_row[index], &cur_row[index],bpc_mask, \
+ correlate_row_##channel[index]); \
+ golomb_coding(correlate_row_##channel[index], \
+ find_bucket(channel_##channel, correlate_row_##channel[index - 1])->bestcode, \
+ &codeword, &codewordlen); \
+ encode(encoder, codeword, codewordlen);
+
+static void FNAME(compress_row_seg)(Encoder *encoder, int i,
+ const PIXEL * const prev_row,
+ const PIXEL * const cur_row,
+ const int end,
+ const unsigned int waitmask,
+ SPICE_GNUC_UNUSED const unsigned int bpc,
+ const unsigned int bpc_mask)
+{
+ Channel * const channel_r = encoder->channels;
+ Channel * const channel_g = channel_r + 1;
+ Channel * const channel_b = channel_g + 1;
+
+ BYTE * const correlate_row_r = channel_r->correlate_row;
+ BYTE * const correlate_row_g = channel_g->correlate_row;
+ BYTE * const correlate_row_b = channel_b->correlate_row;
+ int stopidx;
+#ifdef RLE
+ int run_index = 0;
+ int run_size;
+#endif
+
+ spice_assert(end - i > 0);
+
+ if (!i) {
+ unsigned int codeword, codewordlen;
+
+ COMPRESS_ONE_0(r);
+ COMPRESS_ONE_0(g);
+ COMPRESS_ONE_0(b);
+
+ if (encoder->rgb_state.waitcnt) {
+ encoder->rgb_state.waitcnt--;
+ } else {
+ encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
+ UPDATE_MODEL(0);
+ }
+ stopidx = ++i + encoder->rgb_state.waitcnt;
+ } else {
+ stopidx = i + encoder->rgb_state.waitcnt;
+ }
+ for (;;) {
+ while (stopidx < end) {
+ for (; i <= stopidx; i++) {
+ unsigned int codeword, codewordlen;
+#ifdef RLE
+ RLE_PRED_1_IMP;
+ RLE_PRED_2_IMP;
+ RLE_PRED_3_IMP;
+#endif
+ COMPRESS_ONE(r, i);
+ COMPRESS_ONE(g, i);
+ COMPRESS_ONE(b, i);
+ }
+
+ UPDATE_MODEL(stopidx);
+ stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
+ }
+
+ for (; i < end; i++) {
+ unsigned int codeword, codewordlen;
+#ifdef RLE
+ RLE_PRED_1_IMP;
+ RLE_PRED_2_IMP;
+ RLE_PRED_3_IMP;
+#endif
+ COMPRESS_ONE(r, i);
+ COMPRESS_ONE(g, i);
+ COMPRESS_ONE(b, i);
+ }
+ encoder->rgb_state.waitcnt = stopidx - end;
+
+ return;
+
+#ifdef RLE
+do_run:
+ run_index = i;
+ encoder->rgb_state.waitcnt = stopidx - i;
+ run_size = 0;
+
+ while (SAME_PIXEL(&cur_row[i], &cur_row[i - 1])) {
+ run_size++;
+ if (++i == end) {
+ encode_run(encoder, run_size);
+ return;
+ }
+ }
+ encode_run(encoder, run_size);
+ stopidx = i + encoder->rgb_state.waitcnt;
+#endif
+ }
+}
+
+static void FNAME(compress_row)(Encoder *encoder,
+ const PIXEL * const prev_row,
+ const PIXEL * const cur_row,
+ unsigned int width)
+
+{
+ const unsigned int bpc = BPC;
+ const unsigned int bpc_mask = BPC_MASK;
+ unsigned int pos = 0;
+
+ while ((wmimax > (int)encoder->rgb_state.wmidx) && (encoder->rgb_state.wmileft <= width)) {
+ if (encoder->rgb_state.wmileft) {
+ FNAME(compress_row_seg)(encoder, pos, prev_row, cur_row,
+ pos + encoder->rgb_state.wmileft,
+ bppmask[encoder->rgb_state.wmidx],
+ bpc, bpc_mask);
+ width -= encoder->rgb_state.wmileft;
+ pos += encoder->rgb_state.wmileft;
+ }
+
+ encoder->rgb_state.wmidx++;
+ set_wm_trigger(&encoder->rgb_state);
+ encoder->rgb_state.wmileft = wminext;
+ }
+
+ if (width) {
+ FNAME(compress_row_seg)(encoder, pos, prev_row, cur_row, pos + width,
+ bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask);
+ if (wmimax > (int)encoder->rgb_state.wmidx) {
+ encoder->rgb_state.wmileft -= width;
+ }
+ }
+
+ spice_assert((int)encoder->rgb_state.wmidx <= wmimax);
+ spice_assert(encoder->rgb_state.wmidx <= 32);
+ spice_assert(wminext > 0);
+}
+
+#endif
+
+#define UNCOMPRESS_ONE_ROW0_0(channel) \
+ correlate_row_##channel[0] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \
+ correlate_row_##channel[-1])->bestcode, \
+ encoder->io_word, &codewordlen); \
+ SET_##channel(&cur_row[0], (BYTE)family.xlatL2U[correlate_row_##channel[0]]); \
+ decode_eatbits(encoder, codewordlen);
+
+#define UNCOMPRESS_ONE_ROW0(channel) \
+ correlate_row_##channel[i] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \
+ correlate_row_##channel[i - 1])->bestcode, \
+ encoder->io_word, \
+ &codewordlen); \
+ SET_##channel(&cur_row[i], CORELATE_0(channel, &cur_row[i], correlate_row_##channel[i], \
+ bpc_mask)); \
+ decode_eatbits(encoder, codewordlen);
+
+static void FNAME(uncompress_row0_seg)(Encoder *encoder, int i,
+ PIXEL * const cur_row,
+ const int end,
+ const unsigned int waitmask,
+ SPICE_GNUC_UNUSED const unsigned int bpc,
+ const unsigned int bpc_mask)
+{
+ Channel * const channel_r = encoder->channels;
+ Channel * const channel_g = channel_r + 1;
+ Channel * const channel_b = channel_g + 1;
+
+ BYTE * const correlate_row_r = channel_r->correlate_row;
+ BYTE * const correlate_row_g = channel_g->correlate_row;
+ BYTE * const correlate_row_b = channel_b->correlate_row;
+ int stopidx;
+
+ spice_assert(end - i > 0);
+
+ if (!i) {
+ unsigned int codewordlen;
+
+ UNCOMPRESS_PIX_START(&cur_row[i]);
+ UNCOMPRESS_ONE_ROW0_0(r);
+ UNCOMPRESS_ONE_ROW0_0(g);
+ UNCOMPRESS_ONE_ROW0_0(b);
+
+ if (encoder->rgb_state.waitcnt) {
+ --encoder->rgb_state.waitcnt;
+ } else {
+ encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
+ UPDATE_MODEL(0);
+ }
+ stopidx = ++i + encoder->rgb_state.waitcnt;
+ } else {
+ stopidx = i + encoder->rgb_state.waitcnt;
+ }
+
+ while (stopidx < end) {
+ for (; i <= stopidx; i++) {
+ unsigned int codewordlen;
+
+ UNCOMPRESS_PIX_START(&cur_row[i]);
+ UNCOMPRESS_ONE_ROW0(r);
+ UNCOMPRESS_ONE_ROW0(g);
+ UNCOMPRESS_ONE_ROW0(b);
+ }
+ UPDATE_MODEL(stopidx);
+ stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
+ }
+
+ for (; i < end; i++) {
+ unsigned int codewordlen;
+
+ UNCOMPRESS_PIX_START(&cur_row[i]);
+ UNCOMPRESS_ONE_ROW0(r);
+ UNCOMPRESS_ONE_ROW0(g);
+ UNCOMPRESS_ONE_ROW0(b);
+ }
+ encoder->rgb_state.waitcnt = stopidx - end;
+}
+
+static void FNAME(uncompress_row0)(Encoder *encoder,
+ PIXEL * const cur_row,
+ unsigned int width)
+
+{
+ const unsigned int bpc = BPC;
+ const unsigned int bpc_mask = BPC_MASK;
+ unsigned int pos = 0;
+
+ while ((wmimax > (int)encoder->rgb_state.wmidx) && (encoder->rgb_state.wmileft <= width)) {
+ if (encoder->rgb_state.wmileft) {
+ FNAME(uncompress_row0_seg)(encoder, pos, cur_row,
+ pos + encoder->rgb_state.wmileft,
+ bppmask[encoder->rgb_state.wmidx],
+ bpc, bpc_mask);
+ pos += encoder->rgb_state.wmileft;
+ width -= encoder->rgb_state.wmileft;
+ }
+
+ encoder->rgb_state.wmidx++;
+ set_wm_trigger(&encoder->rgb_state);
+ encoder->rgb_state.wmileft = wminext;
+ }
+
+ if (width) {
+ FNAME(uncompress_row0_seg)(encoder, pos, cur_row, pos + width,
+ bppmask[encoder->rgb_state.wmidx], bpc, bpc_mask);
+ if (wmimax > (int)encoder->rgb_state.wmidx) {
+ encoder->rgb_state.wmileft -= width;
+ }
+ }
+
+ spice_assert((int)encoder->rgb_state.wmidx <= wmimax);
+ spice_assert(encoder->rgb_state.wmidx <= 32);
+ spice_assert(wminext > 0);
+}
+
+#define UNCOMPRESS_ONE_0(channel) \
+ correlate_row_##channel[0] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \
+ correlate_row_##channel[-1])->bestcode, \
+ encoder->io_word, &codewordlen); \
+ SET_##channel(&cur_row[0], (family.xlatL2U[correlate_row_##channel[0]] + \
+ GET_##channel(prev_row)) & bpc_mask); \
+ decode_eatbits(encoder, codewordlen);
+
+#define UNCOMPRESS_ONE(channel) \
+ correlate_row_##channel[i] = (BYTE)golomb_decoding(find_bucket(channel_##channel, \
+ correlate_row_##channel[i - 1])->bestcode, \
+ encoder->io_word, \
+ &codewordlen); \
+ CORELATE(channel, &prev_row[i], &cur_row[i], correlate_row_##channel[i], bpc_mask, \
+ &cur_row[i]); \
+ decode_eatbits(encoder, codewordlen);
+
+static void FNAME(uncompress_row_seg)(Encoder *encoder,
+ const PIXEL * const prev_row,
+ PIXEL * const cur_row,
+ int i,
+ const int end,
+ SPICE_GNUC_UNUSED const unsigned int bpc,
+ const unsigned int bpc_mask)
+{
+ Channel * const channel_r = encoder->channels;
+ Channel * const channel_g = channel_r + 1;
+ Channel * const channel_b = channel_g + 1;
+
+ BYTE * const correlate_row_r = channel_r->correlate_row;
+ BYTE * const correlate_row_g = channel_g->correlate_row;
+ BYTE * const correlate_row_b = channel_b->correlate_row;
+ const unsigned int waitmask = bppmask[encoder->rgb_state.wmidx];
+ int stopidx;
+#ifdef RLE
+ int run_index = 0;
+ int run_end;
+#endif
+
+ spice_assert(end - i > 0);
+
+ if (!i) {
+ unsigned int codewordlen;
+
+ UNCOMPRESS_PIX_START(&cur_row[i]);
+ UNCOMPRESS_ONE_0(r);
+ UNCOMPRESS_ONE_0(g);
+ UNCOMPRESS_ONE_0(b);
+
+ if (encoder->rgb_state.waitcnt) {
+ --encoder->rgb_state.waitcnt;
+ } else {
+ encoder->rgb_state.waitcnt = (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
+ UPDATE_MODEL(0);
+ }
+ stopidx = ++i + encoder->rgb_state.waitcnt;
+ } else {
+ stopidx = i + encoder->rgb_state.waitcnt;
+ }
+ for (;;) {
+ while (stopidx < end) {
+ for (; i <= stopidx; i++) {
+ unsigned int codewordlen;
+#ifdef RLE
+ RLE_PRED_1_IMP;
+ RLE_PRED_2_IMP;
+ RLE_PRED_3_IMP;
+#endif
+ UNCOMPRESS_PIX_START(&cur_row[i]);
+ UNCOMPRESS_ONE(r);
+ UNCOMPRESS_ONE(g);
+ UNCOMPRESS_ONE(b);
+ }
+
+ UPDATE_MODEL(stopidx);
+
+ stopidx = i + (tabrand(&encoder->rgb_state.tabrand_seed) & waitmask);
+ }
+
+ for (; i < end; i++) {
+ unsigned int codewordlen;
+#ifdef RLE
+ RLE_PRED_1_IMP;
+ RLE_PRED_2_IMP;
+ RLE_PRED_3_IMP;
+#endif
+ UNCOMPRESS_PIX_START(&cur_row[i]);
+ UNCOMPRESS_ONE(r);
+ UNCOMPRESS_ONE(g);
+ UNCOMPRESS_ONE(b);
+ }
+
+ encoder->rgb_state.waitcnt = stopidx - end;
+
+ return;
+
+#ifdef RLE
+do_run:
+ encoder->rgb_state.waitcnt = stopidx - i;
+ run_index = i;
+ run_end = i + decode_run(encoder);
+
+ for (; i < run_end; i++) {
+ UNCOMPRESS_PIX_START(&cur_row[i]);
+ SET_r(&cur_row[i], GET_r(&cur_row[i - 1]));
+ SET_g(&cur_row[i], GET_g(&cur_row[i - 1]));
+ SET_b(&cur_row[i], GET_b(&cur_row[i - 1]));
+ }
+
+ if (i == end) {
+ return;
+ }
+
+ stopidx = i + encoder->rgb_state.waitcnt;
+#endif
+ }
+}
+
+static void FNAME(uncompress_row)(Encoder *encoder,
+ const PIXEL * const prev_row,
+ PIXEL * const cur_row,
+ unsigned int width)
+
+{
+ const unsigned int bpc = BPC;
+ const unsigned int bpc_mask = BPC_MASK;
+ unsigned int pos = 0;
+
+ while ((wmimax > (int)encoder->rgb_state.wmidx) && (encoder->rgb_state.wmileft <= width)) {
+ if (encoder->rgb_state.wmileft) {
+ FNAME(uncompress_row_seg)(encoder, prev_row, cur_row, pos,
+ pos + encoder->rgb_state.wmileft, bpc, bpc_mask);
+ pos += encoder->rgb_state.wmileft;
+ width -= encoder->rgb_state.wmileft;
+ }
+
+ encoder->rgb_state.wmidx++;
+ set_wm_trigger(&encoder->rgb_state);
+ encoder->rgb_state.wmileft = wminext;
+ }
+
+ if (width) {
+ FNAME(uncompress_row_seg)(encoder, prev_row, cur_row, pos,
+ pos + width, bpc, bpc_mask);
+ if (wmimax > (int)encoder->rgb_state.wmidx) {
+ encoder->rgb_state.wmileft -= width;
+ }
+ }
+
+ spice_assert((int)encoder->rgb_state.wmidx <= wmimax);
+ spice_assert(encoder->rgb_state.wmidx <= 32);
+ spice_assert(wminext > 0);
+}
+
+#undef PIXEL
+#undef FNAME
+#undef _PIXEL_A
+#undef _PIXEL_B
+#undef _PIXEL_C
+#undef SAME_PIXEL
+#undef RLE_PRED_1_IMP
+#undef RLE_PRED_2_IMP
+#undef RLE_PRED_3_IMP
+#undef UPDATE_MODEL
+#undef DECORELATE_0
+#undef DECORELATE
+#undef COMPRESS_ONE_ROW0_0
+#undef COMPRESS_ONE_ROW0
+#undef COMPRESS_ONE_0
+#undef COMPRESS_ONE
+#undef CORELATE_0
+#undef CORELATE
+#undef UNCOMPRESS_ONE_ROW0_0
+#undef UNCOMPRESS_ONE_ROW0
+#undef UNCOMPRESS_ONE_0
+#undef UNCOMPRESS_ONE
+#undef golomb_coding
+#undef golomb_decoding
+#undef update_model
+#undef find_bucket
+#undef family
+#undef BPC
+#undef BPC_MASK
+#undef COMPRESS_IMP
+#undef SET_r
+#undef GET_r
+#undef SET_g
+#undef GET_g
+#undef SET_b
+#undef GET_b
+#undef UNCOMPRESS_PIX_START
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef ONE_BYTE
+#undef ONE_BYTE
+#define FNAME(name) quic_one_##name
+#define PIXEL one_byte_t
+#endif
+
+#ifdef THREE_BYTE
+#undef THREE_BYTE
+#define FNAME(name) quic_three_##name
+#define PIXEL three_bytes_t
+#endif
+
+#ifdef FOUR_BYTE
+#undef FOUR_BYTE
+#define FNAME(name) quic_four_##name
+#define PIXEL four_bytes_t
+#endif
+
+#define golomb_coding golomb_coding_8bpc
+#define golomb_decoding golomb_decoding_8bpc
+#define update_model update_model_8bpc
+#define find_bucket find_bucket_8bpc
+#define family family_8bpc
+
+#define BPC 8
+#define BPC_MASK 0xffU
+
+#define _PIXEL_A ((unsigned int)curr[-1].a)
+#define _PIXEL_B ((unsigned int)prev[0].a)
+#define _PIXEL_C ((unsigned int)prev[-1].a)
+
+#ifdef RLE_PRED_1
+#define RLE_PRED_1_IMP \
+if (cur_row[i - 1].a == prev_row[i].a) { \
+ if (run_index != i && prev_row[i - 1].a == prev_row[i].a && \
+ i + 1 < end && prev_row[i].a == prev_row[i + 1].a) { \
+ goto do_run; \
+ } \
+}
+#else
+#define RLE_PRED_1_IMP
+#endif
+
+#ifdef RLE_PRED_2
+#define RLE_PRED_2_IMP \
+if (prev_row[i - 1].a == prev_row[i].a) { \
+ if (run_index != i && i > 2 && cur_row[i - 1].a == cur_row[i - 2].a) { \
+ goto do_run; \
+ } \
+}
+#else
+#define RLE_PRED_2_IMP
+#endif
+
+#ifdef RLE_PRED_3
+#define RLE_PRED_3_IMP \
+if (i > 1 && cur_row[i - 1].a == cur_row[i - 2].a && i != run_index) { \
+ goto do_run; \
+}
+#else
+#define RLE_PRED_3_IMP
+#endif
+
+/* a */
+static inline BYTE FNAME(decorelate_0)(const PIXEL * const curr, const unsigned int bpc_mask)
+{
+ return family.xlatU2L[(unsigned)((int)curr[0].a - (int)_PIXEL_A) & bpc_mask];
+}
+
+static inline void FNAME(corelate_0)(PIXEL *curr, const BYTE corelate,
+ const unsigned int bpc_mask)
+{
+ curr->a = (family.xlatL2U[corelate] + _PIXEL_A) & bpc_mask;
+}
+
+#ifdef PRED_1
+
+/* (a+b)/2 */
+static inline BYTE FNAME(decorelate)(const PIXEL *const prev, const PIXEL * const curr,
+ const unsigned int bpc_mask)
+{
+ return family.xlatU2L[(unsigned)((int)curr->a - (int)((_PIXEL_A + _PIXEL_B) >> 1)) & bpc_mask];
+}
+
+
+static inline void FNAME(corelate)(const PIXEL *prev, PIXEL *curr, const BYTE corelate,
+ const unsigned int bpc_mask)
+{
+ curr->a = (family.xlatL2U[corelate] + (int)((_PIXEL_A + _PIXEL_B) >> 1)) & bpc_mask;
+}
+
+#endif
+
+#ifdef PRED_2
+
+/* .75a+.75b-.5c */
+static inline BYTE FNAME(decorelate)(const PIXEL *const prev, const PIXEL * const curr,
+ const unsigned int bpc_mask)
+{
+ int p = ((int)(3 * (_PIXEL_A + _PIXEL_B)) - (int)(_PIXEL_C << 1)) >> 2;
+
+ if (p < 0) {
+ p = 0;
+ } else if ((unsigned)p > bpc_mask) {
+ p = bpc_mask;
+ }
+
+ {
+ return family.xlatU2L[(unsigned)((int)curr->a - p) & bpc_mask];
+ }
+}
+
+static inline void FNAME(corelate)(const PIXEL *prev, PIXEL *curr, const BYTE corelate,
+ const unsigned int bpc_mask)
+{
+ const int p = ((int)(3 * (_PIXEL_A + _PIXEL_B)) - (int)(_PIXEL_C << 1)) >> 2;
+ const unsigned int s = family.xlatL2U[corelate];
+
+ if (!(p & ~bpc_mask)) {
+ curr->a = (s + (unsigned)p) & bpc_mask;
+ } else if (p < 0) {
+ curr->a = s;
+ } else {
+ curr->a = (s + bpc_mask) & bpc_mask;
+ }
+}
+
+#endif
+
+static void FNAME(compress_row0_seg)(Encoder *encoder, Channel *channel, int i,
+ const PIXEL * const cur_row,
+ const int end,
+ const unsigned int waitmask,
+ SPICE_GNUC_UNUSED const unsigned int bpc,
+ const unsigned int bpc_mask)
+{
+ BYTE * const decorelate_drow = channel->correlate_row;
+ int stopidx;
+
+ spice_assert(end - i > 0);
+
+ if (i == 0) {
+ unsigned int codeword, codewordlen;
+
+ decorelate_drow[0] = family.xlatU2L[cur_row->a];
+ golomb_coding(decorelate_drow[0], find_bucket(channel, decorelate_drow[-1])->bestcode,
+ &codeword, &codewordlen);
+ encode(encoder, codeword, codewordlen);
+
+ if (channel->state.waitcnt) {
+ channel->state.waitcnt--;
+ } else {
+ channel->state.waitcnt = (tabrand(&channel->state.tabrand_seed) & waitmask);
+ update_model(&channel->state, find_bucket(channel, decorelate_drow[-1]),
+ decorelate_drow[i]);
+ }
+ stopidx = ++i + channel->state.waitcnt;
+ } else {
+ stopidx = i + channel->state.waitcnt;
+ }
+
+ while (stopidx < end) {
+ for (; i <= stopidx; i++) {
+ unsigned int codeword, codewordlen;
+ decorelate_drow[i] = FNAME(decorelate_0)(&cur_row[i], bpc_mask);
+ golomb_coding(decorelate_drow[i],
+ find_bucket(channel, decorelate_drow[i - 1])->bestcode, &codeword,
+ &codewordlen);
+ encode(encoder, codeword, codewordlen);
+ }
+
+ update_model(&channel->state, find_bucket(channel, decorelate_drow[stopidx - 1]),
+ decorelate_drow[stopidx]);
+ stopidx = i + (tabrand(&channel->state.tabrand_seed) & waitmask);
+ }
+
+ for (; i < end; i++) {
+ unsigned int codeword, codewordlen;
+ decorelate_drow[i] = FNAME(decorelate_0)(&cur_row[i], bpc_mask);
+ golomb_coding(decorelate_drow[i], find_bucket(channel, decorelate_drow[i - 1])->bestcode,
+ &codeword, &codewordlen);
+ encode(encoder, codeword, codewordlen);
+ }
+ channel->state.waitcnt = stopidx - end;
+}
+
+static void FNAME(compress_row0)(Encoder *encoder, Channel *channel, const PIXEL *cur_row,
+ unsigned int width)
+{
+ const unsigned int bpc = BPC;
+ const unsigned int bpc_mask = BPC_MASK;
+ int pos = 0;
+
+ while ((wmimax > (int)channel->state.wmidx) && (channel->state.wmileft <= width)) {
+ if (channel->state.wmileft) {
+ FNAME(compress_row0_seg)(encoder, channel, pos, cur_row, pos + channel->state.wmileft,
+ bppmask[channel->state.wmidx], bpc, bpc_mask);
+ width -= channel->state.wmileft;
+ pos += channel->state.wmileft;
+ }
+
+ channel->state.wmidx++;
+ set_wm_trigger(&channel->state);
+ channel->state.wmileft = wminext;
+ }
+
+ if (width) {
+ FNAME(compress_row0_seg)(encoder, channel, pos, cur_row, pos + width,
+ bppmask[channel->state.wmidx], bpc, bpc_mask);
+ if (wmimax > (int)channel->state.wmidx) {
+ channel->state.wmileft -= width;
+ }
+ }
+
+ spice_assert((int)channel->state.wmidx <= wmimax);
+ spice_assert(channel->state.wmidx <= 32);
+ spice_assert(wminext > 0);
+}
+
+static void FNAME(compress_row_seg)(Encoder *encoder, Channel *channel, int i,
+ const PIXEL * const prev_row,
+ const PIXEL * const cur_row,
+ const int end,
+ const unsigned int waitmask,
+ SPICE_GNUC_UNUSED const unsigned int bpc,
+ const unsigned int bpc_mask)
+{
+ BYTE * const decorelate_drow = channel->correlate_row;
+ int stopidx;
+#ifdef RLE
+ int run_index = 0;
+ int run_size;
+#endif
+
+ spice_assert(end - i > 0);
+
+ if (!i) {
+ unsigned int codeword, codewordlen;
+
+ decorelate_drow[0] = family.xlatU2L[(unsigned)((int)cur_row->a -
+ (int)prev_row->a) & bpc_mask];
+
+ golomb_coding(decorelate_drow[0],
+ find_bucket(channel, decorelate_drow[-1])->bestcode,
+ &codeword,
+ &codewordlen);
+ encode(encoder, codeword, codewordlen);
+
+ if (channel->state.waitcnt) {
+ channel->state.waitcnt--;
+ } else {
+ channel->state.waitcnt = (tabrand(&channel->state.tabrand_seed) & waitmask);
+ update_model(&channel->state, find_bucket(channel, decorelate_drow[-1]),
+ decorelate_drow[0]);
+ }
+ stopidx = ++i + channel->state.waitcnt;
+ } else {
+ stopidx = i + channel->state.waitcnt;
+ }
+ for (;;) {
+ while (stopidx < end) {
+ for (; i <= stopidx; i++) {
+ unsigned int codeword, codewordlen;
+#ifdef RLE
+ RLE_PRED_1_IMP;
+ RLE_PRED_2_IMP;
+ RLE_PRED_3_IMP;
+#endif
+ decorelate_drow[i] = FNAME(decorelate)(&prev_row[i], &cur_row[i], bpc_mask);
+ golomb_coding(decorelate_drow[i],
+ find_bucket(channel, decorelate_drow[i - 1])->bestcode, &codeword,
+ &codewordlen);
+ encode(encoder, codeword, codewordlen);
+ }
+
+ update_model(&channel->state, find_bucket(channel, decorelate_drow[stopidx - 1]),
+ decorelate_drow[stopidx]);
+ stopidx = i + (tabrand(&channel->state.tabrand_seed) & waitmask);
+ }
+
+ for (; i < end; i++) {
+ unsigned int codeword, codewordlen;
+#ifdef RLE
+ RLE_PRED_1_IMP;
+ RLE_PRED_2_IMP;
+ RLE_PRED_3_IMP;
+#endif
+ decorelate_drow[i] = FNAME(decorelate)(&prev_row[i], &cur_row[i], bpc_mask);
+ golomb_coding(decorelate_drow[i], find_bucket(channel,
+ decorelate_drow[i - 1])->bestcode,
+ &codeword, &codewordlen);
+ encode(encoder, codeword, codewordlen);
+ }
+ channel->state.waitcnt = stopidx - end;
+
+ return;
+
+#ifdef RLE
+do_run:
+ run_index = i;
+ channel->state.waitcnt = stopidx - i;
+ run_size = 0;
+
+ while (cur_row[i].a == cur_row[i - 1].a) {
+ run_size++;
+ if (++i == end) {
+#ifdef RLE_STAT
+ encode_channel_run(encoder, channel, run_size);
+#else
+ encode_run(encoder, run_size);
+#endif
+ return;
+ }
+ }
+#ifdef RLE_STAT
+ encode_channel_run(encoder, channel, run_size);
+#else
+ encode_run(encoder, run_size);
+#endif
+ stopidx = i + channel->state.waitcnt;
+#endif
+ }
+}
+
+static void FNAME(compress_row)(Encoder *encoder, Channel *channel,
+ const PIXEL * const prev_row,
+ const PIXEL * const cur_row,
+ unsigned int width)
+
+{
+ const unsigned int bpc = BPC;
+ const unsigned int bpc_mask = BPC_MASK;
+ unsigned int pos = 0;
+
+ while ((wmimax > (int)channel->state.wmidx) && (channel->state.wmileft <= width)) {
+ if (channel->state.wmileft) {
+ FNAME(compress_row_seg)(encoder, channel, pos, prev_row, cur_row,
+ pos + channel->state.wmileft, bppmask[channel->state.wmidx],
+ bpc, bpc_mask);
+ width -= channel->state.wmileft;
+ pos += channel->state.wmileft;
+ }
+
+ channel->state.wmidx++;
+ set_wm_trigger(&channel->state);
+ channel->state.wmileft = wminext;
+ }
+
+ if (width) {
+ FNAME(compress_row_seg)(encoder, channel, pos, prev_row, cur_row, pos + width,
+ bppmask[channel->state.wmidx], bpc, bpc_mask);
+ if (wmimax > (int)channel->state.wmidx) {
+ channel->state.wmileft -= width;
+ }
+ }
+
+ spice_assert((int)channel->state.wmidx <= wmimax);
+ spice_assert(channel->state.wmidx <= 32);
+ spice_assert(wminext > 0);
+}
+
+static void FNAME(uncompress_row0_seg)(Encoder *encoder, Channel *channel, int i,
+ BYTE * const correlate_row,
+ PIXEL * const cur_row,
+ const int end,
+ const unsigned int waitmask,
+ SPICE_GNUC_UNUSED const unsigned int bpc,
+ const unsigned int bpc_mask)
+{
+ int stopidx;
+
+ spice_assert(end - i > 0);
+
+ if (i == 0) {
+ unsigned int codewordlen;
+
+ correlate_row[0] = (BYTE)golomb_decoding(find_bucket(channel,
+ correlate_row[-1])->bestcode,
+ encoder->io_word, &codewordlen);
+ cur_row[0].a = (BYTE)family.xlatL2U[correlate_row[0]];
+ decode_eatbits(encoder, codewordlen);
+
+ if (channel->state.waitcnt) {
+ --channel->state.waitcnt;
+ } else {
+ channel->state.waitcnt = (tabrand(&channel->state.tabrand_seed) & waitmask);
+ update_model(&channel->state, find_bucket(channel, correlate_row[-1]),
+ correlate_row[0]);
+ }
+ stopidx = ++i + channel->state.waitcnt;
+ } else {
+ stopidx = i + channel->state.waitcnt;
+ }
+
+ while (stopidx < end) {
+ struct s_bucket * pbucket = NULL;
+
+ for (; i <= stopidx; i++) {
+ unsigned int codewordlen;
+
+ pbucket = find_bucket(channel, correlate_row[i - 1]);
+ correlate_row[i] = (BYTE)golomb_decoding(pbucket->bestcode, encoder->io_word,
+ &codewordlen);
+ FNAME(corelate_0)(&cur_row[i], correlate_row[i], bpc_mask);
+ decode_eatbits(encoder, codewordlen);
+ }
+
+ update_model(&channel->state, pbucket, correlate_row[stopidx]);
+
+ stopidx = i + (tabrand(&channel->state.tabrand_seed) & waitmask);
+ }
+
+ for (; i < end; i++) {
+ unsigned int codewordlen;
+
+ correlate_row[i] = (BYTE)golomb_decoding(find_bucket(channel,
+ correlate_row[i - 1])->bestcode,
+ encoder->io_word, &codewordlen);
+ FNAME(corelate_0)(&cur_row[i], correlate_row[i], bpc_mask);
+ decode_eatbits(encoder, codewordlen);
+ }
+ channel->state.waitcnt = stopidx - end;
+}
+
+static void FNAME(uncompress_row0)(Encoder *encoder, Channel *channel,
+ PIXEL * const cur_row,
+ unsigned int width)
+
+{
+ const unsigned int bpc = BPC;
+ const unsigned int bpc_mask = BPC_MASK;
+ BYTE * const correlate_row = channel->correlate_row;
+ unsigned int pos = 0;
+
+ while ((wmimax > (int)channel->state.wmidx) && (channel->state.wmileft <= width)) {
+ if (channel->state.wmileft) {
+ FNAME(uncompress_row0_seg)(encoder, channel, pos, correlate_row, cur_row,
+ pos + channel->state.wmileft, bppmask[channel->state.wmidx],
+ bpc, bpc_mask);
+ pos += channel->state.wmileft;
+ width -= channel->state.wmileft;
+ }
+
+ channel->state.wmidx++;
+ set_wm_trigger(&channel->state);
+ channel->state.wmileft = wminext;
+ }
+
+ if (width) {
+ FNAME(uncompress_row0_seg)(encoder, channel, pos, correlate_row, cur_row, pos + width,
+ bppmask[channel->state.wmidx], bpc, bpc_mask);
+ if (wmimax > (int)channel->state.wmidx) {
+ channel->state.wmileft -= width;
+ }
+ }
+
+ spice_assert((int)channel->state.wmidx <= wmimax);
+ spice_assert(channel->state.wmidx <= 32);
+ spice_assert(wminext > 0);
+}
+
+static void FNAME(uncompress_row_seg)(Encoder *encoder, Channel *channel,
+ BYTE *correlate_row,
+ const PIXEL * const prev_row,
+ PIXEL * const cur_row,
+ int i,
+ const int end,
+ SPICE_GNUC_UNUSED const unsigned int bpc,
+ const unsigned int bpc_mask)
+{
+ const unsigned int waitmask = bppmask[channel->state.wmidx];
+ int stopidx;
+#ifdef RLE
+ int run_index = 0;
+ int run_end;
+#endif
+
+ spice_assert(end - i > 0);
+
+ if (i == 0) {
+ unsigned int codewordlen;
+
+ correlate_row[0] = (BYTE)golomb_decoding(find_bucket(channel, correlate_row[-1])->bestcode,
+ encoder->io_word, &codewordlen);
+ cur_row[0].a = (family.xlatL2U[correlate_row[0]] + prev_row[0].a) & bpc_mask;
+ decode_eatbits(encoder, codewordlen);
+
+ if (channel->state.waitcnt) {
+ --channel->state.waitcnt;
+ } else {
+ channel->state.waitcnt = (tabrand(&channel->state.tabrand_seed) & waitmask);
+ update_model(&channel->state, find_bucket(channel, correlate_row[-1]),
+ correlate_row[0]);
+ }
+ stopidx = ++i + channel->state.waitcnt;
+ } else {
+ stopidx = i + channel->state.waitcnt;
+ }
+ for (;;) {
+ while (stopidx < end) {
+ struct s_bucket * pbucket = NULL;
+
+ for (; i <= stopidx; i++) {
+ unsigned int codewordlen;
+#ifdef RLE
+ RLE_PRED_1_IMP;
+ RLE_PRED_2_IMP;
+ RLE_PRED_3_IMP;
+#endif
+ pbucket = find_bucket(channel, correlate_row[i - 1]);
+ correlate_row[i] = (BYTE)golomb_decoding(pbucket->bestcode, encoder->io_word,
+ &codewordlen);
+ FNAME(corelate)(&prev_row[i], &cur_row[i], correlate_row[i], bpc_mask);
+ decode_eatbits(encoder, codewordlen);
+ }
+
+ update_model(&channel->state, pbucket, correlate_row[stopidx]);
+
+ stopidx = i + (tabrand(&channel->state.tabrand_seed) & waitmask);
+ }
+
+ for (; i < end; i++) {
+ unsigned int codewordlen;
+#ifdef RLE
+ RLE_PRED_1_IMP;
+ RLE_PRED_2_IMP;
+ RLE_PRED_3_IMP;
+#endif
+ correlate_row[i] = (BYTE)golomb_decoding(find_bucket(channel,
+ correlate_row[i - 1])->bestcode,
+ encoder->io_word, &codewordlen);
+ FNAME(corelate)(&prev_row[i], &cur_row[i], correlate_row[i], bpc_mask);
+ decode_eatbits(encoder, codewordlen);
+ }
+
+ channel->state.waitcnt = stopidx - end;
+
+ return;
+
+#ifdef RLE
+do_run:
+ channel->state.waitcnt = stopidx - i;
+ run_index = i;
+#ifdef RLE_STAT
+ run_end = i + decode_channel_run(encoder, channel);
+#else
+ run_end = i + decode_run(encoder);
+#endif
+
+ for (; i < run_end; i++) {
+ cur_row[i].a = cur_row[i - 1].a;
+ }
+
+ if (i == end) {
+ return;
+ }
+
+ stopidx = i + channel->state.waitcnt;
+#endif
+ }
+}
+
+static void FNAME(uncompress_row)(Encoder *encoder, Channel *channel,
+ const PIXEL * const prev_row,
+ PIXEL * const cur_row,
+ unsigned int width)
+
+{
+ const unsigned int bpc = BPC;
+ const unsigned int bpc_mask = BPC_MASK;
+ BYTE * const correlate_row = channel->correlate_row;
+ unsigned int pos = 0;
+
+ while ((wmimax > (int)channel->state.wmidx) && (channel->state.wmileft <= width)) {
+ if (channel->state.wmileft) {
+ FNAME(uncompress_row_seg)(encoder, channel, correlate_row, prev_row, cur_row, pos,
+ pos + channel->state.wmileft, bpc, bpc_mask);
+ pos += channel->state.wmileft;
+ width -= channel->state.wmileft;
+ }
+
+ channel->state.wmidx++;
+ set_wm_trigger(&channel->state);
+ channel->state.wmileft = wminext;
+ }
+
+ if (width) {
+ FNAME(uncompress_row_seg)(encoder, channel, correlate_row, prev_row, cur_row, pos,
+ pos + width, bpc, bpc_mask);
+ if (wmimax > (int)channel->state.wmidx) {
+ channel->state.wmileft -= width;
+ }
+ }
+
+ spice_assert((int)channel->state.wmidx <= wmimax);
+ spice_assert(channel->state.wmidx <= 32);
+ spice_assert(wminext > 0);
+}
+
+#undef PIXEL
+#undef FNAME
+#undef _PIXEL_A
+#undef _PIXEL_B
+#undef _PIXEL_C
+#undef RLE_PRED_1_IMP
+#undef RLE_PRED_2_IMP
+#undef RLE_PRED_3_IMP
+#undef golomb_coding
+#undef golomb_deoding
+#undef update_model
+#undef find_bucket
+#undef family
+#undef BPC
+#undef BPC_MASK
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_RECT
+#define _H_RECT
+
+#include <spice/macros.h>
+#include "draw.h"
+#include "log.h"
+
+SPICE_BEGIN_DECLS
+
+static inline void rect_sect(SpiceRect* r, const SpiceRect* bounds)
+{
+ r->left = MAX(r->left, bounds->left);
+ r->right = MIN(r->right, bounds->right);
+ r->right = MAX(r->left, r->right);
+
+ r->top = MAX(r->top, bounds->top);
+ r->bottom = MIN(r->bottom, bounds->bottom);
+ r->bottom = MAX(r->top, r->bottom);
+}
+
+static inline void rect_offset(SpiceRect* r, int dx, int dy)
+{
+ r->left += dx;
+ r->right += dx;
+ r->top += dy;
+ r->bottom += dy;
+}
+
+static inline int rect_is_empty(const SpiceRect* r)
+{
+ return r->top == r->bottom || r->left == r->right;
+}
+
+static inline int rect_intersects(const SpiceRect* r1, const SpiceRect* r2)
+{
+ return r1->left < r2->right && r1->right > r2->left &&
+ r1->top < r2->bottom && r1->bottom > r2->top;
+}
+
+static inline int rect_is_equal(const SpiceRect *r1, const SpiceRect *r2)
+{
+ return r1->top == r2->top && r1->left == r2->left &&
+ r1->bottom == r2->bottom && r1->right == r2->right;
+}
+
+static inline void rect_union(SpiceRect *dest, const SpiceRect *r)
+{
+ dest->top = MIN(dest->top, r->top);
+ dest->left = MIN(dest->left, r->left);
+ dest->bottom = MAX(dest->bottom, r->bottom);
+ dest->right = MAX(dest->right, r->right);
+}
+
+static inline int rect_is_same_size(const SpiceRect *r1, const SpiceRect *r2)
+{
+ return r1->right - r1->left == r2->right - r2->left &&
+ r1->bottom - r1->top == r2->bottom - r2->top;
+}
+
+static inline int rect_contains(const SpiceRect *big, const SpiceRect *small)
+{
+ return big->left <= small->left && big->right >= small->right &&
+ big->top <= small->top && big->bottom >= small->bottom;
+}
+
+static inline int rect_get_area(const SpiceRect *r)
+{
+ return (r->right - r->left) * (r->bottom - r->top);
+}
+
+static inline void rect_debug(const SpiceRect *r)
+{
+ spice_debug("(%d, %d) (%d, %d)", r->left, r->top, r->right, r->bottom);
+}
+
+SPICE_END_DECLS
+
+#ifdef __cplusplus
+
+static inline void rect_sect(SpiceRect& r, const SpiceRect& bounds)
+{
+ rect_sect(&r, &bounds);
+}
+
+static inline void rect_offset(SpiceRect& r, int dx, int dy)
+{
+ rect_offset(&r, dx, dy);
+}
+
+static inline int rect_is_empty(const SpiceRect& r)
+{
+ return rect_is_empty(&r);
+}
+
+static inline int rect_intersects(const SpiceRect& r1, const SpiceRect& r2)
+{
+ return rect_intersects(&r1, &r2);
+}
+
+static inline int rect_is_equal(const SpiceRect& r1, const SpiceRect& r2)
+{
+ return rect_is_equal(&r1, &r2);
+}
+
+static inline void rect_union(SpiceRect& dest, const SpiceRect& r)
+{
+ rect_union(&dest, &r);
+}
+
+static inline int rect_is_same_size(const SpiceRect& r1, const SpiceRect& r2)
+{
+ return rect_is_same_size(&r1, &r2);
+}
+
+static inline int rect_contains(const SpiceRect& big, const SpiceRect& small)
+{
+ return rect_contains(&big, &small);
+}
+
+static inline int rect_get_area(const SpiceRect& r)
+{
+ return rect_get_area(&r);
+}
+
+static inline void rect_debug(const SpiceRect &r)
+{
+ rect_debug(&r);
+}
+
+#endif /* __cplusplus */
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <spice/macros.h>
+
+#include "region.h"
+#include "rect.h"
+#include "mem.h"
+
+/* true iff two Boxes overlap */
+#define EXTENTCHECK(r1, r2) \
+ (!( ((r1)->x2 <= (r2)->x1) || \
+ ((r1)->x1 >= (r2)->x2) || \
+ ((r1)->y2 <= (r2)->y1) || \
+ ((r1)->y1 >= (r2)->y2) ) )
+
+/* true iff Box r1 contains Box r2 */
+#define SUBSUMES(r1, r2) \
+ ( ((r1)->x1 <= (r2)->x1) && \
+ ((r1)->x2 >= (r2)->x2) && \
+ ((r1)->y1 <= (r2)->y1) && \
+ ((r1)->y2 >= (r2)->y2) )
+
+
+void region_init(QRegion *rgn)
+{
+ pixman_region32_init(rgn);
+}
+
+void region_clear(QRegion *rgn)
+{
+ pixman_region32_fini(rgn);
+ pixman_region32_init(rgn);
+}
+
+void region_destroy(QRegion *rgn)
+{
+ pixman_region32_fini(rgn);
+}
+
+void region_clone(QRegion *dest, const QRegion *src)
+{
+ pixman_region32_init(dest);
+ pixman_region32_copy(dest, (pixman_region32_t *)src);
+}
+
+#define FIND_BAND(r, r_band_end, r_end, ry1) \
+ do { \
+ ry1 = r->y1; \
+ r_band_end = r + 1; \
+ while ((r_band_end != r_end) && (r_band_end->y1 == ry1)) { \
+ r_band_end++; \
+ } \
+ } while (0)
+
+static int test_band(int query,
+ int res,
+ pixman_box32_t *r1,
+ pixman_box32_t *r1_end,
+ pixman_box32_t *r2,
+ pixman_box32_t *r2_end)
+{
+ int x1;
+ int x2;
+
+ do {
+ x1 = MAX(r1->x1, r2->x1);
+ x2 = MIN(r1->x2, r2->x2);
+
+ /*
+ * Is there any overlap between the two rectangles?
+ */
+ if (x1 < x2) {
+ res |= REGION_TEST_SHARED;
+
+ if (r1->x1 < r2->x1 || r1->x2 > r2->x2) {
+ res |= REGION_TEST_LEFT_EXCLUSIVE;
+ }
+
+ if (r2->x1 < r1->x1 || r2->x2 > r1->x2) {
+ res |= REGION_TEST_RIGHT_EXCLUSIVE;
+ }
+ } else {
+ /* No overlap at all, the leftmost is exclusive */
+ if (r1->x1 < r2->x1) {
+ res |= REGION_TEST_LEFT_EXCLUSIVE;
+ } else {
+ res |= REGION_TEST_RIGHT_EXCLUSIVE;
+ }
+ }
+
+ if ((res & query) == query) {
+ return res;
+ }
+
+ /*
+ * Advance the pointer(s) with the leftmost right side, since the next
+ * rectangle on that list may still overlap the other region's
+ * current rectangle.
+ */
+ if (r1->x2 == x2) {
+ r1++;
+ }
+ if (r2->x2 == x2) {
+ r2++;
+ }
+ } while ((r1 != r1_end) && (r2 != r2_end));
+
+ /*
+ * Deal with whichever band (if any) still has rectangles left.
+ */
+ if (r1 != r1_end) {
+ res |= REGION_TEST_LEFT_EXCLUSIVE;
+ } else if (r2 != r2_end) {
+ res |= REGION_TEST_RIGHT_EXCLUSIVE;
+ }
+
+ return res;
+}
+
+static int test_generic (pixman_region32_t *reg1,
+ pixman_region32_t *reg2,
+ int query)
+{
+ pixman_box32_t *r1; /* Pointer into first region */
+ pixman_box32_t *r2; /* Pointer into 2d region */
+ pixman_box32_t *r1_end; /* End of 1st region */
+ pixman_box32_t *r2_end; /* End of 2d region */
+ int ybot; /* Bottom of intersection */
+ int ytop; /* Top of intersection */
+ pixman_box32_t * r1_band_end; /* End of current band in r1 */
+ pixman_box32_t * r2_band_end; /* End of current band in r2 */
+ int top; /* Top of non-overlapping band */
+ int bot; /* Bottom of non-overlapping band*/
+ int r1y1; /* Temps for r1->y1 and r2->y1 */
+ int r2y1;
+ int r1_num_rects;
+ int r2_num_rects;
+ int res;
+
+ r1 = pixman_region32_rectangles(reg1, &r1_num_rects);
+ r1_end = r1 + r1_num_rects;
+
+ r2 = pixman_region32_rectangles(reg2, &r2_num_rects);
+ r2_end = r2 + r2_num_rects;
+
+ res = 0;
+
+ /*
+ * Initialize ybot.
+ * In the upcoming loop, ybot and ytop serve different functions depending
+ * on whether the band being handled is an overlapping or non-overlapping
+ * band.
+ * In the case of a non-overlapping band (only one of the regions
+ * has points in the band), ybot is the bottom of the most recent
+ * intersection and thus clips the top of the rectangles in that band.
+ * ytop is the top of the next intersection between the two regions and
+ * serves to clip the bottom of the rectangles in the current band.
+ * For an overlapping band (where the two regions intersect), ytop clips
+ * the top of the rectangles of both regions and ybot clips the bottoms.
+ */
+
+ ybot = MIN(r1->y1, r2->y1);
+
+ do {
+ /*
+ * This algorithm proceeds one source-band (as opposed to a
+ * destination band, which is determined by where the two regions
+ * intersect) at a time. r1_band_end and r2_band_end serve to mark the
+ * rectangle after the last one in the current band for their
+ * respective regions.
+ */
+ FIND_BAND(r1, r1_band_end, r1_end, r1y1);
+ FIND_BAND(r2, r2_band_end, r2_end, r2y1);
+
+ /*
+ * First handle the band that doesn't intersect, if any.
+ *
+ * Note that attention is restricted to one band in the
+ * non-intersecting region at once, so if a region has n
+ * bands between the current position and the next place it overlaps
+ * the other, this entire loop will be passed through n times.
+ */
+ if (r1y1 < r2y1) {
+ top = MAX (r1y1, ybot);
+ bot = MIN (r1->y2, r2y1);
+ if (top != bot) {
+ res |= REGION_TEST_LEFT_EXCLUSIVE;
+
+ if ((res & query) == query) {
+ return res & query;
+ }
+ }
+
+ ytop = r2y1;
+ } else if (r2y1 < r1y1) {
+ top = MAX (r2y1, ybot);
+ bot = MIN (r2->y2, r1y1);
+
+ if (top != bot) {
+ res |= REGION_TEST_RIGHT_EXCLUSIVE;
+
+ if ((res & query) == query) {
+ return res & query;
+ }
+ }
+ ytop = r1y1;
+ } else {
+ ytop = r1y1;
+ }
+
+ /*
+ * Now see if we've hit an intersecting band. The two bands only
+ * intersect if ybot > ytop
+ */
+ ybot = MIN (r1->y2, r2->y2);
+ if (ybot > ytop) {
+ res = test_band(query, res,
+ r1, r1_band_end,
+ r2, r2_band_end);
+ if ((res & query) == query) {
+ return res & query;
+ }
+ }
+
+ /*
+ * If we've finished with a band (y2 == ybot) we skip forward
+ * in the region to the next band.
+ */
+ if (r1->y2 == ybot) {
+ r1 = r1_band_end;
+ }
+
+ if (r2->y2 == ybot) {
+ r2 = r2_band_end;
+ }
+
+ }
+ while (r1 != r1_end && r2 != r2_end);
+
+ /*
+ * Deal with whichever region (if any) still has rectangles left.
+ */
+
+ if (r1 != r1_end) {
+ res |= REGION_TEST_LEFT_EXCLUSIVE;
+ } else if (r2 != r2_end) {
+ res |= REGION_TEST_RIGHT_EXCLUSIVE;
+ }
+
+ return res & query;
+}
+
+int region_test(const QRegion *_reg1, const QRegion *_reg2, int query)
+{
+ int res;
+ pixman_region32_t *reg1 = (pixman_region32_t *)_reg1;
+ pixman_region32_t *reg2 = (pixman_region32_t *)_reg2;
+
+ query = (query) ? query & REGION_TEST_ALL : REGION_TEST_ALL;
+
+ res = 0;
+
+ if (!pixman_region32_not_empty(reg1) || !pixman_region32_not_empty(reg2) ||
+ !EXTENTCHECK (®1->extents, ®2->extents)) {
+ /* One or more regions are empty or they are disjoint */
+
+ if (pixman_region32_not_empty(reg1)) {
+ res |= REGION_TEST_LEFT_EXCLUSIVE;
+ }
+
+ if (pixman_region32_not_empty(reg2)) {
+ res |= REGION_TEST_RIGHT_EXCLUSIVE;
+ }
+
+ return res & query;
+ } else if (!reg1->data && !reg2->data) {
+ /* Just two rectangles that intersect */
+ res |= REGION_TEST_SHARED;
+
+ if (!SUBSUMES(®1->extents, ®2->extents)) {
+ res |= REGION_TEST_RIGHT_EXCLUSIVE;
+ }
+
+ if (!SUBSUMES(®2->extents, ®1->extents)) {
+ res |= REGION_TEST_LEFT_EXCLUSIVE;
+ }
+
+ return res & query;
+ } else if (!reg2->data && SUBSUMES (®2->extents, ®1->extents)) {
+ /* reg2 is just a rect that contains all of reg1 */
+
+ res |= REGION_TEST_SHARED; /* some piece must be shared, because reg is not empty */
+ res |= REGION_TEST_RIGHT_EXCLUSIVE; /* reg2 contains all of reg1 and then some */
+
+ return res & query;
+ } else if (!reg1->data && SUBSUMES (®1->extents, ®2->extents)) {
+ /* reg1 is just a rect that contains all of reg2 */
+
+ res |= REGION_TEST_SHARED; /* some piece must be shared, because reg is not empty */
+ res |= REGION_TEST_LEFT_EXCLUSIVE; /* reg1 contains all of reg2 and then some */
+
+ return res & query;
+ } else if (reg1 == reg2) {
+ res |= REGION_TEST_SHARED;
+ return res & query;
+ } else {
+ /* General purpose intersection */
+ return test_generic (reg1, reg2, query);
+ }
+}
+
+int region_is_valid(const QRegion *rgn)
+{
+ return pixman_region32_selfcheck((pixman_region32_t *)rgn);
+}
+
+int region_is_empty(const QRegion *rgn)
+{
+ return !pixman_region32_not_empty((pixman_region32_t *)rgn);
+}
+
+SpiceRect *region_dup_rects(const QRegion *rgn, uint32_t *num_rects)
+{
+ pixman_box32_t *boxes;
+ SpiceRect *rects;
+ int n, i;
+
+ boxes = pixman_region32_rectangles((pixman_region32_t *)rgn, &n);
+ if (num_rects) {
+ *num_rects = n;
+ }
+ rects = spice_new(SpiceRect, n);
+ for (i = 0; i < n; i++) {
+ rects[i].left = boxes[i].x1;
+ rects[i].top = boxes[i].y1;
+ rects[i].right = boxes[i].x2;
+ rects[i].bottom = boxes[i].y2;
+ }
+ return rects;
+}
+
+void region_ret_rects(const QRegion *rgn, SpiceRect *rects, uint32_t num_rects)
+{
+ pixman_box32_t *boxes;
+ unsigned int n, i;
+
+ boxes = pixman_region32_rectangles((pixman_region32_t *)rgn, (int *)&n);
+ for (i = 0; i < n && i < num_rects; i++) {
+ rects[i].left = boxes[i].x1;
+ rects[i].top = boxes[i].y1;
+ rects[i].right = boxes[i].x2;
+ rects[i].bottom = boxes[i].y2;
+ }
+
+ if (i && i != n) {
+ unsigned int x;
+
+ for (x = 0; x < (n - num_rects); ++x) {
+ rects[i - 1].left = MIN(rects[i - 1].left, boxes[i + x].x1);
+ rects[i - 1].top = MIN(rects[i - 1].top, boxes[i + x].y1);
+ rects[i - 1].right = MAX(rects[i - 1].right, boxes[i + x].x2);
+ rects[i - 1].bottom = MAX(rects[i - 1].bottom, boxes[i + x].y2);
+ }
+ }
+}
+
+void region_extents(const QRegion *rgn, SpiceRect *r)
+{
+ pixman_box32_t *extents;
+
+ extents = pixman_region32_extents((pixman_region32_t *)rgn);
+
+ r->left = extents->x1;
+ r->top = extents->y1;
+ r->right = extents->x2;
+ r->bottom = extents->y2;
+}
+
+int region_is_equal(const QRegion *rgn1, const QRegion *rgn2)
+{
+ return pixman_region32_equal((pixman_region32_t *)rgn1, (pixman_region32_t *)rgn2);
+}
+
+int region_intersects(const QRegion *rgn1, const QRegion *rgn2)
+{
+ int test_res;
+
+ if (!region_bounds_intersects(rgn1, rgn2)) {
+ return FALSE;
+ }
+
+ test_res = region_test(rgn1, rgn2, REGION_TEST_SHARED);
+ return !!test_res;
+}
+
+int region_bounds_intersects(const QRegion *rgn1, const QRegion *rgn2)
+{
+ pixman_box32_t *extents1, *extents2;
+
+ extents1 = pixman_region32_extents((pixman_region32_t *)rgn1);
+ extents2 = pixman_region32_extents((pixman_region32_t *)rgn2);
+
+ return EXTENTCHECK(extents1, extents2);
+}
+
+int region_contains(const QRegion *rgn, const QRegion *other)
+{
+ int test_res;
+
+ test_res = region_test(rgn, other, REGION_TEST_RIGHT_EXCLUSIVE);
+ return !test_res;
+}
+
+int region_contains_point(const QRegion *rgn, int32_t x, int32_t y)
+{
+ return pixman_region32_contains_point((pixman_region32_t *)rgn, x, y, NULL);
+}
+
+void region_or(QRegion *rgn, const QRegion *other_rgn)
+{
+ pixman_region32_union(rgn, rgn, (pixman_region32_t *)other_rgn);
+}
+
+void region_and(QRegion *rgn, const QRegion *other_rgn)
+{
+ pixman_region32_intersect(rgn, rgn, (pixman_region32_t *)other_rgn);
+}
+
+void region_xor(QRegion *rgn, const QRegion *other_rgn)
+{
+ pixman_region32_t intersection;
+
+ pixman_region32_copy(&intersection, rgn);
+ pixman_region32_intersect(&intersection,
+ &intersection,
+ (pixman_region32_t *)other_rgn);
+ pixman_region32_union(rgn, rgn, (pixman_region32_t *)other_rgn);
+ pixman_region32_subtract(rgn, rgn, &intersection);
+ pixman_region32_fini(&intersection);
+}
+
+void region_exclude(QRegion *rgn, const QRegion *other_rgn)
+{
+ pixman_region32_subtract(rgn, rgn, (pixman_region32_t *)other_rgn);
+}
+
+void region_add(QRegion *rgn, const SpiceRect *r)
+{
+ pixman_region32_union_rect(rgn, rgn, r->left, r->top,
+ r->right - r->left,
+ r->bottom - r->top);
+}
+
+void region_remove(QRegion *rgn, const SpiceRect *r)
+{
+ pixman_region32_t rg;
+
+ pixman_region32_init_rect(&rg, r->left, r->top,
+ r->right - r->left,
+ r->bottom - r->top);
+ pixman_region32_subtract(rgn, rgn, &rg);
+ pixman_region32_fini(&rg);
+}
+
+
+void region_offset(QRegion *rgn, int32_t dx, int32_t dy)
+{
+ pixman_region32_translate(rgn, dx, dy);
+}
+
+void region_dump(const QRegion *rgn, const char *prefix)
+{
+ pixman_box32_t *rects, *extents;
+ int n_rects, i;
+
+ printf("%sREGION: %p, ", prefix, rgn);
+
+ if (!pixman_region32_not_empty((pixman_region32_t *)rgn)) {
+ printf("EMPTY\n");
+ return;
+ }
+
+ extents = pixman_region32_extents((pixman_region32_t *)rgn);
+ rects = pixman_region32_rectangles((pixman_region32_t *)rgn, &n_rects);
+ printf("num %u bounds (%d, %d, %d, %d)\n",
+ n_rects,
+ extents->x1,
+ extents->y1,
+ extents->x2,
+ extents->y2);
+
+
+ for (i = 0; i < n_rects; i++) {
+ printf("%*s %12d %12d %12d %12d\n",
+ (int)strlen(prefix), "",
+ rects[i].x1,
+ rects[i].y1,
+ rects[i].x2,
+ rects[i].y2);
+ }
+}
+
+#ifdef REGION_TEST
+
+static int slow_region_test(const QRegion *rgn, const QRegion *other_rgn, int query)
+{
+ pixman_region32_t intersection;
+ int res;
+
+ pixman_region32_init(&intersection);
+ pixman_region32_intersect(&intersection,
+ (pixman_region32_t *)rgn,
+ (pixman_region32_t *)other_rgn);
+
+ res = 0;
+
+ if (query & REGION_TEST_SHARED &&
+ pixman_region32_not_empty(&intersection)) {
+ res |= REGION_TEST_SHARED;
+ }
+
+ if (query & REGION_TEST_LEFT_EXCLUSIVE &&
+ !pixman_region32_equal(&intersection, (pixman_region32_t *)rgn)) {
+ res |= REGION_TEST_LEFT_EXCLUSIVE;
+ }
+
+ if (query & REGION_TEST_RIGHT_EXCLUSIVE &&
+ !pixman_region32_equal(&intersection, (pixman_region32_t *)other_rgn)) {
+ res |= REGION_TEST_RIGHT_EXCLUSIVE;
+ }
+
+ pixman_region32_fini(&intersection);
+
+ return res;
+}
+
+
+static int rect_is_valid(const SpiceRect *r)
+{
+ if (r->top > r->bottom || r->left > r->right) {
+ printf("%s: invalid rect\n", __FUNCTION__);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void rect_set(SpiceRect *r, int32_t top, int32_t left, int32_t bottom, int32_t right)
+{
+ r->top = top;
+ r->left = left;
+ r->bottom = bottom;
+ r->right = right;
+ spice_assert(rect_is_valid(r));
+}
+
+static void random_region(QRegion *reg)
+{
+ int i;
+ int num_rects;
+ int x, y, w, h;
+ SpiceRect _r;
+ SpiceRect *r = &_r;
+
+ region_clear(reg);
+
+ num_rects = rand() % 20;
+ for (i = 0; i < num_rects; i++) {
+ x = rand()%100;
+ y = rand()%100;
+ w = rand()%100;
+ h = rand()%100;
+ rect_set(r,
+ x, y,
+ x+w, y+h);
+ region_add(reg, r);
+ }
+}
+
+static void test(const QRegion *r1, const QRegion *r2, int *expected)
+{
+ printf("r1 is_empty %s [%s]\n",
+ region_is_empty(r1) ? "TRUE" : "FALSE",
+ (region_is_empty(r1) == *(expected++)) ? "OK" : "ERR");
+ printf("r2 is_empty %s [%s]\n",
+ region_is_empty(r2) ? "TRUE" : "FALSE",
+ (region_is_empty(r2) == *(expected++)) ? "OK" : "ERR");
+ printf("is_equal %s [%s]\n",
+ region_is_equal(r1, r2) ? "TRUE" : "FALSE",
+ (region_is_equal(r1, r2) == *(expected++)) ? "OK" : "ERR");
+ printf("intersects %s [%s]\n",
+ region_intersects(r1, r2) ? "TRUE" : "FALSE",
+ (region_intersects(r1, r2) == *(expected++)) ? "OK" : "ERR");
+ printf("contains %s [%s]\n",
+ region_contains(r1, r2) ? "TRUE" : "FALSE",
+ (region_contains(r1, r2) == *(expected++)) ? "OK" : "ERR");
+}
+
+enum {
+ EXPECT_R1_EMPTY,
+ EXPECT_R2_EMPTY,
+ EXPECT_EQUAL,
+ EXPECT_SECT,
+ EXPECT_CONT,
+};
+
+int main(void)
+{
+ QRegion _r1, _r2, _r3;
+ QRegion *r1 = &_r1;
+ QRegion *r2 = &_r2;
+ QRegion *r3 = &_r3;
+ SpiceRect _r;
+ SpiceRect *r = &_r;
+ int expected[5];
+ int i, j;
+
+ region_init(r1);
+ region_init(r2);
+
+ printf("dump r1 empty rgn [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
+ region_dump(r1, "");
+ expected[EXPECT_R1_EMPTY] = TRUE;
+ expected[EXPECT_R2_EMPTY] = TRUE;
+ expected[EXPECT_EQUAL] = TRUE;
+ expected[EXPECT_SECT] = FALSE;
+ expected[EXPECT_CONT] = TRUE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ region_clone(r3, r1);
+ printf("dump r3 clone rgn [%s]\n", region_is_valid(r3) ? "VALID" : "INVALID");
+ region_dump(r3, "");
+ expected[EXPECT_R1_EMPTY] = TRUE;
+ expected[EXPECT_R2_EMPTY] = TRUE;
+ expected[EXPECT_EQUAL] = TRUE;
+ expected[EXPECT_SECT] = FALSE;
+ expected[EXPECT_CONT] = TRUE;
+ test(r1, r3, expected);
+ region_destroy(r3);
+ printf("\n");
+
+ rect_set(r, 0, 0, 100, 100);
+ region_add(r1, r);
+ printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
+ region_dump(r1, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = TRUE;
+ expected[EXPECT_EQUAL] = FALSE;
+ expected[EXPECT_SECT] = FALSE;
+ expected[EXPECT_CONT] = TRUE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ region_clear(r1);
+ rect_set(r, 0, 0, 0, 0);
+ region_add(r1, r);
+ printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
+ region_dump(r1, "");
+ expected[EXPECT_R1_EMPTY] = TRUE;
+ expected[EXPECT_R2_EMPTY] = TRUE;
+ expected[EXPECT_EQUAL] = TRUE;
+ expected[EXPECT_SECT] = FALSE;
+ expected[EXPECT_CONT] = TRUE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ rect_set(r, -100, -100, 0, 0);
+ region_add(r1, r);
+ printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
+ region_dump(r1, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = TRUE;
+ expected[EXPECT_EQUAL] = FALSE;
+ expected[EXPECT_SECT] = FALSE;
+ expected[EXPECT_CONT] = TRUE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ region_clear(r1);
+ rect_set(r, -100, -100, 100, 100);
+ region_add(r1, r);
+ printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
+ region_dump(r1, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = TRUE;
+ expected[EXPECT_EQUAL] = FALSE;
+ expected[EXPECT_SECT] = FALSE;
+ expected[EXPECT_CONT] = TRUE;
+ test(r1, r2, expected);
+ printf("\n");
+
+
+ region_clear(r1);
+ region_clear(r2);
+
+ rect_set(r, 100, 100, 200, 200);
+ region_add(r1, r);
+ printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
+ region_dump(r1, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = TRUE;
+ expected[EXPECT_EQUAL] = FALSE;
+ expected[EXPECT_SECT] = FALSE;
+ expected[EXPECT_CONT] = TRUE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ rect_set(r, 300, 300, 400, 400);
+ region_add(r1, r);
+ printf("dump r1 [%s]\n", region_is_valid(r1) ? "VALID" : "INVALID");
+ region_dump(r1, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = TRUE;
+ expected[EXPECT_EQUAL] = FALSE;
+ expected[EXPECT_SECT] = FALSE;
+ expected[EXPECT_CONT] = TRUE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ rect_set(r, 500, 500, 600, 600);
+ region_add(r2, r);
+ printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
+ region_dump(r2, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = FALSE;
+ expected[EXPECT_EQUAL] = FALSE;
+ expected[EXPECT_SECT] = FALSE;
+ expected[EXPECT_CONT] = FALSE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ region_clear(r2);
+
+ rect_set(r, 100, 100, 200, 200);
+ region_add(r2, r);
+ rect_set(r, 300, 300, 400, 400);
+ region_add(r2, r);
+ printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
+ region_dump(r2, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = FALSE;
+ expected[EXPECT_EQUAL] = TRUE;
+ expected[EXPECT_SECT] = TRUE;
+ expected[EXPECT_CONT] = TRUE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ region_clear(r2);
+
+ rect_set(r, 100, 100, 200, 200);
+ region_add(r2, r);
+ printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
+ region_dump(r2, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = FALSE;
+ expected[EXPECT_EQUAL] = FALSE;
+ expected[EXPECT_SECT] = TRUE;
+ expected[EXPECT_CONT] = TRUE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ region_clear(r2);
+
+ rect_set(r, -2000, -2000, -1000, -1000);
+ region_add(r2, r);
+ printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
+ region_dump(r2, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = FALSE;
+ expected[EXPECT_EQUAL] = FALSE;
+ expected[EXPECT_SECT] = FALSE;
+ expected[EXPECT_CONT] = FALSE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ region_clear(r2);
+
+ rect_set(r, -2000, -2000, 1000, 1000);
+ region_add(r2, r);
+ printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
+ region_dump(r2, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = FALSE;
+ expected[EXPECT_EQUAL] = FALSE;
+ expected[EXPECT_SECT] = TRUE;
+ expected[EXPECT_CONT] = FALSE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ region_clear(r2);
+
+ rect_set(r, 150, 150, 175, 175);
+ region_add(r2, r);
+ printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
+ region_dump(r2, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = FALSE;
+ expected[EXPECT_EQUAL] = FALSE;
+ expected[EXPECT_SECT] = TRUE;
+ expected[EXPECT_CONT] = TRUE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ region_clear(r2);
+
+ rect_set(r, 150, 150, 350, 350);
+ region_add(r2, r);
+ printf("dump r2 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
+ region_dump(r2, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = FALSE;
+ expected[EXPECT_EQUAL] = FALSE;
+ expected[EXPECT_SECT] = TRUE;
+ expected[EXPECT_CONT] = FALSE;
+ test(r1, r2, expected);
+ printf("\n");
+
+ region_and(r2, r1);
+ printf("dump r2 and r1 [%s]\n", region_is_valid(r2) ? "VALID" : "INVALID");
+ region_dump(r2, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = FALSE;
+ expected[EXPECT_EQUAL] = FALSE;
+ expected[EXPECT_SECT] = TRUE;
+ expected[EXPECT_CONT] = FALSE;
+ test(r2, r1, expected);
+ printf("\n");
+
+
+ region_clone(r3, r1);
+ printf("dump r3 clone rgn [%s]\n", region_is_valid(r3) ? "VALID" : "INVALID");
+ region_dump(r3, "");
+ expected[EXPECT_R1_EMPTY] = FALSE;
+ expected[EXPECT_R2_EMPTY] = FALSE;
+ expected[EXPECT_EQUAL] = TRUE;
+ expected[EXPECT_SECT] = TRUE;
+ expected[EXPECT_CONT] = TRUE;
+ test(r1, r3, expected);
+ printf("\n");
+
+ j = 0;
+ for (i = 0; i < 1000000; i++) {
+ int res1, res2, test;
+ int tests[] = {
+ REGION_TEST_LEFT_EXCLUSIVE,
+ REGION_TEST_RIGHT_EXCLUSIVE,
+ REGION_TEST_SHARED,
+ REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_RIGHT_EXCLUSIVE,
+ REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_SHARED,
+ REGION_TEST_RIGHT_EXCLUSIVE | REGION_TEST_SHARED,
+ REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_RIGHT_EXCLUSIVE | REGION_TEST_SHARED
+ };
+
+ random_region(r1);
+ random_region(r2);
+
+ for (test = 0; test < 7; test++) {
+ res1 = region_test(r1, r2, tests[test]);
+ res2 = slow_region_test(r1, r2, tests[test]);
+ if (res1 != res2) {
+ printf ("Error in region_test %d, got %d, expected %d, query=%d\n",
+ j, res1, res2, tests[test]);
+ printf ("r1:\n");
+ region_dump(r1, "");
+ printf ("r2:\n");
+ region_dump(r2, "");
+ }
+ j++;
+ }
+ }
+
+ region_destroy(r3);
+ region_destroy(r1);
+ region_destroy(r2);
+
+ return 0;
+}
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_REGION
+#define _H_REGION
+
+#include <stdint.h>
+#include <spice/macros.h>
+
+#include "draw.h"
+#include "pixman_utils.h"
+
+SPICE_BEGIN_DECLS
+
+typedef pixman_region32_t QRegion;
+
+#define REGION_TEST_LEFT_EXCLUSIVE (1 << 0)
+#define REGION_TEST_RIGHT_EXCLUSIVE (1 << 1)
+#define REGION_TEST_SHARED (1 << 2)
+#define REGION_TEST_ALL \
+ (REGION_TEST_LEFT_EXCLUSIVE | REGION_TEST_RIGHT_EXCLUSIVE | REGION_TEST_SHARED)
+
+void region_init(QRegion *rgn);
+void region_clear(QRegion *rgn);
+void region_destroy(QRegion *rgn);
+void region_clone(QRegion *dest, const QRegion *src);
+SpiceRect *region_dup_rects(const QRegion *rgn, uint32_t *num_rects);
+void region_ret_rects(const QRegion *rgn, SpiceRect *rects, uint32_t num_rects);
+void region_extents(const QRegion *rgn, SpiceRect *r);
+
+int region_test(const QRegion *rgn, const QRegion *other_rgn, int query);
+int region_is_valid(const QRegion *rgn);
+int region_is_empty(const QRegion *rgn);
+int region_is_equal(const QRegion *rgn1, const QRegion *rgn2);
+int region_intersects(const QRegion *rgn1, const QRegion *rgn2);
+int region_bounds_intersects(const QRegion *rgn1, const QRegion *rgn2);
+int region_contains(const QRegion *rgn, const QRegion *other);
+int region_contains_point(const QRegion *rgn, int32_t x, int32_t y);
+
+void region_or(QRegion *rgn, const QRegion *other_rgn);
+void region_and(QRegion *rgn, const QRegion *other_rgn);
+void region_xor(QRegion *rgn, const QRegion *other_rgn);
+void region_exclude(QRegion *rgn, const QRegion *other_rgn);
+
+void region_add(QRegion *rgn, const SpiceRect *r);
+void region_remove(QRegion *rgn, const SpiceRect *r);
+
+void region_offset(QRegion *rgn, int32_t dx, int32_t dy);
+
+
+void region_dump(const QRegion *rgn, const char *prefix);
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_RING2
+#define _H_RING2
+
+#include "spice_common.h"
+
+SPICE_BEGIN_DECLS
+
+typedef struct Ring RingItem;
+typedef struct Ring {
+ RingItem *prev;
+ RingItem *next;
+} Ring;
+
+static inline void ring_init(Ring *ring)
+{
+ ring->next = ring->prev = ring;
+}
+
+static inline void ring_item_init(RingItem *item)
+{
+ item->next = item->prev = NULL;
+}
+
+static inline int ring_item_is_linked(RingItem *item)
+{
+ return !!item->next;
+}
+
+static inline int ring_is_empty(Ring *ring)
+{
+ spice_assert(ring->next != NULL && ring->prev != NULL);
+ return ring == ring->next;
+}
+
+static inline void ring_add(Ring *ring, RingItem *item)
+{
+ spice_assert(ring->next != NULL && ring->prev != NULL);
+ spice_assert(item->next == NULL && item->prev == NULL);
+
+ item->next = ring->next;
+ item->prev = ring;
+ ring->next = item->next->prev = item;
+}
+
+static inline void ring_add_after(RingItem *item, RingItem *pos)
+{
+ ring_add(pos, item);
+}
+
+static inline void ring_add_before(RingItem *item, RingItem *pos)
+{
+ ring_add(pos->prev, item);
+}
+
+static inline void __ring_remove(RingItem *item)
+{
+ item->next->prev = item->prev;
+ item->prev->next = item->next;
+ item->prev = item->next = NULL;
+}
+
+static inline void ring_remove(RingItem *item)
+{
+ spice_assert(item->next != NULL && item->prev != NULL);
+ spice_assert(item->next != item);
+
+ __ring_remove(item);
+}
+
+static inline RingItem *ring_get_head(Ring *ring)
+{
+ RingItem *ret;
+
+ spice_assert(ring->next != NULL && ring->prev != NULL);
+
+ if (ring_is_empty(ring)) {
+ return NULL;
+ }
+ ret = ring->next;
+ return ret;
+}
+
+static inline RingItem *ring_get_tail(Ring *ring)
+{
+ RingItem *ret;
+
+ spice_assert(ring->next != NULL && ring->prev != NULL);
+
+ if (ring_is_empty(ring)) {
+ return NULL;
+ }
+ ret = ring->prev;
+ return ret;
+}
+
+static inline RingItem *ring_next(Ring *ring, RingItem *pos)
+{
+ RingItem *ret;
+
+ spice_assert(ring->next != NULL && ring->prev != NULL);
+ spice_assert(pos);
+ spice_assert(pos->next != NULL && pos->prev != NULL);
+ ret = pos->next;
+ return (ret == ring) ? NULL : ret;
+}
+
+static inline RingItem *ring_prev(Ring *ring, RingItem *pos)
+{
+ RingItem *ret;
+
+ spice_assert(ring->next != NULL && ring->prev != NULL);
+ spice_assert(pos);
+ spice_assert(pos->next != NULL && pos->prev != NULL);
+ ret = pos->prev;
+ return (ret == ring) ? NULL : ret;
+}
+
+#define RING_FOREACH_SAFE(var, next, ring) \
+ for ((var) = ring_get_head(ring); \
+ (var) && ((next) = ring_next(ring, (var)), 1); \
+ (var) = (next))
+
+
+#define RING_FOREACH(var, ring) \
+ for ((var) = ring_get_head(ring); \
+ (var); \
+ (var) = ring_next(ring, var))
+
+#define RING_FOREACH_REVERSED(var, ring) \
+ for ((var) = ring_get_tail(ring); \
+ (var); \
+ (var) = ring_prev(ring, var))
+
+
+static inline unsigned int ring_get_length(Ring *ring)
+{
+ RingItem *i;
+ unsigned int ret = 0;
+
+ RING_FOREACH(i, ring)
+ ret++;
+
+ return ret;
+}
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "rop3.h"
+#include "spice_common.h"
+
+typedef void (*rop3_with_pattern_handler_t)(pixman_image_t *d, pixman_image_t *s,
+ SpicePoint *src_pos, pixman_image_t *p,
+ SpicePoint *pat_pos);
+
+typedef void (*rop3_with_color_handler_t)(pixman_image_t *d, pixman_image_t *s,
+ SpicePoint *src_pos, uint32_t rgb);
+
+typedef void (*rop3_test_handler_t)(void);
+
+#define ROP3_NUM_OPS 256
+
+static rop3_with_pattern_handler_t rop3_with_pattern_handlers_32[ROP3_NUM_OPS];
+static rop3_with_pattern_handler_t rop3_with_pattern_handlers_16[ROP3_NUM_OPS];
+static rop3_with_color_handler_t rop3_with_color_handlers_32[ROP3_NUM_OPS];
+static rop3_with_color_handler_t rop3_with_color_handlers_16[ROP3_NUM_OPS];
+static rop3_test_handler_t rop3_test_handlers_32[ROP3_NUM_OPS];
+static rop3_test_handler_t rop3_test_handlers_16[ROP3_NUM_OPS];
+
+
+static void default_rop3_with_pattern_handler(SPICE_GNUC_UNUSED pixman_image_t *d,
+ SPICE_GNUC_UNUSED pixman_image_t *s,
+ SPICE_GNUC_UNUSED SpicePoint *src_pos,
+ SPICE_GNUC_UNUSED pixman_image_t *p,
+ SPICE_GNUC_UNUSED SpicePoint *pat_pos)
+{
+ spice_critical("not implemented");
+}
+
+static void default_rop3_withe_color_handler(SPICE_GNUC_UNUSED pixman_image_t *d,
+ SPICE_GNUC_UNUSED pixman_image_t *s,
+ SPICE_GNUC_UNUSED SpicePoint *src_pos,
+ SPICE_GNUC_UNUSED uint32_t rgb)
+{
+ spice_critical("not implemented");
+}
+
+static void default_rop3_test_handler(void)
+{
+}
+
+#define ROP3_HANDLERS_DEPTH(name, formula, index, depth) \
+static void rop3_handle_p##depth##_##name(pixman_image_t *d, pixman_image_t *s, \
+ SpicePoint *src_pos, \
+ pixman_image_t *p, SpicePoint *pat_pos) \
+{ \
+ int width = pixman_image_get_width(d); \
+ int height = pixman_image_get_height(d); \
+ uint8_t *dest_line = (uint8_t *)pixman_image_get_data(d); \
+ int dest_stride = pixman_image_get_stride(d); \
+ uint8_t *end_line = dest_line + height * dest_stride; \
+ \
+ int pat_width = pixman_image_get_width(p); \
+ int pat_height = pixman_image_get_height(p); \
+ uint8_t *pat_base = (uint8_t *)pixman_image_get_data(p); \
+ int pat_stride = pixman_image_get_stride(p); \
+ int pat_v_offset = pat_pos->y; \
+ \
+ int src_stride = pixman_image_get_stride(s); \
+ uint8_t *src_line; \
+ src_line = (uint8_t *)pixman_image_get_data(s) + src_pos->y * src_stride + (src_pos->x * depth / 8); \
+ \
+ for (; dest_line < end_line; dest_line += dest_stride, src_line += src_stride) { \
+ uint##depth##_t *dest = (uint##depth##_t *)dest_line; \
+ uint##depth##_t *end = dest + width; \
+ uint##depth##_t *src = (uint##depth##_t *)src_line; \
+ \
+ int pat_h_offset = pat_pos->x; \
+ \
+ for (; dest < end; dest++, src++) { \
+ uint##depth##_t *pat; \
+ pat = (uint##depth##_t *) \
+ (pat_base + pat_v_offset * pat_stride + (pat_h_offset * depth / 8)); \
+ *dest = formula; \
+ pat_h_offset = (pat_h_offset + 1) % pat_width; \
+ } \
+ \
+ pat_v_offset = (pat_v_offset + 1) % pat_height; \
+ } \
+} \
+ \
+static void rop3_handle_c##depth##_##name(pixman_image_t *d, pixman_image_t *s, \
+ SpicePoint *src_pos, \
+ uint32_t rgb) \
+{ \
+ int width = pixman_image_get_width(d); \
+ int height = pixman_image_get_height(d); \
+ uint8_t *dest_line = (uint8_t *)pixman_image_get_data(d); \
+ int dest_stride = pixman_image_get_stride(d); \
+ uint8_t *end_line = dest_line + height * dest_stride; \
+ uint##depth##_t _pat = rgb; \
+ uint##depth##_t *pat = &_pat; \
+ \
+ int src_stride = pixman_image_get_stride(s); \
+ uint8_t *src_line; \
+ src_line = (uint8_t *) \
+ pixman_image_get_data(s) + src_pos->y * src_stride + (src_pos->x * depth / 8); \
+ \
+ for (; dest_line < end_line; dest_line += dest_stride, src_line += src_stride) { \
+ uint##depth##_t *dest = (uint##depth##_t *)dest_line; \
+ uint##depth##_t *end = dest + width; \
+ uint##depth##_t *src = (uint##depth##_t *)src_line; \
+ for (; dest < end; dest++, src++) { \
+ *dest = formula; \
+ } \
+ } \
+} \
+ \
+static void rop3_test##depth##_##name(void) \
+{ \
+ uint8_t d = 0xaa; \
+ uint8_t s = 0xcc; \
+ uint8_t p = 0xf0; \
+ uint8_t *pat = &p; \
+ uint8_t *src = &s; \
+ uint8_t *dest = &d; \
+ \
+ d = formula; \
+ if (d != index) { \
+ printf("%s: failed, result is 0x%x expect 0x%x\n", __FUNCTION__, d, index); \
+ } \
+}
+
+#define ROP3_HANDLERS(name, formula, index) \
+ ROP3_HANDLERS_DEPTH(name, formula, index, 32) \
+ ROP3_HANDLERS_DEPTH(name, formula, index, 16)
+
+ROP3_HANDLERS(DPSoon, ~(*pat | *src | *dest), 0x01);
+ROP3_HANDLERS(DPSona, ~(*pat | *src) & *dest, 0x02);
+ROP3_HANDLERS(SDPona, ~(*pat | *dest) & *src, 0x04);
+ROP3_HANDLERS(PDSxnon, ~(~(*src ^ *dest) | *pat), 0x06);
+ROP3_HANDLERS(PDSaon, ~((*src & *dest) | *pat), 0x07);
+ROP3_HANDLERS(SDPnaa, ~*pat & *dest & *src, 0x08);
+ROP3_HANDLERS(PDSxon, ~((*src ^ *dest) | *pat), 0x09);
+ROP3_HANDLERS(PSDnaon, ~((~*dest & *src) | *pat), 0x0b);
+ROP3_HANDLERS(PDSnaon, ~((~*src & *dest) | *pat), 0x0d);
+ROP3_HANDLERS(PDSonon, ~(~(*src | *dest) | *pat), 0x0e);
+ROP3_HANDLERS(PDSona, ~(*src | *dest) & *pat, 0x10);
+ROP3_HANDLERS(SDPxnon, ~(~(*pat ^ *dest) | *src), 0x12);
+ROP3_HANDLERS(SDPaon, ~((*pat & *dest) | *src), 0x13);
+ROP3_HANDLERS(DPSxnon, ~(~(*pat ^ *src) | *dest), 0x14);
+ROP3_HANDLERS(DPSaon, ~((*pat & *src) | *dest), 0x15);
+ROP3_HANDLERS(PSDPSanaxx, (~(*pat & *src) & *dest) ^ *src ^ *pat, 0x16);
+ROP3_HANDLERS(SSPxDSxaxn, ~(((*src ^ *dest) & (*src ^ *pat)) ^ *src), 0x17);
+ROP3_HANDLERS(SPxPDxa, (*src ^ *pat) & (*pat ^ *dest), 0x18);
+ROP3_HANDLERS(SDPSanaxn, ~((~(*pat & *src) & *dest) ^ *src), 0x19);
+ROP3_HANDLERS(PDSPaox, ((*pat & *src) | *dest) ^ *pat, 0x1a);
+ROP3_HANDLERS(SDPSxaxn, ~(((*pat ^ *src) & *dest) ^ *src), 0x1b);
+ROP3_HANDLERS(PSDPaox, ((*pat & *dest) | *src) ^ *pat, 0x1c);
+ROP3_HANDLERS(DSPDxaxn, ~(((*pat ^ *dest) & *src) ^ *dest), 0x1d);
+ROP3_HANDLERS(PDSox, (*dest | *src) ^ *pat, 0x1e);
+ROP3_HANDLERS(PDSoan, ~((*src | *dest) & *pat), 0x1f);
+ROP3_HANDLERS(DPSnaa, ~*src & *pat & *dest, 0x20);
+ROP3_HANDLERS(SDPxon, ~((*pat ^ *dest) | *src), 0x21);
+ROP3_HANDLERS(SPDnaon, ~((~*dest & *pat) | *src), 0x23);
+ROP3_HANDLERS(SPxDSxa, (*src ^ *pat) & (*dest ^ *src), 0x24);
+ROP3_HANDLERS(PDSPanaxn, ~((~(*src & *pat) & *dest) ^ *pat), 0x25);
+ROP3_HANDLERS(SDPSaox, ((*src & *pat) | *dest) ^ *src, 0x26);
+ROP3_HANDLERS(SDPSxnox, (~(*src ^ *pat) | *dest) ^ *src, 0x27);
+ROP3_HANDLERS(DPSxa, (*pat ^ *src) & *dest, 0x28);
+ROP3_HANDLERS(PSDPSaoxxn, ~(((*src & *pat) | *dest) ^ *src ^ *pat), 0x29);
+ROP3_HANDLERS(DPSana, ~(*src & *pat) & *dest, 0x2a);
+ROP3_HANDLERS(SSPxPDxaxn, ~(((*pat ^ *dest) & (*src ^ *pat)) ^ *src), 0x2b);
+ROP3_HANDLERS(SPDSoax, ((*src | *dest) & *pat) ^ *src, 0x2c);
+ROP3_HANDLERS(PSDnox, (~*dest | *src) ^ *pat, 0x2d);
+ROP3_HANDLERS(PSDPxox, ((*pat ^ *dest) | *src) ^ *pat, 0x2e);
+ROP3_HANDLERS(PSDnoan, ~((~*dest | *src) & *pat), 0x2f);
+ROP3_HANDLERS(SDPnaon, ~((~*pat & *dest) | *src), 0x31);
+ROP3_HANDLERS(SDPSoox, (*src | *pat | *dest) ^ *src, 0x32);
+ROP3_HANDLERS(SPDSaox, ((*src & *dest) | *pat) ^ *src, 0x34);
+ROP3_HANDLERS(SPDSxnox, (~(*src ^ *dest) | *pat) ^ *src, 0x35);
+ROP3_HANDLERS(SDPox, (*pat | *dest) ^ *src, 0x36);
+ROP3_HANDLERS(SDPoan, ~((*pat | *dest) & *src), 0x37);
+ROP3_HANDLERS(PSDPoax, ((*pat | *dest) & *src) ^ *pat, 0x38);
+ROP3_HANDLERS(SPDnox, (~*dest | *pat) ^ *src, 0x39);
+ROP3_HANDLERS(SPDSxox, ((*src ^ *dest) | *pat) ^ *src, 0x3a);
+ROP3_HANDLERS(SPDnoan, ~((~*dest | *pat) & *src), 0x3b);
+ROP3_HANDLERS(SPDSonox, (~(*src | *dest) | *pat) ^ *src, 0x3d);
+ROP3_HANDLERS(SPDSnaox, ((~*src & *dest) | *pat) ^ *src, 0x3e);
+ROP3_HANDLERS(PSDnaa, ~*dest & *src & *pat, 0x40);
+ROP3_HANDLERS(DPSxon, ~((*src ^ *pat) | *dest), 0x41);
+ROP3_HANDLERS(SDxPDxa, (*src ^ *dest) & (*pat ^ *dest), 0x42);
+ROP3_HANDLERS(SPDSanaxn, ~((~(*src & *dest) & *pat) ^ *src), 0x43);
+ROP3_HANDLERS(DPSnaon, ~((~*src & *pat) | *dest), 0x45);
+ROP3_HANDLERS(DSPDaox, ((*dest & *pat) | *src) ^ *dest, 0x46);
+ROP3_HANDLERS(PSDPxaxn, ~(((*pat ^ *dest) & *src) ^ *pat), 0x47);
+ROP3_HANDLERS(SDPxa, (*pat ^ *dest) & *src, 0x48);
+ROP3_HANDLERS(PDSPDaoxxn, ~(((*dest & *pat) | *src) ^ *dest ^ *pat), 0x49);
+ROP3_HANDLERS(DPSDoax, ((*dest | *src) & *pat) ^ *dest, 0x4a);
+ROP3_HANDLERS(PDSnox, (~*src | *dest) ^ *pat, 0x4b);
+ROP3_HANDLERS(SDPana, ~(*pat & *dest) & *src, 0x4c);
+ROP3_HANDLERS(SSPxDSxoxn, ~(((*src ^ *dest) | (*src ^ *pat)) ^ *src), 0x4d);
+ROP3_HANDLERS(PDSPxox, ((*pat ^ *src) | *dest) ^ *pat, 0x4e);
+ROP3_HANDLERS(PDSnoan, ~((~*src | *dest) & *pat), 0x4f);
+ROP3_HANDLERS(DSPnaon, ~((~*pat & *src) | *dest), 0x51);
+ROP3_HANDLERS(DPSDaox, ((*dest & *src) | *pat) ^ *dest, 0x52);
+ROP3_HANDLERS(SPDSxaxn, ~(((*src ^ *dest) & *pat) ^ *src), 0x53);
+ROP3_HANDLERS(DPSonon, ~(~(*src | *pat) | *dest), 0x54);
+ROP3_HANDLERS(DPSox, (*src | *pat) ^ *dest, 0x56);
+ROP3_HANDLERS(DPSoan, ~((*src | *pat) & *dest), 0x57);
+ROP3_HANDLERS(PDSPoax, ((*pat | *src) & *dest) ^ *pat, 0x58);
+ROP3_HANDLERS(DPSnox, (~*src | *pat) ^ *dest, 0x59);
+ROP3_HANDLERS(DPSDonox, (~(*dest | *src) | *pat) ^ *dest, 0x5b);
+ROP3_HANDLERS(DPSDxox, ((*dest ^ *src) | *pat) ^ *dest, 0x5c);
+ROP3_HANDLERS(DPSnoan, ~((~*src | *pat) & *dest), 0x5d);
+ROP3_HANDLERS(DPSDnaox, ((~*dest & *src) | *pat) ^ *dest, 0x5e);
+ROP3_HANDLERS(PDSxa, (*src ^ *dest) & *pat, 0x60);
+ROP3_HANDLERS(DSPDSaoxxn, ~(((*src & *dest) | *pat) ^ *src ^ *dest), 0x61);
+ROP3_HANDLERS(DSPDoax, ((*dest | *pat) & *src) ^ *dest, 0x62);
+ROP3_HANDLERS(SDPnox, (~*pat | *dest) ^ *src, 0x63);
+ROP3_HANDLERS(SDPSoax, ((*src | *pat) & *dest) ^ *src, 0x64);
+ROP3_HANDLERS(DSPnox, (~*pat | *src) ^ *dest, 0x65);
+ROP3_HANDLERS(SDPSonox, (~(*src | *pat) | *dest) ^ *src, 0x67);
+ROP3_HANDLERS(DSPDSonoxxn, ~((~(*src | *dest) | *pat) ^ *src ^ *dest), 0x68);
+ROP3_HANDLERS(PDSxxn, ~(*src ^ *dest ^ *pat), 0x69);
+ROP3_HANDLERS(DPSax, (*src & *pat) ^ *dest, 0x6a);
+ROP3_HANDLERS(PSDPSoaxxn, ~(((*src | *pat) & *dest) ^ *src ^ *pat), 0x6b);
+ROP3_HANDLERS(SDPax, (*pat & *dest) ^ *src, 0x6c);
+ROP3_HANDLERS(PDSPDoaxxn, ~(((*dest | *pat) & *src) ^ *dest ^ *pat), 0x6d);
+ROP3_HANDLERS(SDPSnoax, ((~*src | *pat) & *dest) ^ *src, 0x6e);
+ROP3_HANDLERS(PDSxnan, ~(~(*src ^ *dest) & *pat), 0x6f);
+ROP3_HANDLERS(PDSana, ~(*src & *dest) & *pat, 0x70);
+ROP3_HANDLERS(SSDxPDxaxn, ~(((*dest ^ *pat) & (*src ^ *dest)) ^ *src), 0x71);
+ROP3_HANDLERS(SDPSxox, ((*src ^ *pat) | *dest) ^ *src, 0x72);
+ROP3_HANDLERS(SDPnoan, ~((~*pat | *dest) & *src), 0x73);
+ROP3_HANDLERS(DSPDxox, ((*dest ^ *pat) | *src) ^ *dest, 0x74);
+ROP3_HANDLERS(DSPnoan, ~((~*pat | *src) & *dest), 0x75);
+ROP3_HANDLERS(SDPSnaox, ((~*src & *pat) | *dest) ^ *src, 0x76);
+ROP3_HANDLERS(PDSax, (*src & *dest) ^ *pat, 0x78);
+ROP3_HANDLERS(DSPDSoaxxn, ~(((*src | *dest) & *pat) ^ *src ^ *dest), 0x79);
+ROP3_HANDLERS(DPSDnoax, ((~*dest | *src) & *pat) ^ *dest, 0x7a);
+ROP3_HANDLERS(SDPxnan, ~(~(*pat ^ *dest) & *src), 0x7b);
+ROP3_HANDLERS(SPDSnoax, ((~*src | *dest) & *pat) ^ *src, 0x7c);
+ROP3_HANDLERS(DPSxnan, ~(~(*src ^ *pat) & *dest), 0x7d);
+ROP3_HANDLERS(SPxDSxo, (*src ^ *dest) | (*pat ^ *src), 0x7e);
+ROP3_HANDLERS(DPSaan, ~(*src & *pat & *dest), 0x7f);
+ROP3_HANDLERS(DPSaa, *src & *pat & *dest, 0x80);
+ROP3_HANDLERS(SPxDSxon, ~((*src ^ *dest) | (*pat ^ *src)), 0x81);
+ROP3_HANDLERS(DPSxna, ~(*src ^ *pat) & *dest, 0x82);
+ROP3_HANDLERS(SPDSnoaxn, ~(((~*src | *dest) & *pat) ^ *src), 0x83);
+ROP3_HANDLERS(SDPxna, ~(*pat ^ *dest) & *src, 0x84);
+ROP3_HANDLERS(PDSPnoaxn, ~(((~*pat | *src) & *dest) ^ *pat), 0x85);
+ROP3_HANDLERS(DSPDSoaxx, ((*src | *dest) & *pat) ^ *src ^ *dest, 0x86);
+ROP3_HANDLERS(PDSaxn, ~((*src & *dest) ^ *pat), 0x87);
+ROP3_HANDLERS(SDPSnaoxn, ~(((~*src & *pat) | *dest) ^ *src), 0x89);
+ROP3_HANDLERS(DSPnoa, (~*pat | *src) & *dest, 0x8a);
+ROP3_HANDLERS(DSPDxoxn, ~(((*dest ^ *pat) | *src) ^ *dest), 0x8b);
+ROP3_HANDLERS(SDPnoa, (~*pat | *dest) & *src, 0x8c);
+ROP3_HANDLERS(SDPSxoxn, ~(((*src ^ *pat) | *dest) ^ *src), 0x8d);
+ROP3_HANDLERS(SSDxPDxax, ((*dest ^ *pat) & (*dest ^ *src)) ^ *src, 0x8e);
+ROP3_HANDLERS(PDSanan, ~(~(*src & *dest) & *pat), 0x8f);
+ROP3_HANDLERS(PDSxna, ~(*src ^ *dest) & *pat, 0x90);
+ROP3_HANDLERS(SDPSnoaxn, ~(((~*src | *pat) & *dest) ^ *src), 0x91);
+ROP3_HANDLERS(DPSDPoaxx, ((*pat | *dest) & *src) ^ *pat ^ *dest, 0x92);
+ROP3_HANDLERS(SPDaxn, ~((*dest & *pat) ^ *src), 0x93);
+ROP3_HANDLERS(PSDPSoaxx, ((*src | *pat) & *dest) ^ *src ^ *pat, 0x94);
+ROP3_HANDLERS(DPSaxn, ~((*src & *pat) ^ *dest), 0x95);
+ROP3_HANDLERS(DPSxx, *src ^ *pat ^ *dest, 0x96);
+ROP3_HANDLERS(PSDPSonoxx, (~(*src | *pat) | *dest) ^ *src ^ *pat, 0x97);
+ROP3_HANDLERS(SDPSonoxn, ~((~(*src | *pat) | *dest) ^ *src), 0x98);
+ROP3_HANDLERS(DPSnax, (~*src & *pat) ^ *dest, 0x9a);
+ROP3_HANDLERS(SDPSoaxn, ~(((*src | *pat) & *dest) ^ *src), 0x9b);
+ROP3_HANDLERS(SPDnax, (~*dest & *pat) ^ *src, 0x9c);
+ROP3_HANDLERS(DSPDoaxn, ~(((*dest | *pat) & *src) ^ *dest), 0x9d);
+ROP3_HANDLERS(DSPDSaoxx, ((*src & *dest) | *pat) ^ *src ^ *dest, 0x9e);
+ROP3_HANDLERS(PDSxan, ~((*src ^ *dest) & *pat), 0x9f);
+ROP3_HANDLERS(PDSPnaoxn, ~(((~*pat & *src) | *dest) ^ *pat), 0xa1);
+ROP3_HANDLERS(DPSnoa, (~*src | *pat) & *dest, 0xa2);
+ROP3_HANDLERS(DPSDxoxn, ~(((*dest ^ *src) | *pat) ^ *dest), 0xa3);
+ROP3_HANDLERS(PDSPonoxn, ~((~(*pat | *src) | *dest) ^ *pat), 0xa4);
+ROP3_HANDLERS(DSPnax, (~*pat & *src) ^ *dest, 0xa6);
+ROP3_HANDLERS(PDSPoaxn, ~(((*pat | *src) & *dest) ^ *pat), 0xa7);
+ROP3_HANDLERS(DPSoa, (*src | *pat) & *dest, 0xa8);
+ROP3_HANDLERS(DPSoxn, ~((*src | *pat) ^ *dest), 0xa9);
+ROP3_HANDLERS(DPSono, ~(*src | *pat) | *dest, 0xab);
+ROP3_HANDLERS(SPDSxax, ((*src ^ *dest) & *pat) ^ *src, 0xac);
+ROP3_HANDLERS(DPSDaoxn, ~(((*dest & *src) | *pat) ^ *dest), 0xad);
+ROP3_HANDLERS(DSPnao, (~*pat & *src) | *dest, 0xae);
+ROP3_HANDLERS(PDSnoa, (~*src | *dest) & *pat, 0xb0);
+ROP3_HANDLERS(PDSPxoxn, ~(((*pat ^ *src) | *dest) ^ *pat), 0xb1);
+ROP3_HANDLERS(SSPxDSxox, ((*src ^ *dest) | (*pat ^ *src)) ^ *src, 0xb2);
+ROP3_HANDLERS(SDPanan, ~(~(*pat & *dest) & *src), 0xb3);
+ROP3_HANDLERS(PSDnax, (~*dest & *src) ^ *pat, 0xb4);
+ROP3_HANDLERS(DPSDoaxn, ~(((*dest | *src) & *pat) ^ *dest), 0xb5);
+ROP3_HANDLERS(DPSDPaoxx, ((*pat & *dest) | *src) ^ *pat ^ *dest, 0xb6);
+ROP3_HANDLERS(SDPxan, ~((*pat ^ *dest) & *src), 0xb7);
+ROP3_HANDLERS(PSDPxax, ((*dest ^ *pat) & *src) ^ *pat, 0xb8);
+ROP3_HANDLERS(DSPDaoxn, ~(((*dest & *pat) | *src) ^ *dest), 0xb9);
+ROP3_HANDLERS(DPSnao, (~*src & *pat) | *dest, 0xba);
+ROP3_HANDLERS(SPDSanax, (~(*src & *dest) & *pat) ^ *src, 0xbc);
+ROP3_HANDLERS(SDxPDxan, ~((*dest ^ *pat) & (*dest ^ *src)), 0xbd);
+ROP3_HANDLERS(DPSxo, (*src ^ *pat) | *dest, 0xbe);
+ROP3_HANDLERS(DPSano, ~(*src & *pat) | *dest, 0xbf);
+ROP3_HANDLERS(SPDSnaoxn, ~(((~*src & *dest) | *pat) ^ *src), 0xc1);
+ROP3_HANDLERS(SPDSonoxn, ~((~(*src | *dest) | *pat) ^ *src), 0xc2);
+ROP3_HANDLERS(SPDnoa, (~*dest | *pat) & *src, 0xc4);
+ROP3_HANDLERS(SPDSxoxn, ~(((*src ^ *dest) | *pat) ^ *src), 0xc5);
+ROP3_HANDLERS(SDPnax, (~*pat & *dest) ^ *src, 0xc6);
+ROP3_HANDLERS(PSDPoaxn, ~(((*pat | *dest) & *src) ^ *pat), 0xc7);
+ROP3_HANDLERS(SDPoa, (*pat | *dest) & *src, 0xc8);
+ROP3_HANDLERS(SPDoxn, ~((*dest | *pat) ^ *src), 0xc9);
+ROP3_HANDLERS(DPSDxax, ((*dest ^ *src) & *pat) ^ *dest, 0xca);
+ROP3_HANDLERS(SPDSaoxn, ~(((*src & *dest) | *pat) ^ *src), 0xcb);
+ROP3_HANDLERS(SDPono, ~(*pat | *dest) | *src, 0xcd);
+ROP3_HANDLERS(SDPnao, (~*pat & *dest) | *src, 0xce);
+ROP3_HANDLERS(PSDnoa, (~*dest | *src) & *pat, 0xd0);
+ROP3_HANDLERS(PSDPxoxn, ~(((*pat ^ *dest) | *src) ^ *pat), 0xd1);
+ROP3_HANDLERS(PDSnax, (~*src & *dest) ^ *pat, 0xd2);
+ROP3_HANDLERS(SPDSoaxn, ~(((*src | *dest) & *pat) ^ *src), 0xd3);
+ROP3_HANDLERS(SSPxPDxax, ((*dest ^ *pat) & (*pat ^ *src)) ^ *src, 0xd4);
+ROP3_HANDLERS(DPSanan, ~(~(*src & *pat) & *dest), 0xd5);
+ROP3_HANDLERS(PSDPSaoxx, ((*src & *pat) | *dest) ^ *src ^ *pat, 0xd6);
+ROP3_HANDLERS(DPSxan, ~((*src ^ *pat) & *dest), 0xd7);
+ROP3_HANDLERS(PDSPxax, ((*pat ^ *src) & *dest) ^ *pat, 0xd8);
+ROP3_HANDLERS(SDPSaoxn, ~(((*src & *pat) | *dest) ^ *src), 0xd9);
+ROP3_HANDLERS(DPSDanax, (~(*dest & *src) & *pat) ^ *dest, 0xda);
+ROP3_HANDLERS(SPxDSxan, ~((*src ^ *dest) & (*pat ^ *src)), 0xdb);
+ROP3_HANDLERS(SPDnao, (~*dest & *pat) | *src, 0xdc);
+ROP3_HANDLERS(SDPxo, (*pat ^ *dest) | *src, 0xde);
+ROP3_HANDLERS(SDPano, ~(*pat & *dest) | *src, 0xdf);
+ROP3_HANDLERS(PDSoa, (*src | *dest) & *pat, 0xe0);
+ROP3_HANDLERS(PDSoxn, ~((*src | *dest) ^ *pat), 0xe1);
+ROP3_HANDLERS(DSPDxax, ((*dest ^ *pat) & *src) ^ *dest, 0xe2);
+ROP3_HANDLERS(PSDPaoxn, ~(((*pat & *dest) | *src) ^ *pat), 0xe3);
+ROP3_HANDLERS(SDPSxax, ((*src ^ *pat) & *dest) ^ *src, 0xe4);
+ROP3_HANDLERS(PDSPaoxn, ~(((*pat & *src) | *dest) ^ *pat), 0xe5);
+ROP3_HANDLERS(SDPSanax, (~(*src & *pat) & *dest) ^ *src, 0xe6);
+ROP3_HANDLERS(SPxPDxan, ~((*dest ^ *pat) & (*pat ^ *src)), 0xe7);
+ROP3_HANDLERS(SSPxDSxax, ((*src ^ *dest) & (*pat ^ *src)) ^ *src, 0xe8);
+ROP3_HANDLERS(DSPDSanaxxn, ~((~(*src & *dest) & *pat) ^ *src ^ *dest), 0xe9);
+ROP3_HANDLERS(DPSao, (*src & *pat) | *dest, 0xea);
+ROP3_HANDLERS(DPSxno, ~(*src ^ *pat) | *dest, 0xeb);
+ROP3_HANDLERS(SDPao, (*pat & *dest) | *src, 0xec);
+ROP3_HANDLERS(SDPxno, ~(*pat ^ *dest) | *src, 0xed);
+ROP3_HANDLERS(SDPnoo, ~*pat | *dest | *src, 0xef);
+ROP3_HANDLERS(PDSono, ~(*src | *dest) | *pat, 0xf1);
+ROP3_HANDLERS(PDSnao, (~*src & *dest) | *pat, 0xf2);
+ROP3_HANDLERS(PSDnao, (~*dest & *src) | *pat, 0xf4);
+ROP3_HANDLERS(PDSxo, (*src ^ *dest) | *pat, 0xf6);
+ROP3_HANDLERS(PDSano, ~(*src & *dest) | *pat, 0xf7);
+ROP3_HANDLERS(PDSao, (*src & *dest) | *pat, 0xf8);
+ROP3_HANDLERS(PDSxno, ~(*src ^ *dest) | *pat, 0xf9);
+ROP3_HANDLERS(DPSnoo, ~*src | *pat | *dest, 0xfb);
+ROP3_HANDLERS(PSDnoo, ~*dest | *src | *pat, 0xfd);
+ROP3_HANDLERS(DPSoo, *src | *pat | *dest, 0xfe);
+
+
+#define ROP3_FILL_HANDLERS(op, index) \
+ rop3_with_pattern_handlers_32[index] = rop3_handle_p32_##op; \
+ rop3_with_pattern_handlers_16[index] = rop3_handle_p16_##op; \
+ rop3_with_color_handlers_32[index] = rop3_handle_c32_##op; \
+ rop3_with_color_handlers_16[index] = rop3_handle_c16_##op; \
+ rop3_test_handlers_32[index] = rop3_test32_##op; \
+ rop3_test_handlers_16[index] = rop3_test16_##op;
+
+SPICE_CONSTRUCTOR_FUNC(rop3_global_init)
+{
+ int i;
+
+ for (i = 0; i < ROP3_NUM_OPS; i++) {
+ rop3_with_pattern_handlers_32[i] = default_rop3_with_pattern_handler;
+ rop3_with_pattern_handlers_16[i] = default_rop3_with_pattern_handler;
+ rop3_with_color_handlers_32[i] = default_rop3_withe_color_handler;
+ rop3_with_color_handlers_16[i] = default_rop3_withe_color_handler;
+ rop3_test_handlers_32[i] = default_rop3_test_handler;
+ rop3_test_handlers_16[i] = default_rop3_test_handler;
+ }
+
+ ROP3_FILL_HANDLERS(DPSoon, 0x01);
+ ROP3_FILL_HANDLERS(DPSona, 0x02);
+ ROP3_FILL_HANDLERS(SDPona, 0x04);
+ ROP3_FILL_HANDLERS(PDSxnon, 0x06);
+ ROP3_FILL_HANDLERS(PDSaon, 0x07);
+ ROP3_FILL_HANDLERS(SDPnaa, 0x08);
+ ROP3_FILL_HANDLERS(PDSxon, 0x09);
+ ROP3_FILL_HANDLERS(PSDnaon, 0x0b);
+ ROP3_FILL_HANDLERS(PDSnaon, 0x0d);
+ ROP3_FILL_HANDLERS(PDSonon, 0x0e);
+ ROP3_FILL_HANDLERS(PDSona, 0x10);
+ ROP3_FILL_HANDLERS(SDPxnon, 0x12);
+ ROP3_FILL_HANDLERS(SDPaon, 0x13);
+ ROP3_FILL_HANDLERS(DPSxnon, 0x14);
+ ROP3_FILL_HANDLERS(DPSaon, 0x15);
+ ROP3_FILL_HANDLERS(PSDPSanaxx, 0x16);
+ ROP3_FILL_HANDLERS(SSPxDSxaxn, 0x17);
+ ROP3_FILL_HANDLERS(SPxPDxa, 0x18);
+ ROP3_FILL_HANDLERS(SDPSanaxn, 0x19);
+ ROP3_FILL_HANDLERS(PDSPaox, 0x1a);
+ ROP3_FILL_HANDLERS(SDPSxaxn, 0x1b);
+ ROP3_FILL_HANDLERS(PSDPaox, 0x1c);
+ ROP3_FILL_HANDLERS(DSPDxaxn, 0x1d);
+ ROP3_FILL_HANDLERS(PDSox, 0x1e);
+ ROP3_FILL_HANDLERS(PDSoan, 0x1f);
+ ROP3_FILL_HANDLERS(DPSnaa, 0x20);
+ ROP3_FILL_HANDLERS(SDPxon, 0x21);
+ ROP3_FILL_HANDLERS(SPDnaon, 0x23);
+ ROP3_FILL_HANDLERS(SPxDSxa, 0x24);
+ ROP3_FILL_HANDLERS(PDSPanaxn, 0x25);
+ ROP3_FILL_HANDLERS(SDPSaox, 0x26);
+ ROP3_FILL_HANDLERS(SDPSxnox, 0x27);
+ ROP3_FILL_HANDLERS(DPSxa, 0x28);
+ ROP3_FILL_HANDLERS(PSDPSaoxxn, 0x29);
+ ROP3_FILL_HANDLERS(DPSana, 0x2a);
+ ROP3_FILL_HANDLERS(SSPxPDxaxn, 0x2b);
+ ROP3_FILL_HANDLERS(SPDSoax, 0x2c);
+ ROP3_FILL_HANDLERS(PSDnox, 0x2d);
+ ROP3_FILL_HANDLERS(PSDPxox, 0x2e);
+ ROP3_FILL_HANDLERS(PSDnoan, 0x2f);
+ ROP3_FILL_HANDLERS(SDPnaon, 0x31);
+ ROP3_FILL_HANDLERS(SDPSoox, 0x32);
+ ROP3_FILL_HANDLERS(SPDSaox, 0x34);
+ ROP3_FILL_HANDLERS(SPDSxnox, 0x35);
+ ROP3_FILL_HANDLERS(SDPox, 0x36);
+ ROP3_FILL_HANDLERS(SDPoan, 0x37);
+ ROP3_FILL_HANDLERS(PSDPoax, 0x38);
+ ROP3_FILL_HANDLERS(SPDnox, 0x39);
+ ROP3_FILL_HANDLERS(SPDSxox, 0x3a);
+ ROP3_FILL_HANDLERS(SPDnoan, 0x3b);
+ ROP3_FILL_HANDLERS(SPDSonox, 0x3d);
+ ROP3_FILL_HANDLERS(SPDSnaox, 0x3e);
+ ROP3_FILL_HANDLERS(PSDnaa, 0x40);
+ ROP3_FILL_HANDLERS(DPSxon, 0x41);
+ ROP3_FILL_HANDLERS(SDxPDxa, 0x42);
+ ROP3_FILL_HANDLERS(SPDSanaxn, 0x43);
+ ROP3_FILL_HANDLERS(DPSnaon, 0x45);
+ ROP3_FILL_HANDLERS(DSPDaox, 0x46);
+ ROP3_FILL_HANDLERS(PSDPxaxn, 0x47);
+ ROP3_FILL_HANDLERS(SDPxa, 0x48);
+ ROP3_FILL_HANDLERS(PDSPDaoxxn, 0x49);
+ ROP3_FILL_HANDLERS(DPSDoax, 0x4a);
+ ROP3_FILL_HANDLERS(PDSnox, 0x4b);
+ ROP3_FILL_HANDLERS(SDPana, 0x4c);
+ ROP3_FILL_HANDLERS(SSPxDSxoxn, 0x4d);
+ ROP3_FILL_HANDLERS(PDSPxox, 0x4e);
+ ROP3_FILL_HANDLERS(PDSnoan, 0x4f);
+ ROP3_FILL_HANDLERS(DSPnaon, 0x51);
+ ROP3_FILL_HANDLERS(DPSDaox, 0x52);
+ ROP3_FILL_HANDLERS(SPDSxaxn, 0x53);
+ ROP3_FILL_HANDLERS(DPSonon, 0x54);
+ ROP3_FILL_HANDLERS(DPSox, 0x56);
+ ROP3_FILL_HANDLERS(DPSoan, 0x57);
+ ROP3_FILL_HANDLERS(PDSPoax, 0x58);
+ ROP3_FILL_HANDLERS(DPSnox, 0x59);
+ ROP3_FILL_HANDLERS(DPSDonox, 0x5b);
+ ROP3_FILL_HANDLERS(DPSDxox, 0x5c);
+ ROP3_FILL_HANDLERS(DPSnoan, 0x5d);
+ ROP3_FILL_HANDLERS(DPSDnaox, 0x5e);
+ ROP3_FILL_HANDLERS(PDSxa, 0x60);
+ ROP3_FILL_HANDLERS(DSPDSaoxxn, 0x61);
+ ROP3_FILL_HANDLERS(DSPDoax, 0x62);
+ ROP3_FILL_HANDLERS(SDPnox, 0x63);
+ ROP3_FILL_HANDLERS(SDPSoax, 0x64);
+ ROP3_FILL_HANDLERS(DSPnox, 0x65);
+ ROP3_FILL_HANDLERS(SDPSonox, 0x67);
+ ROP3_FILL_HANDLERS(DSPDSonoxxn, 0x68);
+ ROP3_FILL_HANDLERS(PDSxxn, 0x69);
+ ROP3_FILL_HANDLERS(DPSax, 0x6a);
+ ROP3_FILL_HANDLERS(PSDPSoaxxn, 0x6b);
+ ROP3_FILL_HANDLERS(SDPax, 0x6c);
+ ROP3_FILL_HANDLERS(PDSPDoaxxn, 0x6d);
+ ROP3_FILL_HANDLERS(SDPSnoax, 0x6e);
+ ROP3_FILL_HANDLERS(PDSxnan, 0x6f);
+ ROP3_FILL_HANDLERS(PDSana, 0x70);
+ ROP3_FILL_HANDLERS(SSDxPDxaxn, 0x71);
+ ROP3_FILL_HANDLERS(SDPSxox, 0x72);
+ ROP3_FILL_HANDLERS(SDPnoan, 0x73);
+ ROP3_FILL_HANDLERS(DSPDxox, 0x74);
+ ROP3_FILL_HANDLERS(DSPnoan, 0x75);
+ ROP3_FILL_HANDLERS(SDPSnaox, 0x76);
+ ROP3_FILL_HANDLERS(PDSax, 0x78);
+ ROP3_FILL_HANDLERS(DSPDSoaxxn, 0x79);
+ ROP3_FILL_HANDLERS(DPSDnoax, 0x7a);
+ ROP3_FILL_HANDLERS(SDPxnan, 0x7b);
+ ROP3_FILL_HANDLERS(SPDSnoax, 0x7c);
+ ROP3_FILL_HANDLERS(DPSxnan, 0x7d);
+ ROP3_FILL_HANDLERS(SPxDSxo, 0x7e);
+ ROP3_FILL_HANDLERS(DPSaan, 0x7f);
+ ROP3_FILL_HANDLERS(DPSaa, 0x80);
+ ROP3_FILL_HANDLERS(SPxDSxon, 0x81);
+ ROP3_FILL_HANDLERS(DPSxna, 0x82);
+ ROP3_FILL_HANDLERS(SPDSnoaxn, 0x83);
+ ROP3_FILL_HANDLERS(SDPxna, 0x84);
+ ROP3_FILL_HANDLERS(PDSPnoaxn, 0x85);
+ ROP3_FILL_HANDLERS(DSPDSoaxx, 0x86);
+ ROP3_FILL_HANDLERS(PDSaxn, 0x87);
+ ROP3_FILL_HANDLERS(SDPSnaoxn, 0x89);
+ ROP3_FILL_HANDLERS(DSPnoa, 0x8a);
+ ROP3_FILL_HANDLERS(DSPDxoxn, 0x8b);
+ ROP3_FILL_HANDLERS(SDPnoa, 0x8c);
+ ROP3_FILL_HANDLERS(SDPSxoxn, 0x8d);
+ ROP3_FILL_HANDLERS(SSDxPDxax, 0x8e);
+ ROP3_FILL_HANDLERS(PDSanan, 0x8f);
+ ROP3_FILL_HANDLERS(PDSxna, 0x90);
+ ROP3_FILL_HANDLERS(SDPSnoaxn, 0x91);
+ ROP3_FILL_HANDLERS(DPSDPoaxx, 0x92);
+ ROP3_FILL_HANDLERS(SPDaxn, 0x93);
+ ROP3_FILL_HANDLERS(PSDPSoaxx, 0x94);
+ ROP3_FILL_HANDLERS(DPSaxn, 0x95);
+ ROP3_FILL_HANDLERS(DPSxx, 0x96);
+ ROP3_FILL_HANDLERS(PSDPSonoxx, 0x97);
+ ROP3_FILL_HANDLERS(SDPSonoxn, 0x98);
+ ROP3_FILL_HANDLERS(DPSnax, 0x9a);
+ ROP3_FILL_HANDLERS(SDPSoaxn, 0x9b);
+ ROP3_FILL_HANDLERS(SPDnax, 0x9c);
+ ROP3_FILL_HANDLERS(DSPDoaxn, 0x9d);
+ ROP3_FILL_HANDLERS(DSPDSaoxx, 0x9e);
+ ROP3_FILL_HANDLERS(PDSxan, 0x9f);
+ ROP3_FILL_HANDLERS(PDSPnaoxn, 0xa1);
+ ROP3_FILL_HANDLERS(DPSnoa, 0xa2);
+ ROP3_FILL_HANDLERS(DPSDxoxn, 0xa3);
+ ROP3_FILL_HANDLERS(PDSPonoxn, 0xa4);
+ ROP3_FILL_HANDLERS(DSPnax, 0xa6);
+ ROP3_FILL_HANDLERS(PDSPoaxn, 0xa7);
+ ROP3_FILL_HANDLERS(DPSoa, 0xa8);
+ ROP3_FILL_HANDLERS(DPSoxn, 0xa9);
+ ROP3_FILL_HANDLERS(DPSono, 0xab);
+ ROP3_FILL_HANDLERS(SPDSxax, 0xac);
+ ROP3_FILL_HANDLERS(DPSDaoxn, 0xad);
+ ROP3_FILL_HANDLERS(DSPnao, 0xae);
+ ROP3_FILL_HANDLERS(PDSnoa, 0xb0);
+ ROP3_FILL_HANDLERS(PDSPxoxn, 0xb1);
+ ROP3_FILL_HANDLERS(SSPxDSxox, 0xb2);
+ ROP3_FILL_HANDLERS(SDPanan, 0xb3);
+ ROP3_FILL_HANDLERS(PSDnax, 0xb4);
+ ROP3_FILL_HANDLERS(DPSDoaxn, 0xb5);
+ ROP3_FILL_HANDLERS(DPSDPaoxx, 0xb6);
+ ROP3_FILL_HANDLERS(SDPxan, 0xb7);
+ ROP3_FILL_HANDLERS(PSDPxax, 0xb8);
+ ROP3_FILL_HANDLERS(DSPDaoxn, 0xb9);
+ ROP3_FILL_HANDLERS(DPSnao, 0xba);
+ ROP3_FILL_HANDLERS(SPDSanax, 0xbc);
+ ROP3_FILL_HANDLERS(SDxPDxan, 0xbd);
+ ROP3_FILL_HANDLERS(DPSxo, 0xbe);
+ ROP3_FILL_HANDLERS(DPSano, 0xbf);
+ ROP3_FILL_HANDLERS(SPDSnaoxn, 0xc1);
+ ROP3_FILL_HANDLERS(SPDSonoxn, 0xc2);
+ ROP3_FILL_HANDLERS(SPDnoa, 0xc4);
+ ROP3_FILL_HANDLERS(SPDSxoxn, 0xc5);
+ ROP3_FILL_HANDLERS(SDPnax, 0xc6);
+ ROP3_FILL_HANDLERS(PSDPoaxn, 0xc7);
+ ROP3_FILL_HANDLERS(SDPoa, 0xc8);
+ ROP3_FILL_HANDLERS(SPDoxn, 0xc9);
+ ROP3_FILL_HANDLERS(DPSDxax, 0xca);
+ ROP3_FILL_HANDLERS(SPDSaoxn, 0xcb);
+ ROP3_FILL_HANDLERS(SDPono, 0xcd);
+ ROP3_FILL_HANDLERS(SDPnao, 0xce);
+ ROP3_FILL_HANDLERS(PSDnoa, 0xd0);
+ ROP3_FILL_HANDLERS(PSDPxoxn, 0xd1);
+ ROP3_FILL_HANDLERS(PDSnax, 0xd2);
+ ROP3_FILL_HANDLERS(SPDSoaxn, 0xd3);
+ ROP3_FILL_HANDLERS(SSPxPDxax, 0xd4);
+ ROP3_FILL_HANDLERS(DPSanan, 0xd5);
+ ROP3_FILL_HANDLERS(PSDPSaoxx, 0xd6);
+ ROP3_FILL_HANDLERS(DPSxan, 0xd7);
+ ROP3_FILL_HANDLERS(PDSPxax, 0xd8);
+ ROP3_FILL_HANDLERS(SDPSaoxn, 0xd9);
+ ROP3_FILL_HANDLERS(DPSDanax, 0xda);
+ ROP3_FILL_HANDLERS(SPxDSxan, 0xdb);
+ ROP3_FILL_HANDLERS(SPDnao, 0xdc);
+ ROP3_FILL_HANDLERS(SDPxo, 0xde);
+ ROP3_FILL_HANDLERS(SDPano, 0xdf);
+ ROP3_FILL_HANDLERS(PDSoa, 0xe0);
+ ROP3_FILL_HANDLERS(PDSoxn, 0xe1);
+ ROP3_FILL_HANDLERS(DSPDxax, 0xe2);
+ ROP3_FILL_HANDLERS(PSDPaoxn, 0xe3);
+ ROP3_FILL_HANDLERS(SDPSxax, 0xe4);
+ ROP3_FILL_HANDLERS(PDSPaoxn, 0xe5);
+ ROP3_FILL_HANDLERS(SDPSanax, 0xe6);
+ ROP3_FILL_HANDLERS(SPxPDxan, 0xe7);
+ ROP3_FILL_HANDLERS(SSPxDSxax, 0xe8);
+ ROP3_FILL_HANDLERS(DSPDSanaxxn, 0xe9);
+ ROP3_FILL_HANDLERS(DPSao, 0xea);
+ ROP3_FILL_HANDLERS(DPSxno, 0xeb);
+ ROP3_FILL_HANDLERS(SDPao, 0xec);
+ ROP3_FILL_HANDLERS(SDPxno, 0xed);
+ ROP3_FILL_HANDLERS(SDPnoo, 0xef);
+ ROP3_FILL_HANDLERS(PDSono, 0xf1);
+ ROP3_FILL_HANDLERS(PDSnao, 0xf2);
+ ROP3_FILL_HANDLERS(PSDnao, 0xf4);
+ ROP3_FILL_HANDLERS(PDSxo, 0xf6);
+ ROP3_FILL_HANDLERS(PDSano, 0xf7);
+ ROP3_FILL_HANDLERS(PDSao, 0xf8);
+ ROP3_FILL_HANDLERS(PDSxno, 0xf9);
+ ROP3_FILL_HANDLERS(DPSnoo, 0xfb);
+ ROP3_FILL_HANDLERS(PSDnoo, 0xfd);
+ ROP3_FILL_HANDLERS(DPSoo, 0xfe);
+
+ for (i = 0; i < ROP3_NUM_OPS; i++) {
+ rop3_test_handlers_32[i]();
+ rop3_test_handlers_16[i]();
+ }
+}
+
+void do_rop3_with_pattern(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
+ pixman_image_t *p, SpicePoint *pat_pos)
+{
+ int bpp;
+
+ bpp = spice_pixman_image_get_bpp(d);
+ spice_assert(bpp == spice_pixman_image_get_bpp(s));
+ spice_assert(bpp == spice_pixman_image_get_bpp(p));
+
+ if (bpp == 32) {
+ rop3_with_pattern_handlers_32[rop3](d, s, src_pos, p, pat_pos);
+ } else {
+ rop3_with_pattern_handlers_16[rop3](d, s, src_pos, p, pat_pos);
+ }
+}
+
+void do_rop3_with_color(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
+ uint32_t rgb)
+{
+ int bpp;
+
+ bpp = spice_pixman_image_get_bpp(d);
+ spice_assert(bpp == spice_pixman_image_get_bpp(s));
+
+ if (bpp == 32) {
+ rop3_with_color_handlers_32[rop3](d, s, src_pos, rgb);
+ } else {
+ rop3_with_color_handlers_16[rop3](d, s, src_pos, rgb);
+ }
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_ROP3
+#define _H_ROP3
+
+#include <stdint.h>
+#include <spice/macros.h>
+
+#include "draw.h"
+#include "pixman_utils.h"
+
+SPICE_BEGIN_DECLS
+
+void do_rop3_with_pattern(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
+ pixman_image_t *p, SpicePoint *pat_pos);
+void do_rop3_with_color(uint8_t rop3, pixman_image_t *d, pixman_image_t *s, SpicePoint *src_pos,
+ uint32_t rgb);
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2013 Jeremy White
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* snd_codec.c
+ General purpose sound codec routines for use by Spice.
+ These routines abstract the work of picking a codec and
+ encoding and decoding the buffers.
+ Note: these routines have some peculiarities that come from
+ wanting to provide full backwards compatibility with the original
+ Spice celt 0.51 implementation. It has some hard requirements
+ (fixed sample size, fixed compressed buffer size).
+
+ See below for documentation of the public routines.
+*/
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <spice/macros.h>
+#include <spice/enums.h>
+
+
+#include "snd_codec.h"
+#include "mem.h"
+#include "log.h"
+
+typedef struct
+{
+ int mode;
+ int frequency;
+#if HAVE_CELT051
+ CELTMode *celt_mode;
+ CELTEncoder *celt_encoder;
+ CELTDecoder *celt_decoder;
+#endif
+
+#if HAVE_OPUS
+ OpusEncoder *opus_encoder;
+ OpusDecoder *opus_decoder;
+#endif
+} SndCodecInternal;
+
+
+
+/* celt 0.51 specific support routines */
+#if HAVE_CELT051
+static void snd_codec_destroy_celt051(SndCodecInternal *codec)
+{
+ if (codec->celt_decoder) {
+ celt051_decoder_destroy(codec->celt_decoder);
+ codec->celt_decoder = NULL;
+ }
+
+ if (codec->celt_encoder) {
+ celt051_encoder_destroy(codec->celt_encoder);
+ codec->celt_encoder = NULL;
+ }
+
+ if (codec->celt_mode) {
+ celt051_mode_destroy(codec->celt_mode);
+ codec->celt_mode = NULL;
+ }
+}
+
+static int snd_codec_create_celt051(SndCodecInternal *codec, int purpose)
+{
+ int celt_error;
+
+ codec->celt_mode = celt051_mode_create(codec->frequency,
+ SND_CODEC_PLAYBACK_CHAN,
+ SND_CODEC_CELT_FRAME_SIZE, &celt_error);
+ if (! codec->celt_mode) {
+ spice_printerr("create celt mode failed %d", celt_error);
+ return SND_CODEC_UNAVAILABLE;
+ }
+
+ if (purpose & SND_CODEC_ENCODE) {
+ codec->celt_encoder = celt051_encoder_create(codec->celt_mode);
+ if (! codec->celt_encoder) {
+ spice_printerr("create celt encoder failed");
+ goto error;
+ }
+ }
+
+ if (purpose & SND_CODEC_DECODE) {
+ codec->celt_decoder = celt051_decoder_create(codec->celt_mode);
+ if (! codec->celt_decoder) {
+ spice_printerr("create celt decoder failed");
+ goto error;
+ }
+ }
+
+ codec->mode = SPICE_AUDIO_DATA_MODE_CELT_0_5_1;
+ return SND_CODEC_OK;
+
+error:
+ snd_codec_destroy_celt051(codec);
+ return SND_CODEC_UNAVAILABLE;
+}
+
+static int snd_codec_encode_celt051(SndCodecInternal *codec, uint8_t *in_ptr, int in_size, uint8_t *out_ptr, int *out_size)
+{
+ int n;
+ if (in_size != SND_CODEC_CELT_FRAME_SIZE * SND_CODEC_PLAYBACK_CHAN * 2)
+ return SND_CODEC_INVALID_ENCODE_SIZE;
+ n = celt051_encode(codec->celt_encoder, (celt_int16_t *) in_ptr, NULL, out_ptr, *out_size);
+ if (n < 0) {
+ spice_printerr("celt051_encode failed %d\n", n);
+ return SND_CODEC_ENCODE_FAILED;
+ }
+ *out_size = n;
+ return SND_CODEC_OK;
+}
+
+static int snd_codec_decode_celt051(SndCodecInternal *codec, uint8_t *in_ptr, int in_size, uint8_t *out_ptr, int *out_size)
+{
+ int n;
+ n = celt051_decode(codec->celt_decoder, in_ptr, in_size, (celt_int16_t *) out_ptr);
+ if (n < 0) {
+ spice_printerr("celt051_decode failed %d\n", n);
+ return SND_CODEC_DECODE_FAILED;
+ }
+ *out_size = SND_CODEC_CELT_FRAME_SIZE * SND_CODEC_PLAYBACK_CHAN * 2 /* 16 fmt */;
+ return SND_CODEC_OK;
+}
+#endif
+
+
+/* Opus support routines */
+#if HAVE_OPUS
+static void snd_codec_destroy_opus(SndCodecInternal *codec)
+{
+ if (codec->opus_decoder) {
+ opus_decoder_destroy(codec->opus_decoder);
+ codec->opus_decoder = NULL;
+ }
+
+ if (codec->opus_encoder) {
+ opus_encoder_destroy(codec->opus_encoder);
+ codec->opus_encoder = NULL;
+ }
+
+}
+
+static int snd_codec_create_opus(SndCodecInternal *codec, int purpose)
+{
+ int opus_error;
+
+ if (purpose & SND_CODEC_ENCODE) {
+ codec->opus_encoder = opus_encoder_create(codec->frequency,
+ SND_CODEC_PLAYBACK_CHAN,
+ OPUS_APPLICATION_AUDIO, &opus_error);
+ if (! codec->opus_encoder) {
+ spice_printerr("create opus encoder failed; error %d", opus_error);
+ goto error;
+ }
+ }
+
+ if (purpose & SND_CODEC_DECODE) {
+ codec->opus_decoder = opus_decoder_create(codec->frequency,
+ SND_CODEC_PLAYBACK_CHAN, &opus_error);
+ if (! codec->opus_decoder) {
+ spice_printerr("create opus decoder failed; error %d", opus_error);
+ goto error;
+ }
+ }
+
+ codec->mode = SPICE_AUDIO_DATA_MODE_OPUS;
+ return SND_CODEC_OK;
+
+error:
+ snd_codec_destroy_opus(codec);
+ return SND_CODEC_UNAVAILABLE;
+}
+
+static int snd_codec_encode_opus(SndCodecInternal *codec, uint8_t *in_ptr, int in_size, uint8_t *out_ptr, int *out_size)
+{
+ int n;
+ if (in_size != SND_CODEC_OPUS_FRAME_SIZE * SND_CODEC_PLAYBACK_CHAN * 2)
+ return SND_CODEC_INVALID_ENCODE_SIZE;
+ n = opus_encode(codec->opus_encoder, (opus_int16 *) in_ptr, SND_CODEC_OPUS_FRAME_SIZE, out_ptr, *out_size);
+ if (n < 0) {
+ spice_printerr("opus_encode failed %d\n", n);
+ return SND_CODEC_ENCODE_FAILED;
+ }
+ *out_size = n;
+ return SND_CODEC_OK;
+}
+
+static int snd_codec_decode_opus(SndCodecInternal *codec, uint8_t *in_ptr, int in_size, uint8_t *out_ptr, int *out_size)
+{
+ int n;
+ n = opus_decode(codec->opus_decoder, in_ptr, in_size, (opus_int16 *) out_ptr,
+ *out_size / SND_CODEC_PLAYBACK_CHAN / 2, 0);
+ if (n < 0) {
+ spice_printerr("opus_decode failed %d\n", n);
+ return SND_CODEC_DECODE_FAILED;
+ }
+ *out_size = n * SND_CODEC_PLAYBACK_CHAN * 2 /* 16 fmt */;
+ return SND_CODEC_OK;
+}
+#endif
+
+
+/*----------------------------------------------------------------------------
+** PUBLIC INTERFACE
+**--------------------------------------------------------------------------*/
+
+/*
+ snd_codec_is_capable
+ Returns TRUE if the current spice implementation can
+ use the given codec, FALSE otherwise.
+ mode must be a SPICE_AUDIO_DATA_MODE_XXX enum from spice/enum.h
+ */
+int snd_codec_is_capable(int mode, int frequency)
+{
+#if HAVE_CELT051
+ if (mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1)
+ return TRUE;
+#endif
+
+#if HAVE_OPUS
+ if (mode == SPICE_AUDIO_DATA_MODE_OPUS &&
+ (frequency == SND_CODEC_ANY_FREQUENCY ||
+ frequency == 48000 || frequency == 24000 ||
+ frequency == 16000 || frequency == 12000 ||
+ frequency == 8000) )
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
+/*
+ snd_codec_create
+ Create a codec control. Required for most functions in this library.
+ Parameters:
+ 1. codec Pointer to preallocated codec control
+ 2. mode SPICE_AUDIO_DATA_MODE_XXX enum from spice/enum.h
+ 3. encode TRUE if encoding is desired
+ 4. decode TRUE if decoding is desired
+ Returns:
+ SND_CODEC_OK if all went well; a different code if not.
+
+ snd_codec_destroy is the obvious partner of snd_codec_create.
+ */
+int snd_codec_create(SndCodec *codec, int mode, int frequency, int purpose)
+{
+ int rc = SND_CODEC_UNAVAILABLE;
+ SndCodecInternal **c = (SndCodecInternal **) codec;
+
+ *c = spice_new0(SndCodecInternal, 1);
+ (*c)->frequency = frequency;
+
+#if HAVE_CELT051
+ if (mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1)
+ rc = snd_codec_create_celt051(*c, purpose);
+#endif
+
+#if HAVE_OPUS
+ if (mode == SPICE_AUDIO_DATA_MODE_OPUS)
+ rc = snd_codec_create_opus(*c, purpose);
+#endif
+
+ return rc;
+}
+
+/*
+ snd_codec_destroy
+ The obvious companion to snd_codec_create
+*/
+void snd_codec_destroy(SndCodec *codec)
+{
+ SndCodecInternal **c = (SndCodecInternal **) codec;
+ if (! c || ! *c)
+ return;
+
+#if HAVE_CELT051
+ snd_codec_destroy_celt051(*c);
+#endif
+
+#if HAVE_OPUS
+ snd_codec_destroy_opus(*c);
+#endif
+
+ free(*c);
+ *c = NULL;
+}
+
+/*
+ snd_codec_frame_size
+ Returns the size, in frames, of the raw PCM frame buffer
+ required by this codec. To get bytes, you'll need
+ to multiply by channels and sample width.
+ */
+int snd_codec_frame_size(SndCodec codec)
+{
+#if defined(HAVE_CELT051) || defined(HAVE_OPUS)
+ SndCodecInternal *c = (SndCodecInternal *) codec;
+#endif
+#if HAVE_CELT051
+ if (c && c->mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1)
+ return SND_CODEC_CELT_FRAME_SIZE;
+#endif
+#if HAVE_OPUS
+ if (c && c->mode == SPICE_AUDIO_DATA_MODE_OPUS)
+ return SND_CODEC_OPUS_FRAME_SIZE;
+#endif
+ return SND_CODEC_MAX_FRAME_SIZE;
+}
+
+/*
+ snd_codec_encode
+ Encode a block of data to a compressed buffer.
+
+ Parameters:
+ 1. codec Pointer to codec control previously allocated + created
+ 2. in_data Pointer to uncompressed PCM data
+ 3. in_size Input size (for celt, this must be a
+ particular size, governed by the frame size)
+ 4. out_ptr Pointer to area to write encoded data
+ 5. out_size On input, the maximum size of the output buffer; on
+ successful return, it will hold the number of bytes
+ returned. For celt, this must be set to a particular
+ size to ensure compatibility.
+
+ Returns:
+ SND_CODEC_OK if all went well
+*/
+int snd_codec_encode(SndCodec codec, uint8_t *in_ptr, int in_size, uint8_t *out_ptr, int *out_size)
+{
+#if defined(HAVE_CELT051) || defined(HAVE_OPUS)
+ SndCodecInternal *c = (SndCodecInternal *) codec;
+#endif
+#if HAVE_CELT051
+ if (c && c->mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1) {
+ /* The output buffer size in celt determines the compression,
+ and so is essentially mandatory to use a certain value (47) */
+ if (*out_size > SND_CODEC_CELT_COMPRESSED_FRAME_BYTES)
+ *out_size = SND_CODEC_CELT_COMPRESSED_FRAME_BYTES;
+ return snd_codec_encode_celt051(c, in_ptr, in_size, out_ptr, out_size);
+ }
+#endif
+
+#if HAVE_OPUS
+ if (c && c->mode == SPICE_AUDIO_DATA_MODE_OPUS)
+ return snd_codec_encode_opus(c, in_ptr, in_size, out_ptr, out_size);
+#endif
+
+ return SND_CODEC_ENCODER_UNAVAILABLE;
+}
+
+/*
+ snd_codec_decode
+ Decode a block of data from a compressed buffer.
+
+ Parameters:
+ 1. codec Pointer to codec control previously allocated + created
+ 2. in_data Pointer to compressed data
+ 3. in_size Input size
+ 4. out_ptr Pointer to area to write decoded data
+ 5. out_size On input, the maximum size of the output buffer; on
+ successful return, it will hold the number of bytes
+ returned.
+
+ Returns:
+ SND_CODEC_OK if all went well
+*/
+int snd_codec_decode(SndCodec codec, uint8_t *in_ptr, int in_size, uint8_t *out_ptr, int *out_size)
+{
+#if defined(HAVE_CELT051) || defined(HAVE_OPUS)
+ SndCodecInternal *c = (SndCodecInternal *) codec;
+#endif
+#if HAVE_CELT051
+ if (c && c->mode == SPICE_AUDIO_DATA_MODE_CELT_0_5_1)
+ return snd_codec_decode_celt051(c, in_ptr, in_size, out_ptr, out_size);
+#endif
+
+#if HAVE_OPUS
+ if (c && c->mode == SPICE_AUDIO_DATA_MODE_OPUS)
+ return snd_codec_decode_opus(c, in_ptr, in_size, out_ptr, out_size);
+#endif
+
+ return SND_CODEC_DECODER_UNAVAILABLE;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2013 Jeremy White <jwhite@codeweavers.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_SND_CODEC
+#define _H_SND_CODEC
+
+
+#if HAVE_CELT051
+#include <celt051/celt.h>
+#endif
+
+#if HAVE_OPUS
+#include <opus.h>
+#endif
+
+/* Spice uses a very fixed protocol when transmitting CELT audio;
+ audio must be transmitted in frames of 256, and we must compress
+ data down to a fairly specific size (47, computation below).
+ While the protocol doesn't inherently specify this, the expectation
+ of older clients and server mandates it.
+*/
+#define SND_CODEC_CELT_FRAME_SIZE 256
+#define SND_CODEC_CELT_BIT_RATE (64 * 1024)
+#define SND_CODEC_CELT_PLAYBACK_FREQ 44100
+#define SND_CODEC_CELT_COMPRESSED_FRAME_BYTES (SND_CODEC_CELT_FRAME_SIZE * SND_CODEC_CELT_BIT_RATE / \
+ SND_CODEC_CELT_PLAYBACK_FREQ / 8)
+
+#define SND_CODEC_OPUS_FRAME_SIZE 480
+#define SND_CODEC_OPUS_PLAYBACK_FREQ 48000
+#define SND_CODEC_OPUS_COMPRESSED_FRAME_BYTES 480
+
+#define SND_CODEC_PLAYBACK_CHAN 2
+
+#define SND_CODEC_MAX_FRAME_SIZE (MAX(SND_CODEC_CELT_FRAME_SIZE, SND_CODEC_OPUS_FRAME_SIZE))
+#define SND_CODEC_MAX_FRAME_BYTES (SND_CODEC_MAX_FRAME_SIZE * SND_CODEC_PLAYBACK_CHAN * 2 /* FMT_S16 */)
+#define SND_CODEC_MAX_COMPRESSED_BYTES MAX(SND_CODEC_CELT_COMPRESSED_FRAME_BYTES, SND_CODEC_OPUS_COMPRESSED_FRAME_BYTES)
+
+#define SND_CODEC_ANY_FREQUENCY -1
+
+#define SND_CODEC_OK 0
+#define SND_CODEC_UNAVAILABLE 1
+#define SND_CODEC_ENCODER_UNAVAILABLE 2
+#define SND_CODEC_DECODER_UNAVAILABLE 3
+#define SND_CODEC_ENCODE_FAILED 4
+#define SND_CODEC_DECODE_FAILED 5
+#define SND_CODEC_INVALID_ENCODE_SIZE 6
+
+#define SND_CODEC_ENCODE 0x0001
+#define SND_CODEC_DECODE 0x0002
+
+SPICE_BEGIN_DECLS
+
+typedef struct SndCodecInternal * SndCodec;
+
+int snd_codec_is_capable(int mode, int frequency);
+
+int snd_codec_create(SndCodec *codec, int mode, int frequency, int purpose);
+void snd_codec_destroy(SndCodec *codec);
+
+int snd_codec_frame_size(SndCodec codec);
+
+int snd_codec_encode(SndCodec codec, uint8_t *in_ptr, int in_size, uint8_t *out_ptr, int *out_size);
+int snd_codec_decode(SndCodec codec, uint8_t *in_ptr, int in_size, uint8_t *out_ptr, int *out_size);
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef H_SPICE_COMMON
+#define H_SPICE_COMMON
+
+#include <stdio.h>
+#include <stdint.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#include <spice/macros.h>
+#include "backtrace.h"
+#include "log.h"
+
+#ifdef SPICE_DISABLE_ABORT
+#define spice_abort() do { } while(0)
+#else
+#define spice_abort() abort()
+#endif
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "mem.h"
+#include "ssl_verify.h"
+#include "log.h"
+
+#ifndef WIN32
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+#include <ctype.h>
+#include <string.h>
+#include <gio/gio.h>
+
+static int verify_pubkey(X509* cert, const char *key, size_t key_size)
+{
+ EVP_PKEY* cert_pubkey = NULL;
+ EVP_PKEY* orig_pubkey = NULL;
+ BIO* bio = NULL;
+ int ret = 0;
+
+ if (!key || key_size == 0)
+ return 0;
+
+ if (!cert) {
+ spice_debug("warning: no cert!");
+ return 0;
+ }
+
+ cert_pubkey = X509_get_pubkey(cert);
+ if (!cert_pubkey) {
+ spice_debug("warning: reading public key from certificate failed");
+ goto finish;
+ }
+
+ bio = BIO_new_mem_buf((void*)key, key_size);
+ if (!bio) {
+ spice_debug("creating BIO failed");
+ goto finish;
+ }
+
+ orig_pubkey = d2i_PUBKEY_bio(bio, NULL);
+ if (!orig_pubkey) {
+ spice_debug("reading pubkey from bio failed");
+ goto finish;
+ }
+
+ ret = EVP_PKEY_cmp(orig_pubkey, cert_pubkey);
+
+ if (ret == 1) {
+ spice_debug("public keys match");
+ } else if (ret == 0) {
+ spice_debug("public keys mismatch");
+ } else {
+ spice_debug("public keys types mismatch");
+ }
+
+finish:
+ if (bio)
+ BIO_free(bio);
+
+ if (orig_pubkey)
+ EVP_PKEY_free(orig_pubkey);
+
+ if (cert_pubkey)
+ EVP_PKEY_free(cert_pubkey);
+
+ return ret;
+}
+
+/* from gnutls
+ * compare hostname against certificate, taking account of wildcards
+ * return 1 on success or 0 on error
+ *
+ * note: certnamesize is required as X509 certs can contain embedded NULs in
+ * the strings such as CN or subjectAltName
+ */
+static int _gnutls_hostname_compare(const char *certname,
+ size_t certnamesize, const char *hostname)
+{
+ /* find the first different character */
+ for (; *certname && *hostname && toupper (*certname) == toupper (*hostname);
+ certname++, hostname++, certnamesize--)
+ ;
+
+ /* the strings are the same */
+ if (certnamesize == 0 && *hostname == '\0')
+ return 1;
+
+ if (*certname == '*')
+ {
+ /* a wildcard certificate */
+
+ certname++;
+ certnamesize--;
+
+ while (1)
+ {
+ /* Use a recursive call to allow multiple wildcards */
+ if (_gnutls_hostname_compare (certname, certnamesize, hostname))
+ return 1;
+
+ /* wildcards are only allowed to match a single domain
+ component or component fragment */
+ if (*hostname == '\0' || *hostname == '.')
+ break;
+ hostname++;
+ }
+
+ return 0;
+ }
+
+ return 0;
+}
+
+/**
+ * From gnutls and spice red_peer.c
+ * TODO: switch to gnutls and get rid of this
+ *
+ * This function will check if the given certificate's subject matches
+ * the given hostname. This is a basic implementation of the matching
+ * described in RFC2818 (HTTPS), which takes into account wildcards,
+ * and the DNSName/IPAddress subject alternative name PKIX extension.
+ *
+ * Returns: 1 for a successful match, and 0 on failure.
+ **/
+static int verify_hostname(X509* cert, const char *hostname)
+{
+ GENERAL_NAMES* subject_alt_names;
+ int found_dns_name = 0;
+ int cn_match = 0;
+ X509_NAME* subject;
+
+ spice_return_val_if_fail(hostname != NULL, 0);
+
+ if (!cert) {
+ spice_debug("warning: no cert!");
+ return 0;
+ }
+
+ /* try matching against:
+ * 1) a DNS name as an alternative name (subjectAltName) extension
+ * in the certificate
+ * 2) the common name (CN) in the certificate
+ *
+ * either of these may be of the form: *.domain.tld
+ *
+ * only try (2) if there is no subjectAltName extension of
+ * type dNSName
+ */
+
+ /* Check through all included subjectAltName extensions, comparing
+ * against all those of type dNSName.
+ */
+ subject_alt_names = (GENERAL_NAMES*)X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
+
+ if (subject_alt_names) {
+ int num_alts = sk_GENERAL_NAME_num(subject_alt_names);
+ int i;
+ for (i = 0; i < num_alts; i++) {
+ const GENERAL_NAME* name = sk_GENERAL_NAME_value(subject_alt_names, i);
+ if (name->type == GEN_DNS) {
+ found_dns_name = 1;
+ if (_gnutls_hostname_compare((char *)ASN1_STRING_data(name->d.dNSName),
+ ASN1_STRING_length(name->d.dNSName),
+ hostname)) {
+ spice_debug("alt name match=%s", ASN1_STRING_data(name->d.dNSName));
+ GENERAL_NAMES_free(subject_alt_names);
+ return 1;
+ }
+ } else if (name->type == GEN_IPADD) {
+ GInetAddress * ip = NULL;
+ const guint8 * ip_binary = NULL;
+ int alt_ip_len = 0;
+ int ip_len = 0;
+
+ found_dns_name = 1;
+
+ ip = g_inet_address_new_from_string(hostname);
+ if (ip != NULL) {
+ ip_len = g_inet_address_get_native_size(ip);
+ ip_binary = g_inet_address_to_bytes(ip);
+ } else {
+ spice_warning("Could not parse hostname: %s", hostname);
+ }
+
+ alt_ip_len = ASN1_STRING_length(name->d.iPAddress);
+
+ if ((ip_len == alt_ip_len) &&
+ (memcmp(ASN1_STRING_data(name->d.iPAddress), ip_binary, ip_len)) == 0) {
+ GInetAddress * alt_ip = NULL;
+ gchar * alt_ip_string = NULL;
+
+ alt_ip = g_inet_address_new_from_bytes(ASN1_STRING_data(name->d.iPAddress),
+ g_inet_address_get_family(ip));
+ alt_ip_string = g_inet_address_to_string(alt_ip);
+ spice_debug("alt name IP match=%s", alt_ip_string);
+
+ g_free(alt_ip_string);
+ g_object_unref(alt_ip);
+ g_object_unref(ip);
+ GENERAL_NAMES_free(subject_alt_names);
+ return 1;
+ }
+ if (ip != NULL) {
+ g_object_unref(ip);
+ }
+ }
+ }
+ GENERAL_NAMES_free(subject_alt_names);
+ }
+
+ if (found_dns_name) {
+ spice_debug("warning: SubjectAltName mismatch");
+ return 0;
+ }
+
+ /* extracting commonNames */
+ subject = X509_get_subject_name(cert);
+ if (subject) {
+ int pos = -1;
+ X509_NAME_ENTRY* cn_entry;
+ ASN1_STRING* cn_asn1;
+
+ while ((pos = X509_NAME_get_index_by_NID(subject, NID_commonName, pos)) != -1) {
+ cn_entry = X509_NAME_get_entry(subject, pos);
+ if (!cn_entry) {
+ continue;
+ }
+ cn_asn1 = X509_NAME_ENTRY_get_data(cn_entry);
+ if (!cn_asn1) {
+ continue;
+ }
+
+ if (_gnutls_hostname_compare((char*)ASN1_STRING_data(cn_asn1),
+ ASN1_STRING_length(cn_asn1),
+ hostname)) {
+ spice_debug("common name match=%s", (char*)ASN1_STRING_data(cn_asn1));
+ cn_match = 1;
+ break;
+ }
+ }
+ }
+
+ if (!cn_match) {
+ spice_debug("warning: common name mismatch");
+ }
+
+ return cn_match;
+}
+
+static X509_NAME* subject_to_x509_name(const char *subject, int *nentries)
+{
+ X509_NAME* in_subject;
+ const char *p;
+ char *key, *val, *k, *v = NULL;
+ enum {
+ KEY,
+ VALUE
+ } state;
+
+ spice_return_val_if_fail(subject != NULL, NULL);
+ spice_return_val_if_fail(nentries != NULL, NULL);
+
+ key = (char*)alloca(strlen(subject));
+ val = (char*)alloca(strlen(subject));
+ in_subject = X509_NAME_new();
+
+ if (!in_subject || !key || !val) {
+ spice_debug("failed to allocate");
+ return NULL;
+ }
+
+ *nentries = 0;
+
+ k = key;
+ state = KEY;
+ for (p = subject;; ++p) {
+ int escape = 0;
+ if (*p == '\\') {
+ ++p;
+ if (*p != '\\' && *p != ',') {
+ spice_debug("Invalid character after \\");
+ goto fail;
+ }
+ escape = 1;
+ }
+
+ switch (state) {
+ case KEY:
+ if (*p == ' ' && k == key) {
+ continue; /* skip spaces before key */
+ } if (*p == 0) {
+ if (k == key) /* empty key, ending */
+ goto success;
+ goto fail;
+ } else if (*p == ',' && !escape) {
+ goto fail; /* assignment is missing */
+ } else if (*p == '=' && !escape) {
+ state = VALUE;
+ *k = 0;
+ v = val;
+ } else
+ *k++ = *p;
+ break;
+ case VALUE:
+ if (*p == 0 || (*p == ',' && !escape)) {
+ if (v == val) /* empty value */
+ goto fail;
+
+ *v = 0;
+
+ if (!X509_NAME_add_entry_by_txt(in_subject, key,
+ MBSTRING_UTF8,
+ (const unsigned char*)val,
+ -1, -1, 0)) {
+ spice_debug("warning: failed to add entry %s=%s to X509_NAME",
+ key, val);
+ goto fail;
+ }
+ *nentries += 1;
+
+ if (*p == 0)
+ goto success;
+
+ state = KEY;
+ k = key;
+ } else
+ *v++ = *p;
+ break;
+ }
+ }
+
+success:
+ return in_subject;
+
+fail:
+ if (in_subject)
+ X509_NAME_free(in_subject);
+
+ return NULL;
+}
+
+static int verify_subject(X509* cert, SpiceOpenSSLVerify* verify)
+{
+ X509_NAME *cert_subject = NULL;
+ X509_NAME* in_subject;
+ int ret;
+ int in_entries;
+
+ if (!cert) {
+ spice_debug("warning: no cert!");
+ return 0;
+ }
+
+ cert_subject = X509_get_subject_name(cert);
+ if (!cert_subject) {
+ spice_debug("warning: reading certificate subject failed");
+ return 0;
+ }
+
+ in_subject = subject_to_x509_name(verify->subject, &in_entries);
+ if (!in_subject) {
+ spice_debug("warning: no in_subject!");
+ return 0;
+ }
+
+ /* Note: this check is redundant with the pre-condition in X509_NAME_cmp */
+ if (X509_NAME_entry_count(cert_subject) != in_entries) {
+ spice_debug("subject mismatch: #entries cert=%d, input=%d",
+ X509_NAME_entry_count(cert_subject), in_entries);
+ X509_NAME_free(in_subject);
+ return 0;
+ }
+
+ ret = X509_NAME_cmp(cert_subject, in_subject);
+
+ if (ret == 0) {
+ spice_debug("subjects match");
+ } else {
+ char *p;
+ spice_debug("subjects mismatch");
+
+ p = X509_NAME_oneline(cert_subject, NULL, 0);
+ spice_debug("cert_subject: %s", p);
+ free(p);
+
+ p = X509_NAME_oneline(in_subject, NULL, 0);
+ spice_debug("in_subject: %s", p);
+ free(p);
+ }
+ X509_NAME_free(in_subject);
+
+ return !ret;
+}
+
+static int openssl_verify(int preverify_ok, X509_STORE_CTX *ctx)
+{
+ int depth, err;
+ SpiceOpenSSLVerify *v;
+ SSL *ssl;
+ X509* cert;
+ char buf[256];
+ unsigned int failed_verifications;
+
+ ssl = (SSL*)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
+ v = (SpiceOpenSSLVerify*)SSL_get_app_data(ssl);
+
+ cert = X509_STORE_CTX_get_current_cert(ctx);
+ X509_NAME_oneline(X509_get_subject_name(cert), buf, 256);
+ depth = X509_STORE_CTX_get_error_depth(ctx);
+ err = X509_STORE_CTX_get_error(ctx);
+ if (depth > 0) {
+ if (!preverify_ok) {
+ spice_warning("Error in certificate chain verification: %s (num=%d:depth%d:%s)",
+ X509_verify_cert_error_string(err), err, depth, buf);
+ v->all_preverify_ok = 0;
+
+ /* if certificate verification failed, we can still authorize the server */
+ /* if its public key matches the one we hold in the peer_connect_options. */
+ if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN &&
+ v->verifyop & SPICE_SSL_VERIFY_OP_PUBKEY)
+ return 1;
+
+ if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)
+ spice_debug("server certificate not being signed by the provided CA");
+
+ return 0;
+ } else
+ return 1;
+ }
+
+ /* depth == 0 */
+ if (!cert) {
+ spice_debug("failed to get server certificate");
+ return 0;
+ }
+
+ failed_verifications = 0;
+ if (v->verifyop & SPICE_SSL_VERIFY_OP_PUBKEY) {
+ if (verify_pubkey(cert, v->pubkey, v->pubkey_size))
+ return 1;
+ else
+ failed_verifications |= SPICE_SSL_VERIFY_OP_PUBKEY;
+ }
+
+ if (!preverify_ok) {
+ err = X509_STORE_CTX_get_error(ctx);
+ depth = X509_STORE_CTX_get_error_depth(ctx);
+ spice_warning("Error in server certificate verification: %s (num=%d:depth%d:%s)",
+ X509_verify_cert_error_string(err), err, depth, buf);
+ return 0;
+ }
+ if (!v->all_preverify_ok) {
+ return 0;
+ }
+
+ if (v->verifyop & SPICE_SSL_VERIFY_OP_SUBJECT) {
+ if (verify_subject(cert, v))
+ return 1;
+ else
+ failed_verifications |= SPICE_SSL_VERIFY_OP_SUBJECT;
+ } else if (v->verifyop & SPICE_SSL_VERIFY_OP_HOSTNAME) {
+ if (verify_hostname(cert, v->hostname))
+ return 1;
+ else
+ failed_verifications |= SPICE_SSL_VERIFY_OP_HOSTNAME;
+ }
+
+ /* If we reach this code, this means all the tests failed, thus
+ * verification failed
+ */
+ if (failed_verifications & SPICE_SSL_VERIFY_OP_PUBKEY)
+ spice_warning("ssl: pubkey verification failed");
+
+ if (failed_verifications & SPICE_SSL_VERIFY_OP_HOSTNAME)
+ spice_warning("ssl: hostname '%s' verification failed", v->hostname);
+
+ if (failed_verifications & SPICE_SSL_VERIFY_OP_SUBJECT)
+ spice_warning("ssl: subject '%s' verification failed", v->subject);
+
+ spice_warning("ssl: verification failed");
+
+ return 0;
+}
+
+SpiceOpenSSLVerify* spice_openssl_verify_new(SSL *ssl, SPICE_SSL_VERIFY_OP verifyop,
+ const char *hostname,
+ const char *pubkey, size_t pubkey_size,
+ const char *subject)
+{
+ SpiceOpenSSLVerify *v;
+
+ if (!verifyop)
+ return NULL;
+
+ v = spice_new0(SpiceOpenSSLVerify, 1);
+
+ v->ssl = ssl;
+ v->verifyop = verifyop;
+ v->hostname = spice_strdup(hostname);
+ v->pubkey = (char*)spice_memdup(pubkey, pubkey_size);
+ v->pubkey_size = pubkey_size;
+ v->subject = spice_strdup(subject);
+
+ v->all_preverify_ok = 1;
+
+ SSL_set_app_data(ssl, v);
+ SSL_set_verify(ssl,
+ SSL_VERIFY_PEER, openssl_verify);
+
+ return v;
+}
+
+void spice_openssl_verify_free(SpiceOpenSSLVerify* verify)
+{
+ if (!verify)
+ return;
+
+ free(verify->pubkey);
+ free(verify->subject);
+ free(verify->hostname);
+
+ if (verify->ssl)
+ SSL_set_app_data(verify->ssl, NULL);
+ free(verify);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SSL_VERIFY_H
+#define SSL_VERIFY_H
+
+#if defined(WIN32)
+#include <windows.h>
+#include <wincrypt.h>
+#ifdef X509_NAME
+/* wincrypt.h has already a different define... */
+#undef X509_NAME
+#endif
+#endif
+
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+
+#include <spice/macros.h>
+
+SPICE_BEGIN_DECLS
+
+typedef enum {
+ SPICE_SSL_VERIFY_OP_NONE = 0,
+ SPICE_SSL_VERIFY_OP_PUBKEY = (1 << 0),
+ SPICE_SSL_VERIFY_OP_HOSTNAME = (1 << 1),
+ SPICE_SSL_VERIFY_OP_SUBJECT = (1 << 2),
+} SPICE_SSL_VERIFY_OP;
+
+typedef struct {
+ SSL *ssl;
+ SPICE_SSL_VERIFY_OP verifyop;
+ int all_preverify_ok;
+ char *hostname;
+ char *pubkey;
+ size_t pubkey_size;
+ char *subject;
+} SpiceOpenSSLVerify;
+
+SpiceOpenSSLVerify* spice_openssl_verify_new(SSL *ssl, SPICE_SSL_VERIFY_OP verifyop,
+ const char *hostname,
+ const char *pubkey, size_t pubkey_size,
+ const char *subject);
+void spice_openssl_verify_free(SpiceOpenSSLVerify* verify);
+
+SPICE_END_DECLS
+
+#endif // SSL_VERIFY_H
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+#ifdef __MINGW32__
+#undef HAVE_STDLIB_H
+#endif
+#include <config.h>
+#endif
+
+#include <math.h>
+#include "sw_canvas.h"
+#define CANVAS_USE_PIXMAN
+#define CANVAS_SINGLE_INSTANCE
+#include "canvas_base.c"
+#include "rect.h"
+#include "region.h"
+#include "pixman_utils.h"
+
+typedef struct SwCanvas SwCanvas;
+
+struct SwCanvas {
+ CanvasBase base;
+ uint32_t *private_data;
+ int private_data_size;
+ pixman_image_t *image;
+};
+
+static pixman_image_t *canvas_get_pixman_brush(SwCanvas *canvas,
+ SpiceBrush *brush)
+{
+ switch (brush->type) {
+ case SPICE_BRUSH_TYPE_SOLID: {
+ uint32_t color = brush->u.color;
+ pixman_color_t c;
+
+ c.blue = ((color & canvas->base.color_mask) * 0xffff) / canvas->base.color_mask;
+ color >>= canvas->base.color_shift;
+ c.green = ((color & canvas->base.color_mask) * 0xffff) / canvas->base.color_mask;
+ color >>= canvas->base.color_shift;
+ c.red = ((color & canvas->base.color_mask) * 0xffff) / canvas->base.color_mask;
+ c.alpha = 0xffff;
+
+ return pixman_image_create_solid_fill(&c);
+ }
+ case SPICE_BRUSH_TYPE_PATTERN: {
+ SwCanvas *surface_canvas;
+ pixman_image_t* surface;
+ pixman_transform_t t;
+
+ surface_canvas = (SwCanvas *)canvas_get_surface(&canvas->base, brush->u.pattern.pat);
+ if (surface_canvas) {
+ surface = surface_canvas->image;
+ surface = pixman_image_ref(surface);
+ } else {
+ surface = canvas_get_image(&canvas->base, brush->u.pattern.pat, FALSE);
+ }
+ pixman_transform_init_translate(&t,
+ pixman_int_to_fixed(-brush->u.pattern.pos.x),
+ pixman_int_to_fixed(-brush->u.pattern.pos.y));
+ pixman_image_set_transform(surface, &t);
+ pixman_image_set_repeat(surface, PIXMAN_REPEAT_NORMAL);
+ return surface;
+ }
+ case SPICE_BRUSH_TYPE_NONE:
+ return NULL;
+ default:
+ spice_warn_if_reached();
+ return NULL;
+ }
+ return NULL;
+}
+
+static pixman_image_t *get_image(SpiceCanvas *canvas, int force_opaque)
+{
+ SwCanvas *sw_canvas = (SwCanvas *)canvas;
+ pixman_format_code_t format;
+
+ spice_pixman_image_get_format (sw_canvas->image, &format);
+ if (force_opaque && PIXMAN_FORMAT_A (format) != 0) {
+ uint32_t *data;
+ int stride;
+ int width, height;
+
+ /* Remove alpha bits from format */
+ format = (pixman_format_code_t)(((uint32_t)format) & ~(0xf << 12));
+ data = pixman_image_get_data (sw_canvas->image);
+ stride = pixman_image_get_stride (sw_canvas->image);
+ width = pixman_image_get_width (sw_canvas->image);
+ height = pixman_image_get_height (sw_canvas->image);
+ return pixman_image_create_bits (format, width, height, data, stride);
+ } else {
+ pixman_image_ref(sw_canvas->image);
+ }
+
+ return sw_canvas->image;
+}
+
+static void copy_region(SpiceCanvas *spice_canvas,
+ pixman_region32_t *dest_region,
+ int dx, int dy)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ pixman_box32_t *dest_rects;
+ int n_rects;
+ int i, j, end_line;
+
+ dest_rects = pixman_region32_rectangles(dest_region, &n_rects);
+
+ if (dy > 0) {
+ if (dx >= 0) {
+ /* south-east: copy x and y in reverse order */
+ for (i = n_rects - 1; i >= 0; i--) {
+ spice_pixman_copy_rect(canvas->image,
+ dest_rects[i].x1 - dx, dest_rects[i].y1 - dy,
+ dest_rects[i].x2 - dest_rects[i].x1,
+ dest_rects[i].y2 - dest_rects[i].y1,
+ dest_rects[i].x1, dest_rects[i].y1);
+ }
+ } else {
+ /* south-west: Copy y in reverse order, but x in forward order */
+ i = n_rects - 1;
+
+ while (i >= 0) {
+ /* Copy all rects with same y in forward order */
+ for (end_line = i - 1;
+ end_line >= 0 && dest_rects[end_line].y1 == dest_rects[i].y1;
+ end_line--) {
+ }
+ for (j = end_line + 1; j <= i; j++) {
+ spice_pixman_copy_rect(canvas->image,
+ dest_rects[j].x1 - dx, dest_rects[j].y1 - dy,
+ dest_rects[j].x2 - dest_rects[j].x1,
+ dest_rects[j].y2 - dest_rects[j].y1,
+ dest_rects[j].x1, dest_rects[j].y1);
+ }
+ i = end_line;
+ }
+ }
+ } else {
+ if (dx > 0) {
+ /* north-east: copy y in forward order, but x in reverse order */
+ i = 0;
+
+ while (i < n_rects) {
+ /* Copy all rects with same y in reverse order */
+ for (end_line = i;
+ end_line < n_rects && dest_rects[end_line].y1 == dest_rects[i].y1;
+ end_line++) {
+ }
+ for (j = end_line - 1; j >= i; j--) {
+ spice_pixman_copy_rect(canvas->image,
+ dest_rects[j].x1 - dx, dest_rects[j].y1 - dy,
+ dest_rects[j].x2 - dest_rects[j].x1,
+ dest_rects[j].y2 - dest_rects[j].y1,
+ dest_rects[j].x1, dest_rects[j].y1);
+ }
+ i = end_line;
+ }
+ } else {
+ /* north-west: Copy x and y in forward order */
+ for (i = 0; i < n_rects; i++) {
+ spice_pixman_copy_rect(canvas->image,
+ dest_rects[i].x1 - dx, dest_rects[i].y1 - dy,
+ dest_rects[i].x2 - dest_rects[i].x1,
+ dest_rects[i].y2 - dest_rects[i].y1,
+ dest_rects[i].x1, dest_rects[i].y1);
+ }
+ }
+ }
+}
+
+static void fill_solid_spans(SpiceCanvas *spice_canvas,
+ SpicePoint *points,
+ int *widths,
+ int n_spans,
+ uint32_t color)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ int i;
+
+ for (i = 0; i < n_spans; i++) {
+ spice_pixman_fill_rect(canvas->image,
+ points[i].x, points[i].y,
+ widths[i],
+ 1,
+ color);
+ }
+}
+
+static void fill_solid_rects(SpiceCanvas *spice_canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ uint32_t color)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ int i;
+
+ for (i = 0; i < n_rects; i++) {
+ spice_pixman_fill_rect(canvas->image,
+ rects[i].x1, rects[i].y1,
+ rects[i].x2 - rects[i].x1,
+ rects[i].y2 - rects[i].y1,
+ color);
+ }
+}
+
+static void fill_solid_rects_rop(SpiceCanvas *spice_canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ uint32_t color,
+ SpiceROP rop)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ int i;
+
+ for (i = 0; i < n_rects; i++) {
+ spice_pixman_fill_rect_rop(canvas->image,
+ rects[i].x1, rects[i].y1,
+ rects[i].x2 - rects[i].x1,
+ rects[i].y2 - rects[i].y1,
+ color, rop);
+ }
+}
+
+static void __fill_tiled_rects(SpiceCanvas *spice_canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ pixman_image_t *tile,
+ int offset_x, int offset_y)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ int i;
+
+ for (i = 0; i < n_rects; i++) {
+ spice_pixman_tile_rect(canvas->image,
+ rects[i].x1, rects[i].y1,
+ rects[i].x2 - rects[i].x1,
+ rects[i].y2 - rects[i].y1,
+ tile, offset_x, offset_y);
+ }
+}
+
+static void fill_tiled_rects(SpiceCanvas *spice_canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ pixman_image_t *tile,
+ int offset_x, int offset_y)
+{
+ __fill_tiled_rects(spice_canvas, rects, n_rects, tile, offset_x, offset_y);
+}
+
+static void fill_tiled_rects_from_surface(SpiceCanvas *spice_canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ SpiceCanvas *surface_canvas,
+ int offset_x, int offset_y)
+{
+ SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
+ __fill_tiled_rects(spice_canvas, rects, n_rects, sw_surface_canvas->image, offset_x,
+ offset_y);
+}
+
+static void __fill_tiled_rects_rop(SpiceCanvas *spice_canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ pixman_image_t *tile,
+ int offset_x, int offset_y,
+ SpiceROP rop)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ int i;
+
+ for (i = 0; i < n_rects; i++) {
+ spice_pixman_tile_rect_rop(canvas->image,
+ rects[i].x1, rects[i].y1,
+ rects[i].x2 - rects[i].x1,
+ rects[i].y2 - rects[i].y1,
+ tile, offset_x, offset_y,
+ rop);
+ }
+}
+static void fill_tiled_rects_rop(SpiceCanvas *spice_canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ pixman_image_t *tile,
+ int offset_x, int offset_y,
+ SpiceROP rop)
+{
+ __fill_tiled_rects_rop(spice_canvas, rects, n_rects, tile, offset_x, offset_y, rop);
+}
+
+static void fill_tiled_rects_rop_from_surface(SpiceCanvas *spice_canvas,
+ pixman_box32_t *rects,
+ int n_rects,
+ SpiceCanvas *surface_canvas,
+ int offset_x, int offset_y,
+ SpiceROP rop)
+{
+ SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
+ __fill_tiled_rects_rop(spice_canvas, rects, n_rects, sw_surface_canvas->image, offset_x,
+ offset_y, rop);
+}
+
+/* Some pixman implementations of OP_OVER on xRGB32 sets
+ the high bit to 0xff (which is the right value if the
+ destination was ARGB32, and it should be ignored for
+ xRGB32. However, this fills our alpha bits with
+ data that is not wanted or expected by windows, and its
+ causing us to send rgba images rather than rgb images to
+ the client. So, we manually clear these bytes. */
+static void clear_dest_alpha(pixman_image_t *dest,
+ int x, int y,
+ int width, int height)
+{
+ uint32_t *data;
+ int stride;
+ int w, h;
+
+ w = pixman_image_get_width(dest);
+ h = pixman_image_get_height(dest);
+
+ if (x + width <= 0 || x >= w ||
+ y + height <= 0 || y >= h ||
+ width == 0 || height == 0) {
+ return;
+ }
+
+ if (x < 0) {
+ width += x;
+ x = 0;
+ }
+ if (x + width > w) {
+ width = w - x;
+ }
+
+ if (y < 0) {
+ height += y;
+ y = 0;
+ }
+ if (y + height > h) {
+ height = h - y;
+ }
+
+ stride = pixman_image_get_stride(dest);
+ data = (uint32_t *) (
+ (uint8_t *)pixman_image_get_data(dest) + y * stride + 4 * x);
+
+ if ((*data & 0xff000000U) == 0xff000000U) {
+ spice_pixman_fill_rect_rop(dest,
+ x, y, width, height,
+ 0x00ffffff, SPICE_ROP_AND);
+ }
+}
+
+static void __blit_image(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src_image,
+ int offset_x, int offset_y)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ pixman_box32_t *rects;
+ int n_rects, i;
+
+ rects = pixman_region32_rectangles(region, &n_rects);
+
+ for (i = 0; i < n_rects; i++) {
+ int src_x, src_y, dest_x, dest_y, width, height;
+
+ dest_x = rects[i].x1;
+ dest_y = rects[i].y1;
+ width = rects[i].x2 - rects[i].x1;
+ height = rects[i].y2 - rects[i].y1;
+
+ src_x = rects[i].x1 - offset_x;
+ src_y = rects[i].y1 - offset_y;
+
+ spice_pixman_blit(canvas->image,
+ src_image,
+ src_x, src_y,
+ dest_x, dest_y,
+ width, height);
+ }
+}
+
+static void blit_image(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src_image,
+ int offset_x, int offset_y)
+{
+ __blit_image(spice_canvas, region, src_image, offset_x, offset_y);
+}
+
+static void blit_image_from_surface(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ SpiceCanvas *surface_canvas,
+ int offset_x, int offset_y)
+{
+ SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
+ __blit_image(spice_canvas, region, sw_surface_canvas->image, offset_x, offset_y);
+}
+
+static void __blit_image_rop(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src_image,
+ int offset_x, int offset_y,
+ SpiceROP rop)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ pixman_box32_t *rects;
+ int n_rects, i;
+
+ rects = pixman_region32_rectangles(region, &n_rects);
+
+ for (i = 0; i < n_rects; i++) {
+ int src_x, src_y, dest_x, dest_y, width, height;
+
+ dest_x = rects[i].x1;
+ dest_y = rects[i].y1;
+ width = rects[i].x2 - rects[i].x1;
+ height = rects[i].y2 - rects[i].y1;
+
+ src_x = rects[i].x1 - offset_x;
+ src_y = rects[i].y1 - offset_y;
+
+ spice_pixman_blit_rop(canvas->image,
+ src_image,
+ src_x, src_y,
+ dest_x, dest_y,
+ width, height, rop);
+ }
+}
+
+static void blit_image_rop(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src_image,
+ int offset_x, int offset_y,
+ SpiceROP rop)
+{
+ __blit_image_rop(spice_canvas, region, src_image, offset_x, offset_y, rop);
+}
+
+static void blit_image_rop_from_surface(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ SpiceCanvas *surface_canvas,
+ int offset_x, int offset_y,
+ SpiceROP rop)
+{
+ SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
+ __blit_image_rop(spice_canvas, region, sw_surface_canvas->image, offset_x, offset_y, rop);
+}
+
+
+
+static void __scale_image(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ pixman_transform_t transform;
+ pixman_fixed_t fsx, fsy;
+
+ fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
+ fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
+
+ pixman_image_set_clip_region32(canvas->image, region);
+
+ pixman_transform_init_scale(&transform, fsx, fsy);
+ pixman_transform_translate(&transform, NULL,
+ pixman_int_to_fixed (src_x),
+ pixman_int_to_fixed (src_y));
+
+ pixman_image_set_transform(src, &transform);
+ pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
+ spice_return_if_fail(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE ||
+ scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST);
+ pixman_image_set_filter(src,
+ (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?
+ PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
+ NULL, 0);
+
+ pixman_image_composite32(PIXMAN_OP_SRC,
+ src, NULL, canvas->image,
+ 0, 0, /* src */
+ 0, 0, /* mask */
+ dest_x, dest_y, /* dst */
+ dest_width, dest_height);
+
+ pixman_transform_init_identity(&transform);
+ pixman_image_set_transform(src, &transform);
+
+ pixman_image_set_clip_region32(canvas->image, NULL);
+}
+
+static void scale_image(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode)
+{
+ __scale_image(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x, dest_y,
+ dest_width,dest_height,scale_mode);
+}
+
+static void scale_image_from_surface(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ SpiceCanvas *surface_canvas,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode)
+{
+ SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
+ __scale_image(spice_canvas, region, sw_surface_canvas->image, src_x, src_y, src_width,
+ src_height, dest_x, dest_y, dest_width,dest_height,scale_mode);
+}
+
+static void __scale_image_rop(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode, SpiceROP rop)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ pixman_transform_t transform;
+ pixman_image_t *scaled;
+ pixman_box32_t *rects;
+ int n_rects, i;
+ pixman_fixed_t fsx, fsy;
+ pixman_format_code_t format;
+
+ fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
+ fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
+
+ spice_return_if_fail(spice_pixman_image_get_format(src, &format));
+ scaled = pixman_image_create_bits(format,
+ dest_width,
+ dest_height,
+ NULL, 0);
+
+ pixman_region32_translate(region, -dest_x, -dest_y);
+ pixman_image_set_clip_region32(scaled, region);
+
+ pixman_transform_init_scale(&transform, fsx, fsy);
+ pixman_transform_translate(&transform, NULL,
+ pixman_int_to_fixed (src_x),
+ pixman_int_to_fixed (src_y));
+
+ pixman_image_set_transform(src, &transform);
+ pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
+ spice_return_if_fail(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE ||
+ scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST);
+ pixman_image_set_filter(src,
+ (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?
+ PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
+ NULL, 0);
+
+ pixman_image_composite32(PIXMAN_OP_SRC,
+ src, NULL, scaled,
+ 0, 0, /* src */
+ 0, 0, /* mask */
+ 0, 0, /* dst */
+ dest_width,
+ dest_height);
+
+ pixman_transform_init_identity(&transform);
+ pixman_image_set_transform(src, &transform);
+
+ /* Translate back */
+ pixman_region32_translate(region, dest_x, dest_y);
+
+ rects = pixman_region32_rectangles(region, &n_rects);
+
+ for (i = 0; i < n_rects; i++) {
+ spice_pixman_blit_rop(canvas->image,
+ scaled,
+ rects[i].x1 - dest_x,
+ rects[i].y1 - dest_y,
+ rects[i].x1, rects[i].y1,
+ rects[i].x2 - rects[i].x1,
+ rects[i].y2 - rects[i].y1,
+ rop);
+ }
+
+ pixman_image_unref(scaled);
+}
+
+static void scale_image_rop(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode, SpiceROP rop)
+{
+ __scale_image_rop(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x,
+ dest_y, dest_width, dest_height, scale_mode, rop);
+}
+
+static void scale_image_rop_from_surface(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ SpiceCanvas *surface_canvas,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode, SpiceROP rop)
+{
+ SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
+ __scale_image_rop(spice_canvas, region, sw_surface_canvas->image, src_x, src_y, src_width,
+ src_height, dest_x, dest_y, dest_width, dest_height, scale_mode, rop);
+}
+
+static pixman_image_t *canvas_get_as_surface(SwCanvas *canvas,
+ int with_alpha)
+{
+ pixman_image_t *target;
+
+ if (with_alpha &&
+ canvas->base.format == SPICE_SURFACE_FMT_32_xRGB) {
+ target = pixman_image_create_bits(PIXMAN_a8r8g8b8,
+ pixman_image_get_width(canvas->image),
+ pixman_image_get_height(canvas->image),
+ pixman_image_get_data(canvas->image),
+ pixman_image_get_stride(canvas->image));
+ } else {
+ target = pixman_image_ref(canvas->image);
+ }
+
+ return target;
+}
+
+static void __blend_image(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ int dest_has_alpha,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height,
+ int overall_alpha)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ pixman_image_t *mask, *dest;
+
+ dest = canvas_get_as_surface(canvas, dest_has_alpha);
+
+ pixman_image_set_clip_region32(dest, region);
+
+ mask = NULL;
+ if (overall_alpha != 0xff) {
+ pixman_color_t color = { 0, 0, 0, 0 };
+ color.alpha = overall_alpha * 0x101;
+ mask = pixman_image_create_solid_fill(&color);
+ }
+
+ pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
+
+ pixman_image_composite32(PIXMAN_OP_OVER,
+ src, mask, dest,
+ src_x, src_y, /* src */
+ 0, 0, /* mask */
+ dest_x, dest_y, /* dst */
+ width,
+ height);
+
+ if (canvas->base.format == SPICE_SURFACE_FMT_32_xRGB &&
+ !dest_has_alpha) {
+ clear_dest_alpha(dest, dest_x, dest_y, width, height);
+ }
+
+ if (mask) {
+ pixman_image_unref(mask);
+ }
+
+ pixman_image_set_clip_region32(dest, NULL);
+ pixman_image_unref(dest);
+}
+
+static void blend_image(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ int dest_has_alpha,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height,
+ int overall_alpha)
+{
+ __blend_image(spice_canvas, region, dest_has_alpha, src, src_x, src_y,
+ dest_x, dest_y, width, height,
+ overall_alpha);
+}
+
+static void blend_image_from_surface(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ int dest_has_alpha,
+ SpiceCanvas *surface_canvas,
+ int src_has_alpha,
+ int src_x, int src_y,
+ int dest_x, int dest_y,
+ int width, int height,
+ int overall_alpha)
+{
+ SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
+ pixman_image_t *src;
+
+ src = canvas_get_as_surface(sw_surface_canvas, src_has_alpha);
+ __blend_image(spice_canvas, region, dest_has_alpha,
+ src, src_x, src_y,
+ dest_x, dest_y,
+ width, height, overall_alpha);
+ pixman_image_unref(src);
+}
+
+static void __blend_scale_image(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ int dest_has_alpha,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode,
+ int overall_alpha)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ pixman_transform_t transform;
+ pixman_image_t *mask, *dest;
+ pixman_fixed_t fsx, fsy;
+
+ fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
+ fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
+
+ dest = canvas_get_as_surface(canvas, dest_has_alpha);
+
+ pixman_image_set_clip_region32(dest, region);
+
+ pixman_transform_init_scale(&transform, fsx, fsy);
+ pixman_transform_translate(&transform, NULL,
+ pixman_int_to_fixed (src_x),
+ pixman_int_to_fixed (src_y));
+
+ mask = NULL;
+ if (overall_alpha != 0xff) {
+ pixman_color_t color = { 0, 0, 0, 0 };
+ color.alpha = overall_alpha * 0x101;
+ mask = pixman_image_create_solid_fill(&color);
+ }
+
+ pixman_image_set_transform(src, &transform);
+ pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
+ spice_return_if_fail(scale_mode == SPICE_IMAGE_SCALE_MODE_INTERPOLATE ||
+ scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST);
+ pixman_image_set_filter(src,
+ (scale_mode == SPICE_IMAGE_SCALE_MODE_NEAREST) ?
+ PIXMAN_FILTER_NEAREST : PIXMAN_FILTER_GOOD,
+ NULL, 0);
+
+ pixman_image_composite32(PIXMAN_OP_OVER,
+ src, mask, dest,
+ 0, 0, /* src */
+ 0, 0, /* mask */
+ dest_x, dest_y, /* dst */
+ dest_width, dest_height);
+
+ if (canvas->base.format == SPICE_SURFACE_FMT_32_xRGB &&
+ !dest_has_alpha) {
+ clear_dest_alpha(dest, dest_x, dest_y, dest_width, dest_height);
+ }
+
+ pixman_transform_init_identity(&transform);
+ pixman_image_set_transform(src, &transform);
+
+ if (mask) {
+ pixman_image_unref(mask);
+ }
+
+ pixman_image_set_clip_region32(dest, NULL);
+ pixman_image_unref(dest);
+}
+
+static void blend_scale_image(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ int dest_has_alpha,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode,
+ int overall_alpha)
+{
+ __blend_scale_image(spice_canvas, region, dest_has_alpha,
+ src, src_x, src_y, src_width, src_height,
+ dest_x, dest_y, dest_width, dest_height,
+ scale_mode, overall_alpha);
+}
+
+static void blend_scale_image_from_surface(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ int dest_has_alpha,
+ SpiceCanvas *surface_canvas,
+ int src_has_alpha,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ int scale_mode,
+ int overall_alpha)
+{
+ SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
+ pixman_image_t *src;
+
+ src = canvas_get_as_surface(sw_surface_canvas, src_has_alpha);
+ __blend_scale_image(spice_canvas, region, dest_has_alpha, src, src_x, src_y, src_width,
+ src_height, dest_x, dest_y, dest_width, dest_height, scale_mode,
+ overall_alpha);
+ pixman_image_unref(src);
+}
+
+static void __colorkey_image(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src_image,
+ int offset_x, int offset_y,
+ uint32_t transparent_color)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ pixman_box32_t *rects;
+ int n_rects, i;
+
+ rects = pixman_region32_rectangles(region, &n_rects);
+
+ for (i = 0; i < n_rects; i++) {
+ int src_x, src_y, dest_x, dest_y, width, height;
+
+ dest_x = rects[i].x1;
+ dest_y = rects[i].y1;
+ width = rects[i].x2 - rects[i].x1;
+ height = rects[i].y2 - rects[i].y1;
+
+ src_x = rects[i].x1 - offset_x;
+ src_y = rects[i].y1 - offset_y;
+
+ spice_pixman_blit_colorkey(canvas->image,
+ src_image,
+ src_x, src_y,
+ dest_x, dest_y,
+ width, height,
+ transparent_color);
+ }
+}
+
+static void colorkey_image(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src_image,
+ int offset_x, int offset_y,
+ uint32_t transparent_color)
+{
+ __colorkey_image(spice_canvas, region, src_image, offset_x, offset_y, transparent_color);
+}
+
+static void colorkey_image_from_surface(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ SpiceCanvas *surface_canvas,
+ int offset_x, int offset_y,
+ uint32_t transparent_color)
+{
+ SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
+ __colorkey_image(spice_canvas, region, sw_surface_canvas->image, offset_x, offset_y,
+ transparent_color);
+}
+
+static void __colorkey_scale_image(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ uint32_t transparent_color)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ pixman_transform_t transform;
+ pixman_image_t *scaled;
+ pixman_box32_t *rects;
+ int n_rects, i;
+ pixman_fixed_t fsx, fsy;
+ pixman_format_code_t format;
+
+ fsx = ((pixman_fixed_48_16_t) src_width * 65536) / dest_width;
+ fsy = ((pixman_fixed_48_16_t) src_height * 65536) / dest_height;
+
+ spice_return_if_fail(spice_pixman_image_get_format(src, &format));
+ scaled = pixman_image_create_bits(format,
+ dest_width,
+ dest_height,
+ NULL, 0);
+
+ pixman_region32_translate(region, -dest_x, -dest_y);
+ pixman_image_set_clip_region32(scaled, region);
+
+ pixman_transform_init_scale(&transform, fsx, fsy);
+ pixman_transform_translate(&transform, NULL,
+ pixman_int_to_fixed (src_x),
+ pixman_int_to_fixed (src_y));
+
+ pixman_image_set_transform(src, &transform);
+ pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
+ pixman_image_set_filter(src,
+ PIXMAN_FILTER_NEAREST,
+ NULL, 0);
+
+ pixman_image_composite32(PIXMAN_OP_SRC,
+ src, NULL, scaled,
+ 0, 0, /* src */
+ 0, 0, /* mask */
+ 0, 0, /* dst */
+ dest_width,
+ dest_height);
+
+ pixman_transform_init_identity(&transform);
+ pixman_image_set_transform(src, &transform);
+
+ /* Translate back */
+ pixman_region32_translate(region, dest_x, dest_y);
+
+ rects = pixman_region32_rectangles(region, &n_rects);
+
+ for (i = 0; i < n_rects; i++) {
+ spice_pixman_blit_colorkey(canvas->image,
+ scaled,
+ rects[i].x1 - dest_x,
+ rects[i].y1 - dest_y,
+ rects[i].x1, rects[i].y1,
+ rects[i].x2 - rects[i].x1,
+ rects[i].y2 - rects[i].y1,
+ transparent_color);
+ }
+
+ pixman_image_unref(scaled);
+}
+
+static void colorkey_scale_image(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ pixman_image_t *src,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ uint32_t transparent_color)
+{
+ __colorkey_scale_image(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x,
+ dest_y, dest_width, dest_height, transparent_color);
+}
+
+static void colorkey_scale_image_from_surface(SpiceCanvas *spice_canvas,
+ pixman_region32_t *region,
+ SpiceCanvas *surface_canvas,
+ int src_x, int src_y,
+ int src_width, int src_height,
+ int dest_x, int dest_y,
+ int dest_width, int dest_height,
+ uint32_t transparent_color)
+{
+ SwCanvas *sw_surface_canvas = (SwCanvas *)surface_canvas;
+ __colorkey_scale_image(spice_canvas, region, sw_surface_canvas->image, src_x, src_y,
+ src_width, src_height, dest_x, dest_y, dest_width, dest_height,
+ transparent_color);
+}
+
+static void canvas_put_image(SpiceCanvas *spice_canvas,
+#ifdef WIN32
+ HDC dc,
+#endif
+ const SpiceRect *dest, const uint8_t *src_data,
+ uint32_t src_width, uint32_t src_height, int src_stride,
+ const QRegion *clip)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ pixman_image_t *src;
+ uint32_t dest_width;
+ uint32_t dest_height;
+ double sx, sy;
+ pixman_transform_t transform;
+
+ src = pixman_image_create_bits(PIXMAN_x8r8g8b8,
+ src_width,
+ src_height,
+ (uint32_t*)src_data,
+ src_stride);
+
+
+ if (clip) {
+ pixman_image_set_clip_region32 (canvas->image, (pixman_region32_t *)clip);
+ }
+
+ dest_width = dest->right - dest->left;
+ dest_height = dest->bottom - dest->top;
+
+ if (dest_width != src_width || dest_height != src_height) {
+ sx = (double)(src_width) / (dest_width);
+ sy = (double)(src_height) / (dest_height);
+
+ pixman_transform_init_scale(&transform,
+ pixman_double_to_fixed(sx),
+ pixman_double_to_fixed(sy));
+ pixman_image_set_transform(src, &transform);
+ pixman_image_set_filter(src,
+ PIXMAN_FILTER_NEAREST,
+ NULL, 0);
+ }
+
+ pixman_image_set_repeat(src, PIXMAN_REPEAT_NONE);
+
+ pixman_image_composite32(PIXMAN_OP_SRC,
+ src, NULL, canvas->image,
+ 0, 0, /* src */
+ 0, 0, /* mask */
+ dest->left, dest->top, /* dst */
+ dest_width, dest_height);
+
+
+ if (clip) {
+ pixman_image_set_clip_region32(canvas->image, NULL);
+ }
+ pixman_image_unref(src);
+}
+
+
+static void canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox,
+ SpiceClip *clip, SpiceText *text)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ pixman_region32_t dest_region;
+ pixman_image_t *str_mask, *brush;
+ SpiceString *str;
+ SpicePoint pos = { 0, 0 };
+ int depth;
+
+ pixman_region32_init_rect(&dest_region,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+
+ canvas_clip_pixman(&canvas->base, &dest_region, clip);
+
+ if (!pixman_region32_not_empty(&dest_region)) {
+ touch_brush(&canvas->base, &text->fore_brush);
+ touch_brush(&canvas->base, &text->back_brush);
+ pixman_region32_fini(&dest_region);
+ return;
+ }
+
+ if (!rect_is_empty(&text->back_area)) {
+ pixman_region32_t back_region;
+
+ /* Nothing else makes sense for text and we should deprecate it
+ * and actually it means OVER really */
+ spice_return_if_fail(text->fore_mode == SPICE_ROPD_OP_PUT);
+
+ pixman_region32_init_rect(&back_region,
+ text->back_area.left,
+ text->back_area.top,
+ text->back_area.right - text->back_area.left,
+ text->back_area.bottom - text->back_area.top);
+
+ pixman_region32_intersect(&back_region, &back_region, &dest_region);
+
+ if (pixman_region32_not_empty(&back_region)) {
+ draw_brush(spice_canvas, &back_region, &text->back_brush, SPICE_ROP_COPY);
+ }
+
+ pixman_region32_fini(&back_region);
+ }
+ str = (SpiceString *)SPICE_GET_ADDRESS(text->str);
+
+ if (str->flags & SPICE_STRING_FLAGS_RASTER_A1) {
+ depth = 1;
+ } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A4) {
+ depth = 4;
+ } else if (str->flags & SPICE_STRING_FLAGS_RASTER_A8) {
+ spice_warning("untested path A8 glyphs");
+ depth = 8;
+ } else {
+ spice_warning("unsupported path vector glyphs");
+ pixman_region32_fini (&dest_region);
+ return;
+ }
+
+ brush = canvas_get_pixman_brush(canvas, &text->fore_brush);
+
+ str_mask = canvas_get_str_mask(&canvas->base, str, depth, &pos);
+ if (brush) {
+ pixman_image_set_clip_region32(canvas->image, &dest_region);
+
+ pixman_image_composite32(PIXMAN_OP_OVER,
+ brush,
+ str_mask,
+ canvas->image,
+ 0, 0,
+ 0, 0,
+ pos.x, pos.y,
+ pixman_image_get_width(str_mask),
+ pixman_image_get_height(str_mask));
+ if (canvas->base.format == SPICE_SURFACE_FMT_32_xRGB) {
+ clear_dest_alpha(canvas->image, pos.x, pos.y,
+ pixman_image_get_width(str_mask),
+ pixman_image_get_height(str_mask));
+ }
+ pixman_image_unref(brush);
+
+ pixman_image_set_clip_region32(canvas->image, NULL);
+ }
+ pixman_image_unref(str_mask);
+ pixman_region32_fini(&dest_region);
+}
+
+static void canvas_read_bits(SpiceCanvas *spice_canvas, uint8_t *dest,
+ int dest_stride, const SpiceRect *area)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ pixman_image_t* surface;
+ uint8_t *src;
+ int src_stride;
+ uint8_t *dest_end;
+ int bpp;
+
+ spice_return_if_fail(canvas && area);
+
+ surface = canvas->image;
+
+ bpp = spice_pixman_image_get_bpp(surface) / 8;
+
+ src_stride = pixman_image_get_stride(surface);
+ src = (uint8_t *)pixman_image_get_data(surface) +
+ area->top * src_stride + area->left * bpp;
+ dest_end = dest + (area->bottom - area->top) * dest_stride;
+ for (; dest != dest_end; dest += dest_stride, src += src_stride) {
+ memcpy(dest, src, (area->right - area->left) * bpp);
+ }
+}
+
+static void canvas_clear(SpiceCanvas *spice_canvas)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ spice_pixman_fill_rect(canvas->image,
+ 0, 0,
+ pixman_image_get_width(canvas->image),
+ pixman_image_get_height(canvas->image),
+ 0);
+}
+
+static void canvas_destroy(SpiceCanvas *spice_canvas)
+{
+ SwCanvas *canvas = (SwCanvas *)spice_canvas;
+ if (!canvas) {
+ return;
+ }
+ pixman_image_unref(canvas->image);
+ canvas_base_destroy(&canvas->base);
+ free(canvas->private_data);
+ free(canvas);
+}
+
+static SpiceCanvasOps sw_canvas_ops;
+
+static SpiceCanvas *canvas_create_common(pixman_image_t *image,
+ uint32_t format
+ , SpiceImageCache *bits_cache
+#ifdef SW_CANVAS_CACHE
+ , SpicePaletteCache *palette_cache
+#endif
+ , SpiceImageSurfaces *surfaces
+ , SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
+ , SpiceZlibDecoder *zlib_decoder
+ )
+{
+ SwCanvas *canvas;
+
+ spice_pixman_image_set_format(image,
+ spice_surface_format_to_pixman (format));
+
+ canvas = spice_new0(SwCanvas, 1);
+ canvas_base_init(&canvas->base, &sw_canvas_ops,
+ pixman_image_get_width (image),
+ pixman_image_get_height (image),
+ format
+ , bits_cache
+#ifdef SW_CANVAS_CACHE
+ , palette_cache
+#endif
+ , surfaces
+ , glz_decoder
+ , jpeg_decoder
+ , zlib_decoder
+ );
+ canvas->private_data = NULL;
+ canvas->private_data_size = 0;
+
+ canvas->image = image;
+
+ return (SpiceCanvas *)canvas;
+}
+
+SpiceCanvas *canvas_create(int width, int height, uint32_t format
+ , SpiceImageCache *bits_cache
+#ifdef SW_CANVAS_CACHE
+ , SpicePaletteCache *palette_cache
+#endif
+ , SpiceImageSurfaces *surfaces
+ , SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
+ , SpiceZlibDecoder *zlib_decoder
+ )
+{
+ pixman_image_t *image;
+
+ image = pixman_image_create_bits(spice_surface_format_to_pixman (format),
+ width, height, NULL, 0);
+
+ return canvas_create_common(image, format
+ , bits_cache
+#ifdef SW_CANVAS_CACHE
+ , palette_cache
+#endif
+ , surfaces
+ , glz_decoder
+ , jpeg_decoder
+ , zlib_decoder
+ );
+}
+
+SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format,
+ uint8_t *data, int stride
+ , SpiceImageCache *bits_cache
+#ifdef SW_CANVAS_CACHE
+ , SpicePaletteCache *palette_cache
+#endif
+ , SpiceImageSurfaces *surfaces
+ , SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
+ , SpiceZlibDecoder *zlib_decoder
+ )
+{
+ pixman_image_t *image;
+
+ image = pixman_image_create_bits(spice_surface_format_to_pixman (format),
+ width, height, (uint32_t *)data, stride);
+
+ return canvas_create_common(image, format
+ , bits_cache
+#ifdef SW_CANVAS_CACHE
+ , palette_cache
+#endif
+ , surfaces
+ , glz_decoder
+ , jpeg_decoder
+ , zlib_decoder
+ );
+}
+
+SPICE_CONSTRUCTOR_FUNC(sw_canvas_global_init) //unsafe global function
+{
+ canvas_base_init_ops(&sw_canvas_ops);
+ sw_canvas_ops.draw_text = canvas_draw_text;
+ sw_canvas_ops.put_image = canvas_put_image;
+ sw_canvas_ops.clear = canvas_clear;
+ sw_canvas_ops.read_bits = canvas_read_bits;
+ sw_canvas_ops.destroy = canvas_destroy;
+
+ sw_canvas_ops.fill_solid_spans = fill_solid_spans;
+ sw_canvas_ops.fill_solid_rects = fill_solid_rects;
+ sw_canvas_ops.fill_solid_rects_rop = fill_solid_rects_rop;
+ sw_canvas_ops.fill_tiled_rects = fill_tiled_rects;
+ sw_canvas_ops.fill_tiled_rects_from_surface = fill_tiled_rects_from_surface;
+ sw_canvas_ops.fill_tiled_rects_rop = fill_tiled_rects_rop;
+ sw_canvas_ops.fill_tiled_rects_rop_from_surface = fill_tiled_rects_rop_from_surface;
+ sw_canvas_ops.blit_image = blit_image;
+ sw_canvas_ops.blit_image_from_surface = blit_image_from_surface;
+ sw_canvas_ops.blit_image_rop = blit_image_rop;
+ sw_canvas_ops.blit_image_rop_from_surface = blit_image_rop_from_surface;
+ sw_canvas_ops.scale_image = scale_image;
+ sw_canvas_ops.scale_image_from_surface = scale_image_from_surface;
+ sw_canvas_ops.scale_image_rop = scale_image_rop;
+ sw_canvas_ops.scale_image_rop_from_surface = scale_image_rop_from_surface;
+ sw_canvas_ops.blend_image = blend_image;
+ sw_canvas_ops.blend_image_from_surface = blend_image_from_surface;
+ sw_canvas_ops.blend_scale_image = blend_scale_image;
+ sw_canvas_ops.blend_scale_image_from_surface = blend_scale_image_from_surface;
+ sw_canvas_ops.colorkey_image = colorkey_image;
+ sw_canvas_ops.colorkey_image_from_surface = colorkey_image_from_surface;
+ sw_canvas_ops.colorkey_scale_image = colorkey_scale_image;
+ sw_canvas_ops.colorkey_scale_image_from_surface = colorkey_scale_image_from_surface;
+ sw_canvas_ops.copy_region = copy_region;
+ sw_canvas_ops.get_image = get_image;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H__CANVAS
+#define _H__CANVAS
+
+#include <stdint.h>
+#include <spice/macros.h>
+
+#include "draw.h"
+#include "pixman_utils.h"
+#include "canvas_base.h"
+#include "region.h"
+
+SPICE_BEGIN_DECLS
+
+SpiceCanvas *canvas_create(int width, int height, uint32_t format
+ , SpiceImageCache *bits_cache
+#ifdef SW_CANVAS_CACHE
+ , SpicePaletteCache *palette_cache
+#endif
+ , SpiceImageSurfaces *surfaces
+ , SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
+ , SpiceZlibDecoder *zlib_decoder
+ );
+
+SpiceCanvas *canvas_create_for_data(int width, int height, uint32_t format, uint8_t *data, int stride
+ , SpiceImageCache *bits_cache
+#ifdef SW_CANVAS_CACHE
+ , SpicePaletteCache *palette_cache
+#endif
+ , SpiceImageSurfaces *surfaces
+ , SpiceGlzDecoder *glz_decoder
+ , SpiceJpegDecoder *jpeg_decoder
+ , SpiceZlibDecoder *zlib_decoder
+ );
+
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/* Compile-time assert-like macros.
+
+ Copyright (C) 2005-2006, 2009-2016 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */
+
+#ifndef _GL_VERIFY_H
+#define _GL_VERIFY_H
+
+
+/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11.
+ This is supported by GCC 4.6.0 and later, in C mode, and its use
+ here generates easier-to-read diagnostics when verify (R) fails.
+
+ Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per C++11.
+ This will likely be supported by future GCC versions, in C++ mode.
+
+ Use this only with GCC. If we were willing to slow 'configure'
+ down we could also use it with other compilers, but since this
+ affects only the quality of diagnostics, why bother? */
+#if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \
+ && (201112L <= __STDC_VERSION__ || !defined __STRICT_ANSI__) \
+ && !defined __cplusplus)
+# define _GL_HAVE__STATIC_ASSERT 1
+#endif
+/* The condition (99 < __GNUC__) is temporary, until we know about the
+ first G++ release that supports static_assert. */
+#if (99 < __GNUC__) && defined __cplusplus
+# define _GL_HAVE_STATIC_ASSERT 1
+#endif
+
+/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other
+ system headers, defines a conflicting _Static_assert that is no
+ better than ours; override it. */
+#ifndef _GL_HAVE_STATIC_ASSERT
+# include <stddef.h>
+# undef _Static_assert
+#endif
+
+/* Each of these macros verifies that its argument R is nonzero. To
+ be portable, R should be an integer constant expression. Unlike
+ assert (R), there is no run-time overhead.
+
+ If _Static_assert works, verify (R) uses it directly. Similarly,
+ _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct
+ that is an operand of sizeof.
+
+ The code below uses several ideas for C++ compilers, and for C
+ compilers that do not support _Static_assert:
+
+ * The first step is ((R) ? 1 : -1). Given an expression R, of
+ integral or boolean or floating-point type, this yields an
+ expression of integral type, whose value is later verified to be
+ constant and nonnegative.
+
+ * Next this expression W is wrapped in a type
+ struct _gl_verify_type {
+ unsigned int _gl_verify_error_if_negative: W;
+ }.
+ If W is negative, this yields a compile-time error. No compiler can
+ deal with a bit-field of negative size.
+
+ One might think that an array size check would have the same
+ effect, that is, that the type struct { unsigned int dummy[W]; }
+ would work as well. However, inside a function, some compilers
+ (such as C++ compilers and GNU C) allow local parameters and
+ variables inside array size expressions. With these compilers,
+ an array size check would not properly diagnose this misuse of
+ the verify macro:
+
+ void function (int n) { verify (n < 0); }
+
+ * For the verify macro, the struct _gl_verify_type will need to
+ somehow be embedded into a declaration. To be portable, this
+ declaration must declare an object, a constant, a function, or a
+ typedef name. If the declared entity uses the type directly,
+ such as in
+
+ struct dummy {...};
+ typedef struct {...} dummy;
+ extern struct {...} *dummy;
+ extern void dummy (struct {...} *);
+ extern struct {...} *dummy (void);
+
+ two uses of the verify macro would yield colliding declarations
+ if the entity names are not disambiguated. A workaround is to
+ attach the current line number to the entity name:
+
+ #define _GL_CONCAT0(x, y) x##y
+ #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
+ extern struct {...} * _GL_CONCAT (dummy, __LINE__);
+
+ But this has the problem that two invocations of verify from
+ within the same macro would collide, since the __LINE__ value
+ would be the same for both invocations. (The GCC __COUNTER__
+ macro solves this problem, but is not portable.)
+
+ A solution is to use the sizeof operator. It yields a number,
+ getting rid of the identity of the type. Declarations like
+
+ extern int dummy [sizeof (struct {...})];
+ extern void dummy (int [sizeof (struct {...})]);
+ extern int (*dummy (void)) [sizeof (struct {...})];
+
+ can be repeated.
+
+ * Should the implementation use a named struct or an unnamed struct?
+ Which of the following alternatives can be used?
+
+ extern int dummy [sizeof (struct {...})];
+ extern int dummy [sizeof (struct _gl_verify_type {...})];
+ extern void dummy (int [sizeof (struct {...})]);
+ extern void dummy (int [sizeof (struct _gl_verify_type {...})]);
+ extern int (*dummy (void)) [sizeof (struct {...})];
+ extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})];
+
+ In the second and sixth case, the struct type is exported to the
+ outer scope; two such declarations therefore collide. GCC warns
+ about the first, third, and fourth cases. So the only remaining
+ possibility is the fifth case:
+
+ extern int (*dummy (void)) [sizeof (struct {...})];
+
+ * GCC warns about duplicate declarations of the dummy function if
+ -Wredundant-decls is used. GCC 4.3 and later have a builtin
+ __COUNTER__ macro that can let us generate unique identifiers for
+ each dummy function, to suppress this warning.
+
+ * This implementation exploits the fact that older versions of GCC,
+ which do not support _Static_assert, also do not warn about the
+ last declaration mentioned above.
+
+ * GCC warns if -Wnested-externs is enabled and verify() is used
+ within a function body; but inside a function, you can always
+ arrange to use verify_expr() instead.
+
+ * In C++, any struct definition inside sizeof is invalid.
+ Use a template type to work around the problem. */
+
+/* Concatenate two preprocessor tokens. */
+#define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
+#define _GL_CONCAT0(x, y) x##y
+
+/* _GL_COUNTER is an integer, preferably one that changes each time we
+ use it. Use __COUNTER__ if it works, falling back on __LINE__
+ otherwise. __LINE__ isn't perfect, but it's better than a
+ constant. */
+#if defined __COUNTER__ && __COUNTER__ != __COUNTER__
+# define _GL_COUNTER __COUNTER__
+#else
+# define _GL_COUNTER __LINE__
+#endif
+
+/* Generate a symbol with the given prefix, making it unique if
+ possible. */
+#define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
+
+/* Verify requirement R at compile-time, as an integer constant expression
+ that returns 1. If R is false, fail at compile-time, preferably
+ with a diagnostic that includes the string-literal DIAGNOSTIC. */
+
+#define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \
+ (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC)))
+
+#ifdef __cplusplus
+# if !GNULIB_defined_struct__gl_verify_type
+template <int w>
+ struct _gl_verify_type {
+ unsigned int _gl_verify_error_if_negative: w;
+ };
+# define GNULIB_defined_struct__gl_verify_type 1
+# endif
+# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
+ _gl_verify_type<(R) ? 1 : -1>
+#elif defined _GL_HAVE__STATIC_ASSERT
+# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
+ struct { \
+ _Static_assert (R, DIAGNOSTIC); \
+ int _gl_dummy; \
+ }
+#else
+# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
+ struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; }
+#endif
+
+/* Verify requirement R at compile-time, as a declaration without a
+ trailing ';'. If R is false, fail at compile-time, preferably
+ with a diagnostic that includes the string-literal DIAGNOSTIC.
+
+ Unfortunately, unlike C11, this implementation must appear as an
+ ordinary declaration, and cannot appear inside struct { ... }. */
+
+#ifdef _GL_HAVE__STATIC_ASSERT
+# define _GL_VERIFY _Static_assert
+#else
+# define _GL_VERIFY(R, DIAGNOSTIC) \
+ extern int (*_GL_GENSYM (_gl_verify_function) (void)) \
+ [_GL_VERIFY_TRUE (R, DIAGNOSTIC)]
+#endif
+
+/* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */
+#ifdef _GL_STATIC_ASSERT_H
+# if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert
+# define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC)
+# endif
+# if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert
+# define static_assert _Static_assert /* C11 requires this #define. */
+# endif
+#endif
+
+/* @assert.h omit start@ */
+
+/* Each of these macros verifies that its argument R is nonzero. To
+ be portable, R should be an integer constant expression. Unlike
+ assert (R), there is no run-time overhead.
+
+ There are two macros, since no single macro can be used in all
+ contexts in C. verify_true (R) is for scalar contexts, including
+ integer constant expression contexts. verify (R) is for declaration
+ contexts, e.g., the top level. */
+
+/* Verify requirement R at compile-time, as an integer constant expression.
+ Return 1. This is equivalent to verify_expr (R, 1).
+
+ verify_true is obsolescent; please use verify_expr instead. */
+
+#define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")")
+
+/* Verify requirement R at compile-time. Return the value of the
+ expression E. */
+
+#define verify_expr(R, E) \
+ (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E))
+
+/* Verify requirement R at compile-time, as a declaration without a
+ trailing ';'. */
+
+#define verify(R) _GL_VERIFY (R, "verify (" #R ")")
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+/* Assume that R always holds. This lets the compiler optimize
+ accordingly. R should not have side-effects; it may or may not be
+ evaluated. Behavior is undefined if R is false. */
+
+#if (__has_builtin (__builtin_unreachable) \
+ || 4 < __GNUC__ + (5 <= __GNUC_MINOR__))
+# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
+#elif 1200 <= _MSC_VER
+# define assume(R) __assume (R)
+#elif (defined lint \
+ && (__has_builtin (__builtin_trap) \
+ || 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))))
+ /* Doing it this way helps various packages when configured with
+ --enable-gcc-warnings, which compiles with -Dlint. It's nicer
+ when 'assume' silences warnings even with older GCCs. */
+# define assume(R) ((R) ? (void) 0 : __builtin_trap ())
+#else
+# define assume(R) ((void) (0 && (R)))
+#endif
+
+/* @assert.h omit end@ */
+
+#endif
--- /dev/null
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define if we have celt051 codec */
+#undef HAVE_CELT051
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Define to 1 if you have the `floor' function. */
+#undef HAVE_FLOOR
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the `inet_ntoa' function. */
+#undef HAVE_INET_NTOA
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define if we have OPUS */
+#undef HAVE_OPUS
+
+/* Define to 1 if you have the `pow' function. */
+#undef HAVE_POW
+
+/* Define to 1 if you have the `sqrt' function. */
+#undef HAVE_SQRT
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
+
+/* Define to 1 if you have the <vfork.h> header file. */
+#undef HAVE_VFORK_H
+
+/* Define to 1 if `fork' works. */
+#undef HAVE_WORKING_FORK
+
+/* Define to 1 if `vfork' works. */
+#undef HAVE_WORKING_VFORK
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if supporting smartcard proxying */
+#undef USE_SMARTCARD
+
+/* Define if supporting smartcard proxying without libcacard.h */
+#undef USE_SMARTCARD_012
+
+/* Version number of package */
+#undef VERSION
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT32_T
+
+/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT64_T
+
+/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT8_T
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to the type of a signed integer type of width exactly 16 bits if
+ such a type exists and the standard includes do not define it. */
+#undef int16_t
+
+/* Define to the type of a signed integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+#undef int32_t
+
+/* Define to the type of a signed integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+#undef int64_t
+
+/* Define to the type of a signed integer type of width exactly 8 bits if such
+ a type exists and the standard includes do not define it. */
+#undef int8_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to the type of an unsigned integer type of width exactly 16 bits if
+ such a type exists and the standard includes do not define it. */
+#undef uint16_t
+
+/* Define to the type of an unsigned integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+#undef uint32_t
+
+/* Define to the type of an unsigned integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+#undef uint64_t
+
+/* Define to the type of an unsigned integer type of width exactly 8 bits if
+ such a type exists and the standard includes do not define it. */
+#undef uint8_t
+
+/* Define as `fork' if `vfork' does not work. */
+#undef vfork
+
+
+/* argh.. this is evil */
+#if defined(FIXME_SERVER_SMARTCARD) && defined(USE_SMARTCARD)
+%:undef USE_SMARTCARD
+#endif
+
--- /dev/null
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for spice-common noversion.
+#
+# Report bugs to <spice-devel@lists.freedesktop.org>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: spice-devel@lists.freedesktop.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='spice-common'
+PACKAGE_TARNAME='spice-common'
+PACKAGE_VERSION='noversion'
+PACKAGE_STRING='spice-common noversion'
+PACKAGE_BUGREPORT='spice-devel@lists.freedesktop.org'
+PACKAGE_URL=''
+
+ac_unique_file="common/bitops.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+SPICE_COMMON_LIBS
+SPICE_COMMON_CFLAGS
+OPENSSL_LIBS
+OPENSSL_CFLAGS
+HAVE_OPUS_FALSE
+HAVE_OPUS_TRUE
+OPUS_LIBS
+OPUS_CFLAGS
+GLIB2_LIBS
+GLIB2_CFLAGS
+HAVE_CELT051_FALSE
+HAVE_CELT051_TRUE
+CELT051_LIBS
+CELT051_CFLAGS
+HAVE_SMARTCARD_FALSE
+HAVE_SMARTCARD_TRUE
+SMARTCARD_LIBS
+SMARTCARD_CFLAGS
+PIXMAN_LIBS
+PIXMAN_CFLAGS
+pkgpyexecdir
+pyexecdir
+pkgpythondir
+pythondir
+PYTHON_PLATFORM
+PYTHON_EXEC_PREFIX
+PYTHON_PREFIX
+PYTHON_VERSION
+PYTHON
+PROTOCOL_LIBS
+PROTOCOL_CFLAGS
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
+LIBOBJS
+ALLOCA
+CPP
+LT_SYS_LIBRARY_PATH
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+ac_ct_AR
+AR
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_dependency_tracking
+enable_silent_rules
+enable_maintainer_mode
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_aix_soname
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+enable_python_checks
+enable_smartcard
+enable_celt051
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+LT_SYS_LIBRARY_PATH
+CPP
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR
+PROTOCOL_CFLAGS
+PROTOCOL_LIBS
+PYTHON
+PIXMAN_CFLAGS
+PIXMAN_LIBS
+SMARTCARD_CFLAGS
+SMARTCARD_LIBS
+CELT051_CFLAGS
+CELT051_LIBS
+GLIB2_CFLAGS
+GLIB2_LIBS
+OPUS_CFLAGS
+OPUS_LIBS
+OPENSSL_CFLAGS
+OPENSSL_LIBS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures spice-common noversion to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/spice-common]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of spice-common noversion:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-dependency-tracking
+ do not reject slow dependency extractors
+ --disable-dependency-tracking
+ speeds up one-time build
+ --enable-silent-rules less verbose build output (undo: "make V=1")
+ --disable-silent-rules verbose build output (undo: "make V=0")
+ --enable-maintainer-mode
+ enable make rules and dependencies not useful (and
+ sometimes confusing) to the casual installer
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --enable-python-checks=[yes/no]
+ Enable checks for Python modules needed to build
+ from git [default=no]
+ --enable-smartcard=[yes/no/auto]
+ Enable smartcard support [default=auto]
+ --disable-celt051 Disable celt051 audio codec (enabled by default)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-aix-soname=aix|svr4|both
+ shared library versioning (aka "SONAME") variant to
+ provide on AIX, [default=aix].
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the
+ compiler's sysroot if not specified).
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ LT_SYS_LIBRARY_PATH
+ User-defined run-time library search path.
+ CPP C preprocessor
+ PKG_CONFIG path to pkg-config utility
+ PKG_CONFIG_PATH
+ directories to add to pkg-config's search path
+ PKG_CONFIG_LIBDIR
+ path overriding pkg-config's built-in search path
+ PROTOCOL_CFLAGS
+ C compiler flags for PROTOCOL, overriding pkg-config
+ PROTOCOL_LIBS
+ linker flags for PROTOCOL, overriding pkg-config
+ PYTHON the Python interpreter
+ PIXMAN_CFLAGS
+ C compiler flags for PIXMAN, overriding pkg-config
+ PIXMAN_LIBS linker flags for PIXMAN, overriding pkg-config
+ SMARTCARD_CFLAGS
+ C compiler flags for SMARTCARD, overriding pkg-config
+ SMARTCARD_LIBS
+ linker flags for SMARTCARD, overriding pkg-config
+ CELT051_CFLAGS
+ C compiler flags for CELT051, overriding pkg-config
+ CELT051_LIBS
+ linker flags for CELT051, overriding pkg-config
+ GLIB2_CFLAGS
+ C compiler flags for GLIB2, overriding pkg-config
+ GLIB2_LIBS linker flags for GLIB2, overriding pkg-config
+ OPUS_CFLAGS C compiler flags for OPUS, overriding pkg-config
+ OPUS_LIBS linker flags for OPUS, overriding pkg-config
+ OPENSSL_CFLAGS
+ C compiler flags for OPENSSL, overriding pkg-config
+ OPENSSL_LIBS
+ linker flags for OPENSSL, overriding pkg-config
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <spice-devel@lists.freedesktop.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+spice-common configure noversion
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------------------------ ##
+## Report this to spice-devel@lists.freedesktop.org ##
+## ------------------------------------------------ ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_find_intX_t LINENO BITS VAR
+# -----------------------------------
+# Finds a signed integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_intX_t ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
+$as_echo_n "checking for int$2_t... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ # Order is important - never check a type that is potentially smaller
+ # than half of the expected target width.
+ for ac_type in int$2_t 'int' 'long int' \
+ 'long long int' 'short int' 'signed char'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+ enum { N = $2 / 2 - 1 };
+int
+main ()
+{
+static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+ enum { N = $2 / 2 - 1 };
+int
+main ()
+{
+static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
+ < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ case $ac_type in #(
+ int$2_t) :
+ eval "$3=yes" ;; #(
+ *) :
+ eval "$3=\$ac_type" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if eval test \"x\$"$3"\" = x"no"; then :
+
+else
+ break
+fi
+ done
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_find_intX_t
+
+# ac_fn_c_find_uintX_t LINENO BITS VAR
+# ------------------------------------
+# Finds an unsigned integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_uintX_t ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
+$as_echo_n "checking for uint$2_t... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ # Order is important - never check a type that is potentially smaller
+ # than half of the expected target width.
+ for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \
+ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ case $ac_type in #(
+ uint$2_t) :
+ eval "$3=yes" ;; #(
+ *) :
+ eval "$3=\$ac_type" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if eval test \"x\$"$3"\" = x"no"; then :
+
+else
+ break
+fi
+ done
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_find_uintX_t
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by spice-common $as_me noversion, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0=$ac_configure_args0" '$ac_arg'" ;;
+ 2)
+ ac_configure_args1=$ac_configure_args1" '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args=$ac_configure_args" '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args=$ac_configure_args" '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+ac_aux_dir=
+for ac_dir in build-aux "$srcdir"/build-aux; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+# For automake >= 1.12
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar lib "link -lib"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar lib "link -lib"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ am_cv_ar_interface=ar
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+ (eval $am_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=ar
+ else
+ am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+ (eval $am_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test "$ac_status" -eq 0; then
+ am_cv_ar_interface=lib
+ else
+ am_cv_ar_interface=unknown
+ fi
+ fi
+ rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+ ;;
+lib)
+ # Microsoft lib, so override with the ar-lib wrapper script.
+ # FIXME: It is wrong to rewrite AR.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__AR in this case,
+ # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+ # similar.
+ AR="$am_aux_dir/ar-lib $AR"
+ ;;
+unknown)
+ as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+ ;;
+esac
+
+
+# Checks for programs
+am__api_version='1.15'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ am_has_slept=no
+ for am_try in 1 2; do
+ echo "timestamp, slept: $am_has_slept" > conftest.file
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error $? "ls -t appears to fail. Make sure there is not a broken
+ alias in your environment" "$LINENO" 5
+ fi
+ if test "$2" = conftest.file || test $am_try -eq 2; then
+ break
+ fi
+ # Just in case.
+ sleep 1
+ am_has_slept=yes
+ done
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+ ( sleep 1 ) &
+ am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+ am_missing_run="$MISSING "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip". However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if ${ac_cv_path_mkdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ test -d ./--version && rmdir ./--version
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='spice-common'
+ VERSION='noversion'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility. To be removed once Automake 1.9.x
+# dies out for good. For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target (and possibly the TAP driver). The
+# system "awk" is bad on some platforms.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar plaintar pax cpio none'
+
+# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+ # There is notably a 21 bits limit for the UID and the GID. In fact,
+ # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+ # and bug#13588).
+ am_max_uid=2097151 # 2^21 - 1
+ am_max_gid=$am_max_uid
+ # The $UID and $GID variables are not portable, so we need to resort
+ # to the POSIX-mandated id(1) utility. Errors in the 'id' calls
+ # below are definitely unexpected, so allow the users to see them
+ # (that is, avoid stderr redirection).
+ am_uid=`id -u || echo unknown`
+ am_gid=`id -g || echo unknown`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether UID '$am_uid' is supported by ustar format" >&5
+$as_echo_n "checking whether UID '$am_uid' is supported by ustar format... " >&6; }
+ if test $am_uid -le $am_max_uid; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ _am_tools=none
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GID '$am_gid' is supported by ustar format" >&5
+$as_echo_n "checking whether GID '$am_gid' is supported by ustar format... " >&6; }
+ if test $am_gid -le $am_max_gid; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ _am_tools=none
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a ustar tar archive" >&5
+$as_echo_n "checking how to create a ustar tar archive... " >&6; }
+
+ # Go ahead even if we have the value already cached. We do so because we
+ # need to set the values for the 'am__tar' and 'am__untar' variables.
+ _am_tools=${am_cv_prog_tar_ustar-$_am_tools}
+
+ for _am_tool in $_am_tools; do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar; do
+ { echo "$as_me:$LINENO: $_am_tar --version" >&5
+ ($_am_tar --version) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && break
+ done
+ am__tar="$_am_tar --format=ustar -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=ustar -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x ustar -w "$$tardir"'
+ am__tar_='pax -L -x ustar -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H ustar -L'
+ am__tar_='find "$tardir" -print | cpio -o -H ustar -L'
+ am__untar='cpio -i -H ustar -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_ustar}" && break
+
+ # tar/untar a dummy directory, and stop if the command works.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5
+ (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ { echo "$as_me:$LINENO: $am__untar <conftest.tar" >&5
+ ($am__untar <conftest.tar) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+ { echo "$as_me:$LINENO: cat conftest.dir/file" >&5
+ (cat conftest.dir/file) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+ done
+ rm -rf conftest.dir
+
+ if ${am_cv_prog_tar_ustar+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ am_cv_prog_tar_ustar=$_am_tool
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_ustar" >&5
+$as_echo "$am_cv_prog_tar_ustar" >&6; }
+
+
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named 'D' -- because '-MD' means "put the output
+ # in D".
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+ # Solaris 10 /bin/sh.
+ echo '/* dummy */' > sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with '-c' and '-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle '-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs.
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # After this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested.
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok '-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes. So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+ cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present. This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message. This
+can help us improve future automake versions.
+
+END
+ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+ echo 'Configuration will proceed anyway, since you have set the' >&2
+ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+ echo >&2
+ else
+ cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+ fi
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+ enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+ yes) AM_DEFAULT_VERBOSITY=0;;
+ no) AM_DEFAULT_VERBOSITY=1;;
+ *) AM_DEFAULT_VERBOSITY=0;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+ @$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+ am_cv_make_support_nested_variables=yes
+else
+ am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+ AM_V='$(V)'
+ AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+ AM_V=$AM_DEFAULT_VERBOSITY
+ AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.6'
+macro_revision='2.4.6'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case $ECHO in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi
+fi
+
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+os2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in ar
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+ done
+fi
+if test -z "$AR"; then
+ ac_ct_AR=$AR
+ for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_AR" && break
+done
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ar_at_file=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+ (eval $lt_ar_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+ withval=$with_sysroot;
+else
+ with_sysroot=no
+fi
+
+
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5
+$as_echo "$with_sysroot" >&6; }
+ as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+ ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5
+$as_echo_n "checking for a working dd... " >&6; }
+if ${ac_cv_path_lt_DD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+if test -z "$lt_DD"; then
+ ac_path_lt_DD_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in dd; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_lt_DD" || continue
+if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi
+ $ac_path_lt_DD_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_lt_DD"; then
+ :
+ fi
+else
+ ac_cv_path_lt_DD=$lt_DD
+fi
+
+rm -f conftest.i conftest2.i conftest.out
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5
+$as_echo "$ac_cv_path_lt_DD" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5
+$as_echo_n "checking how to truncate binary pipes... " >&6; }
+if ${lt_cv_truncate_bin+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5
+$as_echo "$lt_cv_truncate_bin" >&6; }
+
+
+
+
+
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$MANIFEST_TOOL"; then
+ ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+ ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+ # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_MANIFEST_TOOL"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_MANIFEST_TOOL" = x; then
+ MANIFEST_TOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+ fi
+else
+ MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&5
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&5
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ echo "$RANLIB libconftest.a" >&5
+ $RANLIB libconftest.a 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&5
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[012][,.]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+# Set options
+
+
+
+ enable_dlopen=no
+
+
+ enable_win32_dll=no
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ pic_mode=default
+fi
+
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+ shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[5-9]*,yes)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5
+$as_echo_n "checking which variant of shared library versioning to provide... " >&6; }
+
+# Check whether --with-aix-soname was given.
+if test "${with_aix_soname+set}" = set; then :
+ withval=$with_aix_soname; case $withval in
+ aix|svr4|both)
+ ;;
+ *)
+ as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5
+ ;;
+ esac
+ lt_cv_with_aix_soname=$with_aix_soname
+else
+ if ${lt_cv_with_aix_soname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_with_aix_soname=aix
+fi
+
+ with_aix_soname=$lt_cv_with_aix_soname
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5
+$as_echo "$with_aix_soname" >&6; }
+ if test aix != "$with_aix_soname"; then
+ # For the AIX way of multilib, we name the shared archive member
+ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+ # the AIX toolchain works better with OBJECT_MODE set (default 32).
+ if test 64 = "${OBJECT_MODE-32}"; then
+ shared_archive_member_spec=shr_64
+ else
+ shared_archive_member_spec=shr
+ fi
+ fi
+ ;;
+*)
+ with_aix_soname=aix
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+func_cc_basename $compiler
+cc_basename=$func_cc_basename_result
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/${ac_tool_prefix}file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/file"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac
+fi
+
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC=$CC
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+ if test yes = "$GCC"; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static='$wl-static'
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ if test -n "$lt_prog_compiler_pic"; then
+ lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ case $host_os in
+ os2*)
+ lt_prog_compiler_static='$wl-static'
+ ;;
+ esac
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ lt_prog_compiler_wl='-Wl,-Wl,,'
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Intel*\ [CF]*Compiler*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ *Portland\ Group*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_pic_works"; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test yes = "$lt_cv_prog_compiler_static_works"; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links=nottested
+if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test no = "$hard_links"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ export_dynamic_flag_spec='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='$wl--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ shrext_cmds=.dll
+ archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ tcc*)
+ export_dynamic_flag_spec='-rdynamic'
+ ;;
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test no = "$ld_shlibs"; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # traditional, no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ ;;
+ esac
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ export_dynamic_flag_spec='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ if ${lt_cv_aix_libpath_+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }'
+ lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "$lt_cv_aix_libpath_"; then
+ lt_cv_aix_libpath_=/usr/lib:/lib
+ fi
+
+fi
+
+ aix_libpath=$lt_cv_aix_libpath_
+fi
+
+ hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' $wl-bernotok'
+ allow_undefined_flag=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ file_list_spec='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+ enable_shared_with_static_runtimes=yes
+ exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ old_postinstall_cmds='chmod 644 $oldlib'
+ postlink_cmds='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ enable_shared_with_static_runtimes=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test yes = "$lt_cv_prog_compiler__b"; then
+ archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ hardcode_libdir_flag_spec='$wl+b $wl$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='$wl-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_irix_exported_symbol=yes
+else
+ lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ linux*)
+ case $cc_basename in
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ ld_shlibs=yes
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ export_dynamic_flag_spec='$wl-E'
+ else
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='$wl-rpath,$libdir'
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ shrext_cmds=.dll
+ archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ allow_undefined_flag=' $wl-expect_unresolved $wl\*'
+ archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='$wl-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='$wl-z,text'
+ allow_undefined_flag='$wl-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='$wl-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test no = "$ld_shlibs" && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a(lib.so.V)'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Add ABI-specific directories to the system library path.
+ sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test yes = "$hardcode_automatic"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$hardcode_direct" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" &&
+ test no != "$hardcode_minus_L"; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test relink = "$hardcode_action" ||
+ test yes = "$inherit_rpath"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+ lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+ lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+ lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test yes = "$cross_compiling"; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report what library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC=$lt_save_CC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ # Make sure it works both with $CC and with simple cc.
+ # Following AC_PROG_CC_C_O, we do the test twice because some
+ # compilers refuse to overwrite an existing .o file with -o,
+ # though they will create one.
+ am_cv_prog_cc_c_o=yes
+ for am_i in 1 2; do
+ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } \
+ && test -f conftest2.$ac_objext; then
+ : OK
+ else
+ am_cv_prog_cc_c_o=no
+ break
+ fi
+ done
+ rm -f core conftest*
+ unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
+$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
+if ${ac_cv_prog_cc_c99+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros. These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+ int x = 1234;
+ int y = 5678;
+ debug ("Flag");
+ debug ("X = %d\n", x);
+ showlist (The first, second, and third items.);
+ report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+ your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+ your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+ int datasize;
+ double data[];
+};
+
+struct named_init {
+ int number;
+ const wchar_t *name;
+ double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+ // See if C++-style comments work.
+ // Iterate through items via the restricted pointer.
+ // Also check for declarations in for loops.
+ for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+ continue;
+ return 0;
+}
+
+// Check varargs and va_copy.
+static void
+test_varargs (const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ va_list args_copy;
+ va_copy (args_copy, args);
+
+ const char *str;
+ int number;
+ float fnumber;
+
+ while (*format)
+ {
+ switch (*format++)
+ {
+ case 's': // string
+ str = va_arg (args_copy, const char *);
+ break;
+ case 'd': // int
+ number = va_arg (args_copy, int);
+ break;
+ case 'f': // float
+ fnumber = va_arg (args_copy, double);
+ break;
+ default:
+ break;
+ }
+ }
+ va_end (args_copy);
+ va_end (args);
+}
+
+int
+main ()
+{
+
+ // Check bool.
+ _Bool success = false;
+
+ // Check restrict.
+ if (test_restrict ("String literal") == 0)
+ success = true;
+ char *restrict newvar = "Another string";
+
+ // Check varargs.
+ test_varargs ("s, d' f .", "string", 65, 34.234);
+ test_varargs_macros ();
+
+ // Check flexible array members.
+ struct incomplete_array *ia =
+ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+ ia->datasize = 10;
+ for (int i = 0; i < ia->datasize; ++i)
+ ia->data[i] = i * 1.234;
+
+ // Check named initializers.
+ struct named_init ni = {
+ .number = 34,
+ .name = L"Test wide string",
+ .average = 543.34343,
+ };
+
+ ni.number = 58;
+
+ int dynamic_array[ni.number];
+ dynamic_array[ni.number - 1] = 543;
+
+ // work around unused variable warnings
+ return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+ || dynamic_array[ni.number - 1] != 543);
+
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c99" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c99"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c99" != xno; then :
+
+fi
+
+
+if test "x$ac_cv_prog_cc_c99" = xno; then
+ as_fn_error $? "C99 compiler is required." "$LINENO" 5
+fi
+
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+ # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
+$as_echo_n "checking for working alloca.h... " >&6; }
+if ${ac_cv_working_alloca_h+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+ if (p) return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_working_alloca_h=yes
+else
+ ac_cv_working_alloca_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5
+$as_echo "$ac_cv_working_alloca_h" >&6; }
+if test $ac_cv_working_alloca_h = yes; then
+
+$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
+$as_echo_n "checking for alloca... " >&6; }
+if ${ac_cv_func_alloca_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+void *alloca (size_t);
+# endif
+# endif
+# endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+ if (p) return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_func_alloca_works=yes
+else
+ ac_cv_func_alloca_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5
+$as_echo "$ac_cv_func_alloca_works" >&6; }
+
+if test $ac_cv_func_alloca_works = yes; then
+
+$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
+
+else
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble. Some versions do not even contain alloca or
+# contain a buggy version. If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
+
+$as_echo "#define C_ALLOCA 1" >>confdefs.h
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5
+$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; }
+if ${ac_cv_os_cray+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#if defined CRAY && ! defined CRAY2
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "webecray" >/dev/null 2>&1; then :
+ ac_cv_os_cray=yes
+else
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5
+$as_echo "$ac_cv_os_cray" >&6; }
+if test $ac_cv_os_cray = yes; then
+ for ac_func in _getb67 GETB67 getb67; do
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+ break
+fi
+
+ done
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
+$as_echo_n "checking stack direction for C alloca... " >&6; }
+if ${ac_cv_c_stack_direction+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_c_stack_direction=0
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+find_stack_direction (int *addr, int depth)
+{
+ int dir, dummy = 0;
+ if (! addr)
+ addr = &dummy;
+ *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
+ dir = depth ? find_stack_direction (addr, depth - 1) : 0;
+ return dir + dummy;
+}
+
+int
+main (int argc, char **argv)
+{
+ return find_stack_direction (0, argc + !argv + 20) < 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_stack_direction=1
+else
+ ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5
+$as_echo "$ac_cv_c_stack_direction" >&6; }
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+ for ac_header in arpa/inet.h malloc.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/socket.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ # Checks for typedefs, structures, and compiler characteristics
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+ ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t"
+case $ac_cv_c_int16_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int16_t $ac_cv_c_int16_t
+_ACEOF
+;;
+esac
+
+ ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t"
+case $ac_cv_c_int32_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int32_t $ac_cv_c_int32_t
+_ACEOF
+;;
+esac
+
+ ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t"
+case $ac_cv_c_int64_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int64_t $ac_cv_c_int64_t
+_ACEOF
+;;
+esac
+
+ ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t"
+case $ac_cv_c_int8_t in #(
+ no|yes) ;; #(
+ *)
+
+cat >>confdefs.h <<_ACEOF
+#define int8_t $ac_cv_c_int8_t
+_ACEOF
+;;
+esac
+
+ ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+ ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+ ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t"
+case $ac_cv_c_uint16_t in #(
+ no|yes) ;; #(
+ *)
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint16_t $ac_cv_c_uint16_t
+_ACEOF
+;;
+ esac
+
+ ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t"
+case $ac_cv_c_uint32_t in #(
+ no|yes) ;; #(
+ *)
+
+$as_echo "#define _UINT32_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint32_t $ac_cv_c_uint32_t
+_ACEOF
+;;
+ esac
+
+ ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t"
+case $ac_cv_c_uint64_t in #(
+ no|yes) ;; #(
+ *)
+
+$as_echo "#define _UINT64_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint64_t $ac_cv_c_uint64_t
+_ACEOF
+;;
+ esac
+
+ ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t"
+case $ac_cv_c_uint8_t in #(
+ no|yes) ;; #(
+ *)
+
+$as_echo "#define _UINT8_T 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define uint8_t $ac_cv_c_uint8_t
+_ACEOF
+;;
+ esac
+
+
+ # Checks for library functions
+ # do not check malloc or realloc, since that cannot be cross-compiled checked
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5
+$as_echo_n "checking for error_at_line... " >&6; }
+if ${ac_cv_lib_error_at_line+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <error.h>
+int
+main ()
+{
+error_at_line (0, 0, "", 0, "an error occurred");
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_error_at_line=yes
+else
+ ac_cv_lib_error_at_line=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_error_at_line" >&5
+$as_echo "$ac_cv_lib_error_at_line" >&6; }
+if test $ac_cv_lib_error_at_line = no; then
+ case " $LIBOBJS " in
+ *" error.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS error.$ac_objext"
+ ;;
+esac
+
+fi
+
+ for ac_header in vfork.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
+if test "x$ac_cv_header_vfork_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_VFORK_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in fork vfork
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+if test "x$ac_cv_func_fork" = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
+$as_echo_n "checking for working fork... " >&6; }
+if ${ac_cv_func_fork_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_fork_works=cross
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* By Ruediger Kuhlmann. */
+ return fork () < 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_fork_works=yes
+else
+ ac_cv_func_fork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
+$as_echo "$ac_cv_func_fork_works" >&6; }
+
+else
+ ac_cv_func_fork_works=$ac_cv_func_fork
+fi
+if test "x$ac_cv_func_fork_works" = xcross; then
+ case $host in
+ *-*-amigaos* | *-*-msdosdjgpp*)
+ # Override, as these systems have only a dummy fork() stub
+ ac_cv_func_fork_works=no
+ ;;
+ *)
+ ac_cv_func_fork_works=yes
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
+fi
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+if test "x$ac_cv_func_vfork" = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
+$as_echo_n "checking for working vfork... " >&6; }
+if ${ac_cv_func_vfork_works+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ ac_cv_func_vfork_works=cross
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Thanks to Paul Eggert for this test. */
+$ac_includes_default
+#include <sys/wait.h>
+#ifdef HAVE_VFORK_H
+# include <vfork.h>
+#endif
+/* On some sparc systems, changes by the child to local and incoming
+ argument registers are propagated back to the parent. The compiler
+ is told about this with #include <vfork.h>, but some compilers
+ (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a
+ static variable whose address is put into a register that is
+ clobbered by the vfork. */
+static void
+#ifdef __cplusplus
+sparc_address_test (int arg)
+# else
+sparc_address_test (arg) int arg;
+#endif
+{
+ static pid_t child;
+ if (!child) {
+ child = vfork ();
+ if (child < 0) {
+ perror ("vfork");
+ _exit(2);
+ }
+ if (!child) {
+ arg = getpid();
+ write(-1, "", 0);
+ _exit (arg);
+ }
+ }
+}
+
+int
+main ()
+{
+ pid_t parent = getpid ();
+ pid_t child;
+
+ sparc_address_test (0);
+
+ child = vfork ();
+
+ if (child == 0) {
+ /* Here is another test for sparc vfork register problems. This
+ test uses lots of local variables, at least as many local
+ variables as main has allocated so far including compiler
+ temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris
+ 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should
+ reuse the register of parent for one of the local variables,
+ since it will think that parent can't possibly be used any more
+ in this routine. Assigning to the local variable will thus
+ munge parent in the parent process. */
+ pid_t
+ p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+ p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+ /* Convince the compiler that p..p7 are live; otherwise, it might
+ use the same hardware register for all 8 local variables. */
+ if (p != p1 || p != p2 || p != p3 || p != p4
+ || p != p5 || p != p6 || p != p7)
+ _exit(1);
+
+ /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
+ from child file descriptors. If the child closes a descriptor
+ before it execs or exits, this munges the parent's descriptor
+ as well. Test for this by closing stdout in the child. */
+ _exit(close(fileno(stdout)) != 0);
+ } else {
+ int status;
+ struct stat st;
+
+ while (wait(&status) != child)
+ ;
+ return (
+ /* Was there some problem with vforking? */
+ child < 0
+
+ /* Did the child fail? (This shouldn't happen.) */
+ || status
+
+ /* Did the vfork/compiler bug occur? */
+ || parent != getpid()
+
+ /* Did the file descriptor bug occur? */
+ || fstat(fileno(stdout), &st) != 0
+ );
+ }
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_func_vfork_works=yes
+else
+ ac_cv_func_vfork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
+$as_echo "$ac_cv_func_vfork_works" >&6; }
+
+fi;
+if test "x$ac_cv_func_fork_works" = xcross; then
+ ac_cv_func_vfork_works=$ac_cv_func_vfork
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
+fi
+
+if test "x$ac_cv_func_vfork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h
+
+else
+
+$as_echo "#define vfork fork" >>confdefs.h
+
+fi
+if test "x$ac_cv_func_fork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
+
+fi
+
+ for ac_func in dup2 floor inet_ntoa memmove memset pow sqrt
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+# Checks for libraries
+
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+ ac_pt_PKG_CONFIG=$PKG_CONFIG
+ # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_PKG_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_PKG_CONFIG" = x; then
+ PKG_CONFIG=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ PKG_CONFIG=$ac_pt_PKG_CONFIG
+ fi
+else
+ PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+ _pkg_min_version=0.9.0
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ PKG_CONFIG=""
+ fi
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PROTOCOL" >&5
+$as_echo_n "checking for PROTOCOL... " >&6; }
+
+if test -n "$PROTOCOL_CFLAGS"; then
+ pkg_cv_PROTOCOL_CFLAGS="$PROTOCOL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"spice-protocol >= 0.12.12\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "spice-protocol >= 0.12.12") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PROTOCOL_CFLAGS=`$PKG_CONFIG --cflags "spice-protocol >= 0.12.12" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$PROTOCOL_LIBS"; then
+ pkg_cv_PROTOCOL_LIBS="$PROTOCOL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"spice-protocol >= 0.12.12\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "spice-protocol >= 0.12.12") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PROTOCOL_LIBS=`$PKG_CONFIG --libs "spice-protocol >= 0.12.12" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ PROTOCOL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "spice-protocol >= 0.12.12" 2>&1`
+ else
+ PROTOCOL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "spice-protocol >= 0.12.12" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$PROTOCOL_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (spice-protocol >= 0.12.12) were not met:
+
+$PROTOCOL_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables PROTOCOL_CFLAGS
+and PROTOCOL_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables PROTOCOL_CFLAGS
+and PROTOCOL_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ PROTOCOL_CFLAGS=$pkg_cv_PROTOCOL_CFLAGS
+ PROTOCOL_LIBS=$pkg_cv_PROTOCOL_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+
+
+
+
+
+
+ # Find any Python interpreter.
+ if test -z "$PYTHON"; then
+ for ac_prog in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PYTHON+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PYTHON in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+PYTHON=$ac_cv_path_PYTHON
+if test -n "$PYTHON"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+$as_echo "$PYTHON" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$PYTHON" && break
+done
+test -n "$PYTHON" || PYTHON=":"
+
+ fi
+ am_display_PYTHON=python
+
+
+ if test "$PYTHON" = :; then
+ as_fn_error $? "no suitable Python interpreter found" "$LINENO" 5
+ else
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5
+$as_echo_n "checking for $am_display_PYTHON version... " >&6; }
+if ${am_cv_python_version+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"`
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5
+$as_echo "$am_cv_python_version" >&6; }
+ PYTHON_VERSION=$am_cv_python_version
+
+
+
+ PYTHON_PREFIX='${prefix}'
+
+ PYTHON_EXEC_PREFIX='${exec_prefix}'
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5
+$as_echo_n "checking for $am_display_PYTHON platform... " >&6; }
+if ${am_cv_python_platform+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5
+$as_echo "$am_cv_python_platform" >&6; }
+ PYTHON_PLATFORM=$am_cv_python_platform
+
+
+ # Just factor out some code duplication.
+ am_python_setup_sysconfig="\
+import sys
+# Prefer sysconfig over distutils.sysconfig, for better compatibility
+# with python 3.x. See automake bug#10227.
+try:
+ import sysconfig
+except ImportError:
+ can_use_sysconfig = 0
+else:
+ can_use_sysconfig = 1
+# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs:
+# <https://github.com/pypa/virtualenv/issues/118>
+try:
+ from platform import python_implementation
+ if python_implementation() == 'CPython' and sys.version[:3] == '2.7':
+ can_use_sysconfig = 0
+except ImportError:
+ pass"
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5
+$as_echo_n "checking for $am_display_PYTHON script directory... " >&6; }
+if ${am_cv_python_pythondir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$prefix" = xNONE
+ then
+ am_py_prefix=$ac_default_prefix
+ else
+ am_py_prefix=$prefix
+ fi
+ am_cv_python_pythondir=`$PYTHON -c "
+$am_python_setup_sysconfig
+if can_use_sysconfig:
+ sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
+else:
+ from distutils import sysconfig
+ sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
+sys.stdout.write(sitedir)"`
+ case $am_cv_python_pythondir in
+ $am_py_prefix*)
+ am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
+ am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"`
+ ;;
+ *)
+ case $am_py_prefix in
+ /usr|/System*) ;;
+ *)
+ am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages
+ ;;
+ esac
+ ;;
+ esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5
+$as_echo "$am_cv_python_pythondir" >&6; }
+ pythondir=$am_cv_python_pythondir
+
+
+
+ pkgpythondir=\${pythondir}/$PACKAGE
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory" >&5
+$as_echo_n "checking for $am_display_PYTHON extension module directory... " >&6; }
+if ${am_cv_python_pyexecdir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$exec_prefix" = xNONE
+ then
+ am_py_exec_prefix=$am_py_prefix
+ else
+ am_py_exec_prefix=$exec_prefix
+ fi
+ am_cv_python_pyexecdir=`$PYTHON -c "
+$am_python_setup_sysconfig
+if can_use_sysconfig:
+ sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
+else:
+ from distutils import sysconfig
+ sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
+sys.stdout.write(sitedir)"`
+ case $am_cv_python_pyexecdir in
+ $am_py_exec_prefix*)
+ am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
+ am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"`
+ ;;
+ *)
+ case $am_py_exec_prefix in
+ /usr|/System*) ;;
+ *)
+ am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages
+ ;;
+ esac
+ ;;
+ esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5
+$as_echo "$am_cv_python_pyexecdir" >&6; }
+ pyexecdir=$am_cv_python_pyexecdir
+
+
+
+ pkgpyexecdir=\${pyexecdir}/$PACKAGE
+
+
+
+ fi
+
+
+ # Check whether --enable-python-checks was given.
+if test "${enable_python_checks+set}" = set; then :
+ enableval=$enable_python_checks;
+else
+ enable_python_checks="no"
+fi
+
+ if test "x$enable_python_checks" != "xno"; then
+
+ if test -z $PYTHON;
+ then
+ PYTHON="python"
+ fi
+ PYTHON_NAME=`basename $PYTHON`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking $PYTHON_NAME module: six" >&5
+$as_echo_n "checking $PYTHON_NAME module: six... " >&6; }
+ $PYTHON -c "import six" 2>/dev/null
+ if test $? -eq 0;
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ eval HAVE_PYMOD_SIX=yes
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ eval HAVE_PYMOD_SIX=no
+ #
+ if test -n "1"
+ then
+ as_fn_error $? "failed to find required module six" "$LINENO" 5
+ exit 1
+ fi
+ fi
+
+
+ if test -z $PYTHON;
+ then
+ PYTHON="python"
+ fi
+ PYTHON_NAME=`basename $PYTHON`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking $PYTHON_NAME module: pyparsing" >&5
+$as_echo_n "checking $PYTHON_NAME module: pyparsing... " >&6; }
+ $PYTHON -c "import pyparsing" 2>/dev/null
+ if test $? -eq 0;
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ eval HAVE_PYMOD_PYPARSING=yes
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ eval HAVE_PYMOD_PYPARSING=no
+ #
+ if test -n "1"
+ then
+ as_fn_error $? "failed to find required module pyparsing" "$LINENO" 5
+ exit 1
+ fi
+ fi
+
+ fi
+
+
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PIXMAN" >&5
+$as_echo_n "checking for PIXMAN... " >&6; }
+
+if test -n "$PIXMAN_CFLAGS"; then
+ pkg_cv_PIXMAN_CFLAGS="$PIXMAN_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"pixman-1 >= 0.17.7\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "pixman-1 >= 0.17.7") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PIXMAN_CFLAGS=`$PKG_CONFIG --cflags "pixman-1 >= 0.17.7" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$PIXMAN_LIBS"; then
+ pkg_cv_PIXMAN_LIBS="$PIXMAN_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"pixman-1 >= 0.17.7\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "pixman-1 >= 0.17.7") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PIXMAN_LIBS=`$PKG_CONFIG --libs "pixman-1 >= 0.17.7" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ PIXMAN_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "pixman-1 >= 0.17.7" 2>&1`
+ else
+ PIXMAN_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "pixman-1 >= 0.17.7" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$PIXMAN_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (pixman-1 >= 0.17.7) were not met:
+
+$PIXMAN_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables PIXMAN_CFLAGS
+and PIXMAN_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables PIXMAN_CFLAGS
+and PIXMAN_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ PIXMAN_CFLAGS=$pkg_cv_PIXMAN_CFLAGS
+ PIXMAN_LIBS=$pkg_cv_PIXMAN_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+ # Check whether --enable-smartcard was given.
+if test "${enable_smartcard+set}" = set; then :
+ enableval=$enable_smartcard;
+else
+ enable_smartcard="auto"
+fi
+
+
+ have_smartcard=no
+ if test "x$enable_smartcard" != "xno"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SMARTCARD" >&5
+$as_echo_n "checking for SMARTCARD... " >&6; }
+
+if test -n "$SMARTCARD_CFLAGS"; then
+ pkg_cv_SMARTCARD_CFLAGS="$SMARTCARD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcacard >= 2.5.1\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libcacard >= 2.5.1") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SMARTCARD_CFLAGS=`$PKG_CONFIG --cflags "libcacard >= 2.5.1" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$SMARTCARD_LIBS"; then
+ pkg_cv_SMARTCARD_LIBS="$SMARTCARD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcacard >= 2.5.1\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libcacard >= 2.5.1") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SMARTCARD_LIBS=`$PKG_CONFIG --libs "libcacard >= 2.5.1" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ SMARTCARD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcacard >= 2.5.1" 2>&1`
+ else
+ SMARTCARD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcacard >= 2.5.1" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$SMARTCARD_PKG_ERRORS" >&5
+
+ have_smartcard=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_smartcard=no
+else
+ SMARTCARD_CFLAGS=$pkg_cv_SMARTCARD_CFLAGS
+ SMARTCARD_LIBS=$pkg_cv_SMARTCARD_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_smartcard=yes
+fi
+ if test "x$have_smartcard" = "xno"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SMARTCARD" >&5
+$as_echo_n "checking for SMARTCARD... " >&6; }
+
+if test -n "$SMARTCARD_CFLAGS"; then
+ pkg_cv_SMARTCARD_CFLAGS="$SMARTCARD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcacard >= 0.1.2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libcacard >= 0.1.2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SMARTCARD_CFLAGS=`$PKG_CONFIG --cflags "libcacard >= 0.1.2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$SMARTCARD_LIBS"; then
+ pkg_cv_SMARTCARD_LIBS="$SMARTCARD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcacard >= 0.1.2\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libcacard >= 0.1.2") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_SMARTCARD_LIBS=`$PKG_CONFIG --libs "libcacard >= 0.1.2" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ SMARTCARD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcacard >= 0.1.2" 2>&1`
+ else
+ SMARTCARD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcacard >= 0.1.2" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$SMARTCARD_PKG_ERRORS" >&5
+
+ have_smartcard=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_smartcard=no
+else
+ SMARTCARD_CFLAGS=$pkg_cv_SMARTCARD_CFLAGS
+ SMARTCARD_LIBS=$pkg_cv_SMARTCARD_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_smartcard=yes have_smartcard_012=yes
+fi
+ fi
+ if test "x$enable_smartcard" != "xauto" && test "x$have_smartcard" = "xno"; then
+ as_fn_error $? "\"Smartcard support requested but libcacard could not be found\"" "$LINENO" 5
+ fi
+ if test "x$have_smartcard_012" = "xyes"; then
+
+$as_echo "#define USE_SMARTCARD_012 1" >>confdefs.h
+
+ fi
+ if test "x$have_smartcard" = "xyes"; then
+
+$as_echo "#define USE_SMARTCARD 1" >>confdefs.h
+
+ fi
+ fi
+ if test "x$have_smartcard" = "xyes"; then
+ HAVE_SMARTCARD_TRUE=
+ HAVE_SMARTCARD_FALSE='#'
+else
+ HAVE_SMARTCARD_TRUE='#'
+ HAVE_SMARTCARD_FALSE=
+fi
+
+
+
+ # Check whether --enable-celt051 was given.
+if test "${enable_celt051+set}" = set; then :
+ enableval=$enable_celt051;
+else
+ enable_celt051="yes"
+fi
+
+
+ if test "x$enable_celt051" = "xyes"; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CELT051" >&5
+$as_echo_n "checking for CELT051... " >&6; }
+
+if test -n "$CELT051_CFLAGS"; then
+ pkg_cv_CELT051_CFLAGS="$CELT051_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"celt051 >= 0.5.1.1\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "celt051 >= 0.5.1.1") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_CELT051_CFLAGS=`$PKG_CONFIG --cflags "celt051 >= 0.5.1.1" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$CELT051_LIBS"; then
+ pkg_cv_CELT051_LIBS="$CELT051_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"celt051 >= 0.5.1.1\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "celt051 >= 0.5.1.1") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_CELT051_LIBS=`$PKG_CONFIG --libs "celt051 >= 0.5.1.1" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ CELT051_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "celt051 >= 0.5.1.1" 2>&1`
+ else
+ CELT051_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "celt051 >= 0.5.1.1" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$CELT051_PKG_ERRORS" >&5
+
+ have_celt051=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_celt051=no
+else
+ CELT051_CFLAGS=$pkg_cv_CELT051_CFLAGS
+ CELT051_LIBS=$pkg_cv_CELT051_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_celt051=yes
+fi
+ else
+ have_celt051=no
+ fi
+
+ if test "x$have_celt051" = "xyes"; then
+ HAVE_CELT051_TRUE=
+ HAVE_CELT051_FALSE='#'
+else
+ HAVE_CELT051_TRUE='#'
+ HAVE_CELT051_FALSE=
+fi
+
+ if test -z "$HAVE_CELT051_TRUE"; then :
+
+$as_echo "#define HAVE_CELT051 1" >>confdefs.h
+
+fi
+
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLIB2" >&5
+$as_echo_n "checking for GLIB2... " >&6; }
+
+if test -n "$GLIB2_CFLAGS"; then
+ pkg_cv_GLIB2_CFLAGS="$GLIB2_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.22 gio-2.0 >= 2.22 gthread-2.0 >= 2.22\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.22 gio-2.0 >= 2.22 gthread-2.0 >= 2.22") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GLIB2_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0 >= 2.22 gio-2.0 >= 2.22 gthread-2.0 >= 2.22" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GLIB2_LIBS"; then
+ pkg_cv_GLIB2_LIBS="$GLIB2_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0 >= 2.22 gio-2.0 >= 2.22 gthread-2.0 >= 2.22\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "glib-2.0 >= 2.22 gio-2.0 >= 2.22 gthread-2.0 >= 2.22") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GLIB2_LIBS=`$PKG_CONFIG --libs "glib-2.0 >= 2.22 gio-2.0 >= 2.22 gthread-2.0 >= 2.22" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GLIB2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "glib-2.0 >= 2.22 gio-2.0 >= 2.22 gthread-2.0 >= 2.22" 2>&1`
+ else
+ GLIB2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "glib-2.0 >= 2.22 gio-2.0 >= 2.22 gthread-2.0 >= 2.22" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GLIB2_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (glib-2.0 >= 2.22 gio-2.0 >= 2.22 gthread-2.0 >= 2.22) were not met:
+
+$GLIB2_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables GLIB2_CFLAGS
+and GLIB2_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables GLIB2_CFLAGS
+and GLIB2_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ GLIB2_CFLAGS=$pkg_cv_GLIB2_CFLAGS
+ GLIB2_LIBS=$pkg_cv_GLIB2_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPUS" >&5
+$as_echo_n "checking for OPUS... " >&6; }
+
+if test -n "$OPUS_CFLAGS"; then
+ pkg_cv_OPUS_CFLAGS="$OPUS_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"opus >= 0.9.14\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "opus >= 0.9.14") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_OPUS_CFLAGS=`$PKG_CONFIG --cflags "opus >= 0.9.14" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$OPUS_LIBS"; then
+ pkg_cv_OPUS_LIBS="$OPUS_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"opus >= 0.9.14\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "opus >= 0.9.14") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_OPUS_LIBS=`$PKG_CONFIG --libs "opus >= 0.9.14" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ OPUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "opus >= 0.9.14" 2>&1`
+ else
+ OPUS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "opus >= 0.9.14" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$OPUS_PKG_ERRORS" >&5
+
+ have_opus=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ have_opus=no
+else
+ OPUS_CFLAGS=$pkg_cv_OPUS_CFLAGS
+ OPUS_LIBS=$pkg_cv_OPUS_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_opus=yes
+fi
+
+ if test "x$have_opus" = "xyes"; then
+ HAVE_OPUS_TRUE=
+ HAVE_OPUS_FALSE='#'
+else
+ HAVE_OPUS_TRUE='#'
+ HAVE_OPUS_FALSE=
+fi
+
+ if test "x$have_opus" = "xyes" ; then
+
+$as_echo "#define HAVE_OPUS 1" >>confdefs.h
+
+ fi
+
+
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENSSL" >&5
+$as_echo_n "checking for OPENSSL... " >&6; }
+
+if test -n "$OPENSSL_CFLAGS"; then
+ pkg_cv_OPENSSL_CFLAGS="$OPENSSL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "openssl") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_OPENSSL_CFLAGS=`$PKG_CONFIG --cflags "openssl" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$OPENSSL_LIBS"; then
+ pkg_cv_OPENSSL_LIBS="$OPENSSL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"openssl\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "openssl") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_OPENSSL_LIBS=`$PKG_CONFIG --libs "openssl" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ OPENSSL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "openssl" 2>&1`
+ else
+ OPENSSL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "openssl" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$OPENSSL_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (openssl) were not met:
+
+$OPENSSL_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables OPENSSL_CFLAGS
+and OPENSSL_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables OPENSSL_CFLAGS
+and OPENSSL_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ OPENSSL_CFLAGS=$pkg_cv_OPENSSL_CFLAGS
+ OPENSSL_LIBS=$pkg_cv_OPENSSL_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+SPICE_COMMON_CFLAGS='$(PIXMAN_CFLAGS) $(SMARTCARD_CFLAGS) $(CELT051_CFLAGS) $(GLIB2_CFLAGS) $(OPUS_CFLAGS) $(OPENSSL_CFLAGS)'
+SPICE_COMMON_LIBS='$(PIXMAN_LIBS) $(CELT051_LIBS) $(GLIB2_LIBS) $(OPUS_LIBS) $(OPENSSL_LIBS)'
+
+
+
+# The End!
+ac_config_files="$ac_config_files Makefile common/Makefile python_modules/Makefile tests/Makefile"
+
+
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ ac_libobjs=$ac_libobjs" \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ ac_ltlibobjs=$ac_ltlibobjs" \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+ if test -n "$am_sleep_pid"; then
+ # Hide warnings about reused PIDs.
+ wait $am_sleep_pid 2>/dev/null
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+if test -z "${HAVE_SMARTCARD_TRUE}" && test -z "${HAVE_SMARTCARD_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_SMARTCARD\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_CELT051_TRUE}" && test -z "${HAVE_CELT051_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_CELT051\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_OPUS_TRUE}" && test -z "${HAVE_OPUS_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_OPUS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by spice-common $as_me noversion, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <spice-devel@lists.freedesktop.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+spice-common config.status noversion
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ CONFIG_FILES=$CONFIG_FILES" '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ CONFIG_HEADERS=$CONFIG_HEADERS" '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) ac_config_targets=$ac_config_targets" $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`'
+configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_import \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_cv_nm_interface \
+nm_file_list_spec \
+lt_cv_truncate_bin \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+configure_time_dlsearch_path \
+configure_time_lt_sys_library_path; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "common/Makefile") CONFIG_FILES="$CONFIG_FILES common/Makefile" ;;
+ "python_modules/Makefile") CONFIG_FILES="$CONFIG_FILES python_modules/Makefile" ;;
+ "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = "\a"
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = "\a"
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ ac_file_inputs=$ac_file_inputs" '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Older Autoconf quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named 'Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running 'make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "$am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags=''
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shared archive member basename,for filename based shared library versioning on AIX.
+shared_archive_member_spec=$shared_archive_member_spec
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm into a list of symbols to manually relocate.
+global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name lister interface.
+nm_interface=$lt_lt_cv_nm_interface
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and where our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# Command to truncate a binary pipe.
+lt_truncate_bin=$lt_lt_cv_truncate_bin
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Detected run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path
+
+# Explicit LT_SYS_LIBRARY_PATH set during ./configure time.
+configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x$2 in
+ x)
+ ;;
+ *:)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\"
+ ;;
+ x:*)
+ eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\"
+ ;;
+ *)
+ eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+
+
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in $*""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain=$ac_aux_dir/ltmain.sh
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
--- /dev/null
+AC_PREREQ([2.63])
+
+AC_INIT([spice-common],
+ [noversion],
+ [spice-devel@lists.freedesktop.org])
+
+AC_CONFIG_SRCDIR([common/bitops.h])
+AC_CONFIG_MACRO_DIR([m4])
+AM_CONFIG_HEADER([config.h])
+AC_CONFIG_AUX_DIR([build-aux])
+
+# For automake >= 1.12
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+
+# Checks for programs
+AM_INIT_AUTOMAKE([1.11 dist-xz no-dist-gzip tar-ustar foreign -Wall -Werror])
+AM_MAINTAINER_MODE
+AM_SILENT_RULES([yes])
+LT_INIT
+
+AC_PROG_CC
+AC_PROG_CC_C99
+if test "x$ac_cv_prog_cc_c99" = xno; then
+ AC_MSG_ERROR([C99 compiler is required.])
+fi
+AM_PROG_CC_C_O
+
+SPICE_CHECK_SYSDEPS
+
+# Checks for libraries
+PKG_CHECK_MODULES([PROTOCOL], [spice-protocol >= 0.12.12])
+
+SPICE_CHECK_PYTHON_MODULES()
+
+SPICE_CHECK_PIXMAN
+SPICE_CHECK_SMARTCARD
+SPICE_CHECK_CELT051
+SPICE_CHECK_GLIB2
+SPICE_CHECK_OPUS
+SPICE_CHECK_OPENSSL
+
+SPICE_COMMON_CFLAGS='$(PIXMAN_CFLAGS) $(SMARTCARD_CFLAGS) $(CELT051_CFLAGS) $(GLIB2_CFLAGS) $(OPUS_CFLAGS) $(OPENSSL_CFLAGS)'
+SPICE_COMMON_LIBS='$(PIXMAN_LIBS) $(CELT051_LIBS) $(GLIB2_LIBS) $(OPUS_LIBS) $(OPENSSL_LIBS)'
+AC_SUBST(SPICE_COMMON_CFLAGS)
+AC_SUBST(SPICE_COMMON_LIBS)
+
+# The End!
+AC_CONFIG_FILES([
+ Makefile
+ common/Makefile
+ python_modules/Makefile
+ tests/Makefile
+])
+
+AH_BOTTOM([
+/* argh.. this is evil */
+#if defined(FIXME_SERVER_SMARTCARD) && defined(USE_SMARTCARD)
+%:undef USE_SMARTCARD
+#endif
+])
+
+AC_OUTPUT
--- /dev/null
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_python_module.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PYTHON_MODULE(modname[, fatal])
+#
+# DESCRIPTION
+#
+# Checks for Python module.
+#
+# If fatal is non-empty then absence of a module will trigger an error.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Andrew Collier
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 6
+
+AU_ALIAS([AC_PYTHON_MODULE], [AX_PYTHON_MODULE])
+AC_DEFUN([AX_PYTHON_MODULE],[
+ if test -z $PYTHON;
+ then
+ PYTHON="python"
+ fi
+ PYTHON_NAME=`basename $PYTHON`
+ AC_MSG_CHECKING($PYTHON_NAME module: $1)
+ $PYTHON -c "import $1" 2>/dev/null
+ if test $? -eq 0;
+ then
+ AC_MSG_RESULT(yes)
+ eval AS_TR_CPP(HAVE_PYMOD_$1)=yes
+ else
+ AC_MSG_RESULT(no)
+ eval AS_TR_CPP(HAVE_PYMOD_$1)=no
+ #
+ if test -n "$2"
+ then
+ AC_MSG_ERROR(failed to find required module $1)
+ exit 1
+ fi
+ fi
+])
--- /dev/null
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 2014 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program or library that is built
+# using GNU Libtool, you may include this file under the same
+# distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+])
+
+# serial 58 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS=$ltmain
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_PREPARE_CC_BASENAME
+# -----------------------
+m4_defun([_LT_PREPARE_CC_BASENAME], [
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+func_cc_basename ()
+{
+ for cc_temp in @S|@*""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+ done
+ func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+}
+])# _LT_PREPARE_CC_BASENAME
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME,
+# but that macro is also expanded into generated libtool script, which
+# arranges for $SED and $ECHO to be set by different means.
+m4_defun([_LT_CC_BASENAME],
+[m4_require([_LT_PREPARE_CC_BASENAME])dnl
+AC_REQUIRE([_LT_DECL_SED])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+func_cc_basename $1
+cc_basename=$func_cc_basename_result
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+m4_require([_LT_CMD_TRUNCATE])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options that allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+old_CC=$CC
+old_CFLAGS=$CFLAGS
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from 'configure', and 'config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# 'config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain=$ac_aux_dir/ltmain.sh
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the 'libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to 'config.status' so that its
+# declaration there will have the same value as in 'configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags='_LT_TAGS'dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into 'config.status', and then the shell code to quote escape them in
+# for loops in 'config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable. If COMMENT is supplied, it is inserted after the
+# '#!' sequence but before initialization text begins. After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script. The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test 0 = "$lt_write_fail" && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+'$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test 0 != $[#]
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try '$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try '$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test yes = "$silent" &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options that allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}"; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile=${ofile}T
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+
+# Provide generalized library-building support services.
+# Written by Gordon Matzigkeit, 1996
+
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# Configured defaults for sys_lib_dlsearch_path munging.
+: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"}
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ cat <<'_LT_EOF' >> "$cfgfile"
+
+# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_PREPARE_MUNGE_PATH_LIST
+_LT_PREPARE_CC_BASENAME
+
+# ### END FUNCTIONS SHARED WITH CONFIGURE
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test set != "${COLLECT_NAMES+set}"; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Go], [_LT_LANG(GO)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_GO. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC], [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+ fi
+fi
+if test -z "$GOC"; then
+ AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+ [LT_LANG(GO)],
+ [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "$LT_MULTI_MODULE"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ # If there is a non-empty error log, and "single_module"
+ # appears in it, assume the flag caused a linker warning
+ if test -s conftest.err && $GREP single_module conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ # Otherwise, if the output was created with a 0 exit code from
+ # the compiler, it worked.
+ elif test -f libconftest.dylib && test 0 = "$_lt_result"; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS=$save_LDFLAGS
+ ])
+
+ AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+ [lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+ echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+ $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+ echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+ $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -s conftest.err && $GREP force_load conftest.err; then
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]][[,.]]*)
+ _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test yes = "$lt_cv_apple_cc_single_mod"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test yes = "$lt_cv_ld_exported_symbols_list"; then
+ _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib'
+ fi
+ if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ if test yes = "$lt_cv_ld_force_load"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+ [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined
+ case $cc_basename in
+ ifort*|nagfor*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test yes = "$_lt_dar_can_shared"; then
+ output_verbose_link_cmd=func_echo_all
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
+ m4_if([$1], [CXX],
+[ if test yes != "$lt_cv_apple_cc_single_mod"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test set = "${lt_cv_aix_libpath+set}"; then
+ aix_libpath=$lt_cv_aix_libpath
+else
+ AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+ lt_aix_libpath_sed='[
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\([^ ]*\) *$/\1/
+ p
+ }
+ }]'
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ # Check for a 64-bit object if we didn't find anything.
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+ fi],[])
+ if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+ _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib
+ fi
+ ])
+ aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script that will find a shell with a builtin
+# printf (that we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO "$*"
+}
+
+case $ECHO in
+ printf*) AC_MSG_RESULT([printf]) ;;
+ print*) AC_MSG_RESULT([print -r]) ;;
+ *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test "X`printf %s $ECHO`" = "X$ECHO" \
+ || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
+ [Search for dependent libraries within DIR (or the compiler's sysroot
+ if not specified).])],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted. We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case $with_sysroot in #(
+ yes)
+ if test yes = "$GCC"; then
+ lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+ fi
+ ;; #(
+ /*)
+ lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+ ;; #(
+ no|'')
+ ;; #(
+ *)
+ AC_MSG_RESULT([$with_sysroot])
+ AC_MSG_ERROR([The sysroot must be an absolute path.])
+ ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and where our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test no = "$enable_libtool_lock" || enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out what ABI is being produced by ac_compile, and set mode
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE=32
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE=64
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+mips64*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ emul=elf
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ emul="${emul}32"
+ ;;
+ *64-bit*)
+ emul="${emul}64"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *MSB*)
+ emul="${emul}btsmip"
+ ;;
+ *LSB*)
+ emul="${emul}ltsmip"
+ ;;
+ esac
+ case `/usr/bin/file conftest.$ac_objext` in
+ *N32*)
+ emul="${emul}n32"
+ ;;
+ esac
+ LD="${LD-ld} -m $emul"
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly. Note that the listed cases only cover the
+ # situations where additional linker options are needed (such as when
+ # doing 32-bit compilation for a host where ld defaults to 64-bit, or
+ # vice versa); the common cases where no linker options are needed do
+ # not appear in the list.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ powerpc64le-*linux*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ powerpcle-*linux*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test yes != "$lt_cv_cc_needs_belf"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS=$SAVE_CFLAGS
+ fi
+ ;;
+*-*solaris*)
+ # Find out what ABI is being produced by ac_compile, and set linker
+ # options accordingly.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*)
+ case $host in
+ i?86-*-solaris*|x86_64-*-solaris*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ sparc*-*-solaris*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ # GNU ld 2.21 introduced _sol2 emulations. Use them if available.
+ if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+ LD=${LD-ld}_sol2
+ fi
+ ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks=$enable_libtool_lock
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+ [lt_cv_ar_at_file=no
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+ [echo conftest.$ac_objext > conftest.lst
+ lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+ AC_TRY_EVAL([lt_ar_try])
+ if test 0 -eq "$ac_status"; then
+ # Ensure the archiver fails upon bogus file names.
+ rm -f conftest.$ac_objext libconftest.a
+ AC_TRY_EVAL([lt_ar_try])
+ if test 0 -ne "$ac_status"; then
+ lt_cv_ar_at_file=@
+ fi
+ fi
+ rm -f conftest.* libconftest.a
+ ])
+ ])
+
+if test no = "$lt_cv_ar_at_file"; then
+ archiver_list_spec=
+else
+ archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+ [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ bitrig* | openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+ [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test yes = "[$]$2"; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS=$save_LDFLAGS
+])
+
+if test yes = "[$]$2"; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring=ABCD
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ os2*)
+ # The test takes a long time on OS/2.
+ lt_cv_sys_max_cmd_len=8192
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len" && \
+ test undefined != "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test X`env echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test 17 != "$i" # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n "$lt_cv_sys_max_cmd_len"; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes = "$cross_compiling"; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisibility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test yes != "$enable_dlopen"; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen=load_add_on
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen=LoadLibrary
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[
+ lt_cv_dlopen=dyld
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ tpf*)
+ # Don't try to run any link tests for TPF. We know it's impossible
+ # because TPF is a cross-compiler, and we know how we open DSOs.
+ lt_cv_dlopen=dlopen
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=no
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen=shl_load],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen=dlopen],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test no = "$lt_cv_dlopen"; then
+ enable_dlopen=no
+ else
+ enable_dlopen=yes
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS=$CPPFLAGS
+ test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS=$LDFLAGS
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS=$LIBS
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test yes = "$lt_cv_dlopen_self"; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links=nottested
+if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test no = "$hard_links"; then
+ AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/",
+ [Define to the sub-directory where libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then
+
+ # We can hardcode non-existent directories.
+ if test no != "$_LT_TAGVAR(hardcode_direct, $1)" &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" &&
+ test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test relink = "$_LT_TAGVAR(hardcode_action, $1)" ||
+ test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test yes = "$shlibpath_overrides_runpath" ||
+ test no = "$enable_shared"; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP"; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_PREPARE_MUNGE_PATH_LIST
+# ---------------------------
+# Make sure func_munge_path_list() is defined correctly.
+m4_defun([_LT_PREPARE_MUNGE_PATH_LIST],
+[[# func_munge_path_list VARIABLE PATH
+# -----------------------------------
+# VARIABLE is name of variable containing _space_ separated list of
+# directories to be munged by the contents of PATH, which is string
+# having a format:
+# "DIR[:DIR]:"
+# string "DIR[ DIR]" will be prepended to VARIABLE
+# ":DIR[:DIR]"
+# string "DIR[ DIR]" will be appended to VARIABLE
+# "DIRP[:DIRP]::[DIRA:]DIRA"
+# string "DIRP[ DIRP]" will be prepended to VARIABLE and string
+# "DIRA[ DIRA]" will be appended to VARIABLE
+# "DIR[:DIR]"
+# VARIABLE will be replaced by "DIR[ DIR]"
+func_munge_path_list ()
+{
+ case x@S|@2 in
+ x)
+ ;;
+ *:)
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\"
+ ;;
+ x:*)
+ eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\"
+ ;;
+ *::*)
+ eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\"
+ eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\"
+ ;;
+ *)
+ eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\"
+ ;;
+ esac
+}
+]])# _LT_PREPARE_PATH_LIST
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test yes = "$GCC"; then
+ case $host_os in
+ darwin*) lt_awk_arg='/^libraries:/,/LR/' ;;
+ *) lt_awk_arg='/^libraries:/' ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
+ *) lt_sed_strip_eq='s|=/|/|g' ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary...
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ # ...but if some path component already ends with the multilib dir we assume
+ # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer).
+ case "$lt_multi_os_dir; $lt_search_path_spec " in
+ "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*)
+ lt_multi_os_dir=
+ ;;
+ esac
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir"
+ elif test -n "$lt_multi_os_dir"; then
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS = " "; FS = "/|\n";} {
+ lt_foo = "";
+ lt_count = 0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo = "/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=.so
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+AC_ARG_VAR([LT_SYS_LIBRARY_PATH],
+[User-defined run-time library search path.])
+
+case $host_os in
+aix3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 supports IA64
+ library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line '#! .'. This would cause the generated library to
+ # depend on '.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # Using Import Files as archive members, it is possible to support
+ # filename-based versioning of shared library archives on AIX. While
+ # this would work for both with and without runtime linking, it will
+ # prevent static linking of such archives. So we do filename-based
+ # shared library versioning with .so extension only, which is used
+ # when both runtime linking and shared linking is enabled.
+ # Unfortunately, runtime linking may impact performance, so we do
+ # not want this to be the default eventually. Also, we use the
+ # versioned .so libs for executables only if there is the -brtl
+ # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+ # To allow for filename-based versioning support, we need to create
+ # libNAME.so.V as an archive file, containing:
+ # *) an Import File, referring to the versioned filename of the
+ # archive as well as the shared archive member, telling the
+ # bitwidth (32 or 64) of that shared object, and providing the
+ # list of exported symbols of that shared object, eventually
+ # decorated with the 'weak' keyword
+ # *) the shared object with the F_LOADONLY flag set, to really avoid
+ # it being seen by the linker.
+ # At run time we better use the real file rather than another symlink,
+ # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+ case $with_aix_soname,$aix_use_runtimelinking in
+ # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ aix,yes) # traditional libtool
+ dynamic_linker='AIX unversionable lib.so'
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ aix,no) # traditional AIX only
+ dynamic_linker='AIX lib.a[(]lib.so.V[)]'
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ svr4,*) # full svr4 only
+ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,yes) # both, prefer svr4
+ dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]"
+ library_names_spec='$libname$release$shared_ext$major $libname$shared_ext'
+ # unpreferred sharedlib libNAME.a needs extra handling
+ postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+ postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"'
+ # We do not specify a path in Import Files, so LIBPATH fires.
+ shlibpath_overrides_runpath=yes
+ ;;
+ *,no) # both, prefer aix
+ dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]"
+ library_names_spec='$libname$release.a $libname.a'
+ soname_spec='$libname$release$shared_ext$major'
+ # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling
+ postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+ postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+ ;;
+ esac
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='$libname$shared_ext'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$cc_basename in
+ yes,*)
+ # gcc
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ ;;
+
+ *,cl*)
+ # Native MSVC
+ libname_spec='$name'
+ soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
+ library_names_spec='$libname.dll.lib'
+
+ case $build_os in
+ mingw*)
+ sys_lib_search_path_spec=
+ lt_save_ifs=$IFS
+ IFS=';'
+ for lt_path in $LIB
+ do
+ IFS=$lt_save_ifs
+ # Let DOS variable expansion print the short 8.3 style file name.
+ lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+ sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+ done
+ IFS=$lt_save_ifs
+ # Convert to MSYS style.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+ ;;
+ cygwin*)
+ # Convert to unix form, then to dos form, then back to unix form
+ # but this time dos style (no spaces!) so that the unix form looks
+ # like /cygdrive/c/PROGRA~1:/cygdr...
+ sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+ sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ *)
+ sys_lib_search_path_spec=$LIB
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # FIXME: find the short name or the path components, as spaces are
+ # common. (e.g. "Program Files" -> "PROGRA~1")
+ ;;
+ esac
+
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+ dynamic_linker='Win32 link.exe'
+ ;;
+
+ *)
+ # Assume MSVC wrapper
+ library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
+ dynamic_linker='Win32 ld.exe'
+ ;;
+ esac
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$major$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$major$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[23]].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+haiku*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ if test 32 = "$HPUX_IA64_MODE"; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux32
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ sys_lib_dlsearch_path_spec=/usr/lib/hpux64
+ fi
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test yes = "$lt_cv_prog_gnu_ld"; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff"
+ sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+linux*android*)
+ version_type=none # Android doesn't support versioned libraries.
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext'
+ soname_spec='$libname$release$shared_ext'
+ finish_cmds=
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ dynamic_linker='Android linker'
+ # Don't embed -rpath directories since the linker doesn't support them.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+ [lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [lt_cv_shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+ ])
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Add ABI-specific directories to the system library path.
+ sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
+
+ # Ideally, we could use ldconfig to report *all* directores which are
+ # searched for libraries, however this is still not possible. Aside from not
+ # being certain /sbin/ldconfig is available, command
+ # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
+ # even though it is searched at run-time. Try to do the best guess by
+ # appending ld.so.conf contents (and includes) to the search path.
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd* | bitrig*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec=/usr/lib
+ need_lib_prefix=no
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ need_version=no
+ else
+ need_version=yes
+ fi
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+os2*)
+ libname_spec='$name'
+ version_type=windows
+ shrext_cmds=.dll
+ need_version=no
+ need_lib_prefix=no
+ # OS/2 can only load a DLL with a base name of 8 characters or less.
+ soname_spec='`test -n "$os2dllname" && libname="$os2dllname";
+ v=$($ECHO $release$versuffix | tr -d .-);
+ n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _);
+ $ECHO $n$v`$shared_ext'
+ library_names_spec='${libname}_dll.$libext'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=BEGINLIBPATH
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ postinstall_cmds='base_file=`basename \$file`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='$libname$release$shared_ext$major'
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test yes = "$with_gnu_ld"; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec; then
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext'
+ soname_spec='$libname$shared_ext.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=sco
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test yes = "$with_gnu_ld"; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux # correct to gnu/linux during the next big refactor
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux # correct to gnu/linux during the next big refactor
+ library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'
+ soname_spec='$libname$release$shared_ext$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test no = "$dynamic_linker" && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test yes = "$GCC"; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then
+ sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec
+fi
+
+if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then
+ sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec
+fi
+
+# remember unaugmented sys_lib_dlsearch_path content for libtool script decls...
+configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec
+
+# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code
+func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH"
+
+# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool
+configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+ [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2],
+ [Detected run-time system search path for libraries])
+_LT_DECL([], [configure_time_lt_sys_library_path], [2],
+ [Explicit LT_SYS_LIBRARY_PATH set during ./configure time])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program that can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD=$MAGIC_CMD
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$1"; then
+ lt_cv_path_MAGIC_CMD=$ac_dir/"$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS=$lt_save_ifs
+ MAGIC_CMD=$lt_save_MAGIC_CMD
+ ;;
+esac])
+MAGIC_CMD=$lt_cv_path_MAGIC_CMD
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program that can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test no = "$withval" || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test yes = "$GCC"; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return, which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD=$ac_prog
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test yes = "$with_gnu_ld"; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD=$ac_dir/$ac_prog
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test no != "$with_gnu_ld" && break
+ ;;
+ *)
+ test yes != "$with_gnu_ld" && break
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+else
+ lt_cv_path_LD=$LD # Let the user override the test with a path.
+fi])
+LD=$lt_cv_path_LD
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ if test yes != "$GCC"; then
+ reload_cmds=false
+ fi
+ ;;
+ darwin*)
+ if test yes = "$GCC"; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_PATH_DD
+# -----------
+# find a working dd
+m4_defun([_LT_PATH_DD],
+[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
+[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi])
+rm -f conftest.i conftest2.i conftest.out])
+])# _LT_PATH_DD
+
+
+# _LT_CMD_TRUNCATE
+# ----------------
+# find command to truncate a binary pipe
+m4_defun([_LT_CMD_TRUNCATE],
+[m4_require([_LT_PATH_DD])
+AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+ cmp -s conftest.i conftest.out \
+ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
+_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
+ [Command to truncate a binary pipe])
+])# _LT_CMD_TRUNCATE
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# 'unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# that responds to the $file_magic_cmd with a given extended regex.
+# If you have 'file' or equivalent on your system and you're not sure
+# whether 'pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ # Keep this pattern in sync with the one in func_win32_libid.
+ lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd* | bitrig*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+os2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+ case $host_os in
+ mingw* | pw32*)
+ if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+ want_nocaseglob=yes
+ else
+ file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+ fi
+ ;;
+ esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+ [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+ [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM=$NM
+else
+ lt_nm_to_check=${ac_tool_prefix}nm
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS=$lt_save_ifs
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/$lt_tmp_nm
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the 'sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
+ case $build_os in
+ mingw*) lt_bad_file=conftest.nm/nofile ;;
+ *) lt_bad_file=/dev/null ;;
+ esac
+ case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
+ *$lt_bad_file* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break 2
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break 2
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS=$lt_save_ifs
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test no != "$lt_cv_path_NM"; then
+ NM=$lt_cv_path_NM
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+ case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols -headers"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+ AC_SUBST([DUMPBIN])
+ if test : != "$DUMPBIN"; then
+ NM=$DUMPBIN
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+ # two different shell functions defined in ltmain.sh;
+ # decide which one to use based on capabilities of $DLLTOOL
+ case `$DLLTOOL --help 2>&1` in
+ *--identify-strict*)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+ ;;
+ *)
+ lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+ ;;
+ esac
+ ;;
+*)
+ # fallback: assume linklib IS sharedlib
+ lt_cv_sharedlib_from_linklib_cmd=$ECHO
+ ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+ [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+ [lt_cv_path_mainfest_tool=no
+ echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+ $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+ lt_cv_path_mainfest_tool=yes
+ fi
+ rm -f conftest*])
+if test yes != "$lt_cv_path_mainfest_tool"; then
+ MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# _LT_DLL_DEF_P([FILE])
+# ---------------------
+# True iff FILE is a Windows DLL '.def' file.
+# Keep in sync with func_dll_def_p in the libtool script
+AC_DEFUN([_LT_DLL_DEF_P],
+[dnl
+ test DEF = "`$SED -n dnl
+ -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace
+ -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments
+ -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl
+ -e q dnl Only consider the first "real" line
+ $1`" dnl
+])# _LT_DLL_DEF_P
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw)
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM=-lm)
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test yes = "$GCC"; then
+ case $cc_basename in
+ nvcc*)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+ esac
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test ia64 = "$host_cpu"; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Gets list of data symbols to import.
+ lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
+ # Adjust the below global symbol transforms to fixup imported variables.
+ lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
+ lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
+ lt_c_name_lib_hook="\
+ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\
+ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'"
+else
+ # Disable hooks by default.
+ lt_cv_sys_global_symbol_to_import=
+ lt_cdecl_hook=
+ lt_c_name_hook=
+ lt_c_name_lib_hook=
+fi
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n"\
+$lt_cdecl_hook\
+" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
+$lt_c_name_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
+
+# Transform an extracted symbol line into symbol name with lib prefix and
+# symbol address.
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
+$lt_c_name_lib_hook\
+" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
+" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
+" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function,
+ # D for any global variable and I for any imported variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\
+" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\
+" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\
+" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\
+" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+ lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */
+#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE
+/* DATA imports from DLLs on WIN32 can't be const, because runtime
+ relocations are performed -- see ld's documentation on pseudo-relocs. */
+# define LT@&t@_DLSYM_CONST
+#elif defined __osf__
+/* This system does not cope well with relocations in const data. */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+LT@&t@_DLSYM_CONST struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_globsym_save_LIBS=$LIBS
+ lt_globsym_save_CFLAGS=$CFLAGS
+ LIBS=conftstm.$ac_objext
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then
+ pipe_works=yes
+ fi
+ LIBS=$lt_globsym_save_LIBS
+ CFLAGS=$lt_globsym_save_CFLAGS
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test yes = "$pipe_works"; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+ nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1],
+ [Transform the output of nm into a list of symbols to manually relocate])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([nm_interface], [lt_cv_nm_interface], [1],
+ [The name lister interface])
+_LT_DECL([], [nm_file_list_spec], [1],
+ [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64, which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the '-m68020' flag to GCC prevents building anything better,
+ # like '-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+ if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+ fi
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test ia64 = "$host_cpu"; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ case $cc_basename in
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ case $host_os in
+ os2*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static'
+ ;;
+ esac
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ # old Intel for x86_64, which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ nagfor*)
+ # NAG Fortran compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ *Sun\ F* | *Sun*Fortran*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Intel*\ [[CF]]*Compiler*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ *Portland\ Group*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms that do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
+ ;;
+ cygwin* | mingw* | cegcc*)
+ case $cc_basename in
+ cl*)
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+ ;;
+ esac
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ' (' and ')$', so one must not match beginning or
+ # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc',
+ # as well as any symbol that contains 'd'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test yes != "$GCC"; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd* | bitrig*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test yes = "$with_gnu_ld"; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+ *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test yes = "$lt_use_gnu_ld_interface"; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='$wl'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test ia64 != "$host_cpu"; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test linux-dietlibc = "$host_os"; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test no = "$tmp_diet"
+ then
+ tmp_addflag=' $pic_flag'
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ nagfor*) # NAGFOR 5.3
+ tmp_sharedflag='-Wl,-shared' ;;
+ xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ tcc*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
+ ;;
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+ # Without the "-l" option, or with the "-B" option, AIX nm treats
+ # weak defined symbols like other global defined symbols, whereas
+ # GNU nm marks them as "W".
+ # While the 'weak' keyword is ignored in the Export File, we need
+ # it in the Import File for the 'aix-soname' feature, so we have
+ # to replace the "-B" option with "-P" for AIX nm.
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # traditional, no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ ;;
+ esac
+
+ if test yes = "$GCC"; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag="$shared_flag "'$wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ case $cc_basename in
+ cl*)
+ # Native MSVC
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # Assume MSVC wrapper
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+ esac
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ ;;
+
+ hpux10*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test yes,no = "$GCC,$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ m4_if($1, [], [
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ _LT_LINKER_OPTION([if $CC understands -b],
+ _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+ [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+ [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+ ;;
+ esac
+ fi
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ # This should be the same for all languages, so no per-tag cache variable.
+ AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+ [lt_cv_irix_exported_symbol],
+ [save_LDFLAGS=$LDFLAGS
+ LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE(
+ [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+ [C++], [[int foo (void) { return 0; }]],
+ [Fortran 77], [[
+ subroutine foo
+ end]],
+ [Fortran], [[
+ subroutine foo
+ end]])])],
+ [lt_cv_irix_exported_symbol=yes],
+ [lt_cv_irix_exported_symbol=no])
+ LDFLAGS=$save_LDFLAGS])
+ if test yes = "$lt_cv_irix_exported_symbol"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
+ fi
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ linux*)
+ case $cc_basename in
+ tcc*)
+ # Fabrice Bellard et al's Tiny C Compiler
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ osf3*)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test yes = "$GCC"; then
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='$wl'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'. GCC discards it without '$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test sequent = "$host_vendor"; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test yes = "$GCC"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test sni = "$host_vendor"; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test yes,yes = "$GCC,$enable_shared"; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+ [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+ [$RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ ])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting $shlibpath_var if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+ [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC=$CC
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report what library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC=$lt_save_CC
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test no != "$CXX" &&
+ ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) ||
+ (test g++ != "$CXX"))); then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_caught_CXX_error"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_CFLAGS=$CFLAGS
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ CFLAGS=$CXXFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test yes = "$GXX"; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test yes = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='$wl'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test ia64 = "$host_cpu"; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # have runtime linking enabled, and use it for executables.
+ # For shared libraries, we enable/disable runtime linking
+ # depending on the kind of the shared library created -
+ # when "with_aix_soname,aix_use_runtimelinking" is:
+ # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables
+ # "aix,yes" lib.so shared, rtl:yes, for executables
+ # lib.a static archive
+ # "both,no" lib.so.V(shr.o) shared, rtl:yes
+ # lib.a(lib.so.V) shared, rtl:no, for executables
+ # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a(lib.so.V) shared, rtl:no
+ # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables
+ # lib.a static archive
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # With aix-soname=svr4, we create the lib.so.V shared archives only,
+ # so we don't have lib.a shared libs to link our executables.
+ # We have to force runtime linking in this case.
+ aix_use_runtimelinking=yes
+ LDFLAGS="$LDFLAGS -Wl,-brtl"
+ fi
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+ case $with_aix_soname,$aix_use_runtimelinking in
+ aix,*) ;; # no import file
+ svr4,* | *,yes) # use import file
+ # The Import File defines what to hardcode.
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ ;;
+ esac
+
+ if test yes = "$GXX"; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`$CC -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag=$shared_flag' $wl-G'
+ fi
+ # Need to ensure runtime linking is disabled for the traditional
+ # shared library, or the linker may eventually find shared libraries
+ # /with/ Import File - we do not want to mix them.
+ shared_flag_aix='-shared'
+ shared_flag_svr4='-shared $wl-G'
+ else
+ # not using gcc
+ if test ia64 = "$host_cpu"; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test yes = "$aix_use_runtimelinking"; then
+ shared_flag='$wl-G'
+ else
+ shared_flag='$wl-bM:SRE'
+ fi
+ shared_flag_aix='$wl-bM:SRE'
+ shared_flag_svr4='$wl-G'
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ # The "-G" linker flag allows undefined symbols.
+ _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag
+ else
+ if test ia64 = "$host_cpu"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX([$1])
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok'
+ if test yes = "$with_gnu_ld"; then
+ # We only use this code for GNU lds that support --whole-archive.
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+ # -brtl affects multiple linker settings, -berok does not and is overridden later
+ compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+ if test svr4 != "$with_aix_soname"; then
+ # This is similar to how AIX traditionally builds its shared
+ # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+ fi
+ if test aix != "$with_aix_soname"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp'
+ else
+ # used by -dlpreopen to get the symbols
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir'
+ fi
+ _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $GXX,$cc_basename in
+ ,cl* | no,cl*)
+ # Native MSVC
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='@'
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=.dll
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp "$export_symbols" "$output_objdir/$soname.def";
+ echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
+ else
+ $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
+ fi~
+ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+ linknames='
+ # The linker will not automatically build a static lib if we build a DLL.
+ # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ # Don't use ranlib
+ _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+ _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+ lt_tool_outputfile="@TOOL_OUTPUT@"~
+ case $lt_outputfile in
+ *.exe|*.EXE) ;;
+ *)
+ lt_outputfile=$lt_outputfile.exe
+ lt_tool_outputfile=$lt_tool_outputfile.exe
+ ;;
+ esac~
+ func_to_tool_file "$lt_outputfile"~
+ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then
+ $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+ $RM "$lt_outputfile.manifest";
+ fi'
+ ;;
+ *)
+ # g++
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file, use it as
+ # is; otherwise, prepend EXPORTS...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ shrext_cmds=.dll
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~
+ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~
+ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~
+ $ECHO EXPORTS >> $output_objdir/$libname.def~
+ prefix_cmds="$SED"~
+ if test EXPORTS = "`$SED 1q $export_symbols`"; then
+ prefix_cmds="$prefix_cmds -e 1d";
+ fi~
+ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~
+ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
+ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
+ emximp -o $lib $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ haiku*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test yes = "$GXX"; then
+ if test no = "$with_gnu_ld"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
+ if test yes = "$supports_anon_versioning"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd* | bitrig*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC* | sunCC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands '-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test yes,no = "$GXX,$with_gnu_ld"; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require '-G' NOT '-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We CANNOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+ '"$_LT_TAGVAR(old_archive_cmds, $1)"
+ _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+ '"$_LT_TAGVAR(reload_cmds, $1)"
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)=$GXX
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test yes != "$_lt_caught_CXX_error"
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+ case @S|@2 in
+ .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;;
+ *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;;
+ esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $prev$p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test x-L = "$p" ||
+ test x-R = "$p"; then
+ prev=$p
+ continue
+ fi
+
+ # Expand the sysroot to ease extracting the directories later.
+ if test -z "$prev"; then
+ case $p in
+ -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+ -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+ -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+ esac
+ fi
+ case $p in
+ =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+ esac
+ if test no = "$pre_test_object_deps_done"; then
+ case $prev in
+ -L | -R)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)=$prev$p
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p"
+ fi
+ fi
+ prev=
+ ;;
+
+ *.lto.$objext) ;; # Ignore GCC LTO objects
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test no = "$pre_test_object_deps_done"; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)=$p
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)=$p
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test no = "$F77"; then
+ _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_F77"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${F77-"f77"}
+ CFLAGS=$FFLAGS
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)=$G77
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_F77"
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test no = "$FC"; then
+ _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test yes != "$_lt_disable_FC"; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_GCC=$GCC
+ lt_save_CFLAGS=$CFLAGS
+ CC=${FC-"f95"}
+ CFLAGS=$FCFLAGS
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test no = "$can_build_shared" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test yes = "$enable_shared" && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test ia64 != "$host_cpu"; then
+ case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in
+ yes,aix,yes) ;; # shared object as lib.so file only
+ yes,svr4,*) ;; # shared object as lib.so archive member only
+ yes,*) enable_static=no ;; # shared object in lib.a archive as well
+ esac
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test yes = "$enable_shared" || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu
+ _LT_TAGVAR(LD, $1)=$LD
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC=$lt_save_CC
+ CFLAGS=$lt_save_CFLAGS
+fi # test yes != "$_lt_disable_FC"
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)=$LD
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to 'libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code=$lt_simple_compile_test_code
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f "$lt_ac_sed" && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test 10 -lt "$lt_ac_count" && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test "$lt_ac_count" -gt "$lt_ac_max"; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine what file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path). These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+ ;;
+ esac
+ ;;
+ *-*-cygwin* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+ ;;
+ *-*-cygwin* )
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+ * ) # otherwise, assume *nix
+ lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+ ;;
+ esac
+ ;;
+ * ) # unhandled hosts (and "normal" native builds)
+ lt_cv_to_host_file_cmd=func_convert_file_noop
+ ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+ [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+ *-*-mingw* )
+ case $build in
+ *-*-mingw* ) # actually msys
+ lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+ ;;
+ esac
+ ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+ [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
--- /dev/null
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 8 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option '$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
+ [_LT_WITH_AIX_SONAME([aix])])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the 'shared' and
+# 'disable-shared' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the 'static' and
+# 'disable-static' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the 'fast-install'
+# and 'disable-fast-install' LT_INIT options.
+# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for pkg in $enableval; do
+ IFS=$lt_save_ifs
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the 'disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_AIX_SONAME([DEFAULT])
+# ----------------------------------
+# implement the --with-aix-soname flag, and support the `aix-soname=aix'
+# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
+# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
+m4_define([_LT_WITH_AIX_SONAME],
+[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
+shared_archive_member_spec=
+case $host,$enable_shared in
+power*-*-aix[[5-9]]*,yes)
+ AC_MSG_CHECKING([which variant of shared library versioning to provide])
+ AC_ARG_WITH([aix-soname],
+ [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
+ [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
+ [case $withval in
+ aix|svr4|both)
+ ;;
+ *)
+ AC_MSG_ERROR([Unknown argument to --with-aix-soname])
+ ;;
+ esac
+ lt_cv_with_aix_soname=$with_aix_soname],
+ [AC_CACHE_VAL([lt_cv_with_aix_soname],
+ [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
+ with_aix_soname=$lt_cv_with_aix_soname])
+ AC_MSG_RESULT([$with_aix_soname])
+ if test aix != "$with_aix_soname"; then
+ # For the AIX way of multilib, we name the shared archive member
+ # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+ # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+ # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+ # the AIX toolchain works better with OBJECT_MODE set (default 32).
+ if test 64 = "${OBJECT_MODE-32}"; then
+ shared_archive_member_spec=shr_64
+ else
+ shared_archive_member_spec=shr
+ fi
+ fi
+ ;;
+*)
+ with_aix_soname=aix
+ ;;
+esac
+
+_LT_DECL([], [shared_archive_member_spec], [0],
+ [Shared archive member basename, for filename based shared library versioning on AIX])dnl
+])# _LT_WITH_AIX_SONAME
+
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
+# LT_INIT options.
+# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [lt_p=${PACKAGE-default}
+ case $withval in
+ yes|no) pic_mode=$withval ;;
+ *)
+ pic_mode=default
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
+ for lt_pkg in $withval; do
+ IFS=$lt_save_ifs
+ if test "X$lt_pkg" = "X$lt_p"; then
+ pic_mode=yes
+ fi
+ done
+ IFS=$lt_save_ifs
+ ;;
+ esac],
+ [pic_mode=m4_default([$1], [default])])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the 'pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
--- /dev/null
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59, which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
--- /dev/null
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 4179 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.6])
+m4_define([LT_PACKAGE_REVISION], [2.4.6])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.6'
+macro_revision='2.4.6'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
--- /dev/null
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
+# Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
--- /dev/null
+# For autoconf < 2.63
+m4_ifndef([AS_VAR_APPEND],
+ AC_DEFUN([AS_VAR_APPEND], $1=$$1$2))
+m4_ifndef([AS_VAR_COPY],
+ [m4_define([AS_VAR_COPY],
+ [AS_LITERAL_IF([$1[]$2], [$1=$$2], [eval $1=\$$2])])])
+
+
+# SPICE_WARNING(warning)
+# SPICE_PRINT_MESSAGES
+# ----------------------
+# Collect warnings and print them at the end so they are clearly visible.
+# ---------------------
+AC_DEFUN([SPICE_WARNING],[AS_VAR_APPEND([spice_warnings],["|$1"])])
+AC_DEFUN([SPICE_PRINT_MESSAGES],[
+ ac_save_IFS="$IFS"
+ IFS="|"
+ for msg in $spice_warnings; do
+ IFS="$ac_save_IFS"
+ AS_VAR_IF([msg],[],,[AC_MSG_WARN([$msg]); echo >&2])
+ done
+ IFS="$ac_save_IFS"
+])
+
+
+# SPICE_CHECK_SYSDEPS()
+# ---------------------
+# Checks for header files and library functions needed by spice-common.
+# ---------------------
+AC_DEFUN([SPICE_CHECK_SYSDEPS], [
+ AC_C_BIGENDIAN
+ AC_FUNC_ALLOCA
+ AC_CHECK_HEADERS([arpa/inet.h malloc.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/socket.h unistd.h])
+
+ # Checks for typedefs, structures, and compiler characteristics
+ AC_C_INLINE
+ AC_TYPE_INT16_T
+ AC_TYPE_INT32_T
+ AC_TYPE_INT64_T
+ AC_TYPE_INT8_T
+ AC_TYPE_PID_T
+ AC_TYPE_SIZE_T
+ AC_TYPE_UINT16_T
+ AC_TYPE_UINT32_T
+ AC_TYPE_UINT64_T
+ AC_TYPE_UINT8_T
+
+ # Checks for library functions
+ # do not check malloc or realloc, since that cannot be cross-compiled checked
+ AC_FUNC_ERROR_AT_LINE
+ AC_FUNC_FORK
+ AC_CHECK_FUNCS([dup2 floor inet_ntoa memmove memset pow sqrt])
+])
+
+
+# SPICE_CHECK_SMARTCARD
+# ---------------------
+# Adds a --enable-smartcard switch in order to enable/disable smartcard
+# support, and checks if the needed libraries are available. If found, it will
+# return the flags to use in the SMARTCARD_CFLAGS and SMARTCARD_LIBS variables, and
+# it will define a USE_SMARTCARD preprocessor symbol as well as a HAVE_SMARTCARD
+# Makefile conditional.
+#----------------------
+AC_DEFUN([SPICE_CHECK_SMARTCARD], [
+ AC_ARG_ENABLE([smartcard],
+ AS_HELP_STRING([--enable-smartcard=@<:@yes/no/auto@:>@],
+ [Enable smartcard support @<:@default=auto@:>@]),
+ [],
+ [enable_smartcard="auto"])
+
+ have_smartcard=no
+ if test "x$enable_smartcard" != "xno"; then
+ PKG_CHECK_MODULES([SMARTCARD], [libcacard >= 2.5.1], [have_smartcard=yes], [have_smartcard=no])
+ if test "x$have_smartcard" = "xno"; then
+ PKG_CHECK_MODULES([SMARTCARD], [libcacard >= 0.1.2], [have_smartcard=yes have_smartcard_012=yes], [have_smartcard=no])
+ fi
+ if test "x$enable_smartcard" != "xauto" && test "x$have_smartcard" = "xno"; then
+ AC_MSG_ERROR("Smartcard support requested but libcacard could not be found")
+ fi
+ if test "x$have_smartcard_012" = "xyes"; then
+ AC_DEFINE(USE_SMARTCARD_012, [1], [Define if supporting smartcard proxying without libcacard.h])
+ fi
+ if test "x$have_smartcard" = "xyes"; then
+ AC_DEFINE(USE_SMARTCARD, [1], [Define if supporting smartcard proxying])
+ fi
+ fi
+ AM_CONDITIONAL(HAVE_SMARTCARD, test "x$have_smartcard" = "xyes")
+])
+
+
+# SPICE_CHECK_CELT051
+# -------------------
+# Adds a --disable-celt051 switch in order to enable/disable CELT 0.5.1
+# support, and checks if the needed libraries are available. If found, it will
+# return the flags to use in the CELT051_CFLAGS and CELT051_LIBS variables, and
+# it will define a HAVE_CELT051 preprocessor symbol as well as a HAVE_CELT051
+# Makefile conditional.
+#--------------------
+AC_DEFUN([SPICE_CHECK_CELT051], [
+ AC_ARG_ENABLE([celt051],
+ [ --disable-celt051 Disable celt051 audio codec (enabled by default)],,
+ [enable_celt051="yes"])
+
+ if test "x$enable_celt051" = "xyes"; then
+ PKG_CHECK_MODULES([CELT051], [celt051 >= 0.5.1.1], [have_celt051=yes], [have_celt051=no])
+ else
+ have_celt051=no
+ fi
+
+ AM_CONDITIONAL([HAVE_CELT051], [test "x$have_celt051" = "xyes"])
+ AM_COND_IF([HAVE_CELT051], AC_DEFINE([HAVE_CELT051], 1, [Define if we have celt051 codec]))
+])
+
+
+# SPICE_CHECK_OPUS
+# ----------------
+# Check for the availability of Opus. If found, it will return the flags to use
+# in the OPUS_CFLAGS and OPUS_LIBS variables, and it will define a
+# HAVE_OPUS preprocessor symbol as well as a HAVE_OPUS Makefile conditional.
+# ----------------
+AC_DEFUN([SPICE_CHECK_OPUS], [
+ PKG_CHECK_MODULES([OPUS], [opus >= 0.9.14], [have_opus=yes], [have_opus=no])
+
+ AM_CONDITIONAL([HAVE_OPUS], [test "x$have_opus" = "xyes"])
+ if test "x$have_opus" = "xyes" ; then
+ AC_DEFINE([HAVE_OPUS], [1], [Define if we have OPUS])
+ fi
+])
+
+
+# SPICE_CHECK_PIXMAN
+# ------------------
+# Check for the availability of pixman. If found, it will return the flags to
+# use in the PIXMAN_CFLAGS and PIXMAN_LIBS variables.
+#-------------------
+AC_DEFUN([SPICE_CHECK_PIXMAN], [
+ PKG_CHECK_MODULES(PIXMAN, pixman-1 >= 0.17.7)
+])
+
+
+# SPICE_CHECK_GLIB2
+# -----------------
+# Check for the availability of glib2. If found, it will return the flags to
+# use in the GLIB2_CFLAGS and GLIB2_LIBS variables.
+#------------------
+AC_DEFUN([SPICE_CHECK_GLIB2], [
+ PKG_CHECK_MODULES(GLIB2, glib-2.0 >= 2.22 gio-2.0 >= 2.22 gthread-2.0 >= 2.22)
+])
+
+# SPICE_CHECK_PYTHON_MODULES()
+# --------------------------
+# Adds a --enable-python-checks configure flags as well as checks for the
+# availability of the python modules needed by the python scripts generating
+# C code from spice.proto. These checks are not needed when building from
+# tarballs so they are disabled by default.
+#---------------------------
+AC_DEFUN([SPICE_CHECK_PYTHON_MODULES], [
+ AM_PATH_PYTHON
+ AC_ARG_ENABLE([python-checks],
+ AS_HELP_STRING([--enable-python-checks=@<:@yes/no@:>@],
+ [Enable checks for Python modules needed to build from git @<:@default=no@:>@]),
+ [],
+ [enable_python_checks="no"])
+ if test "x$enable_python_checks" != "xno"; then
+ AX_PYTHON_MODULE([six], [1])
+ AX_PYTHON_MODULE([pyparsing], [1])
+ fi
+])
+
+
+# SPICE_CHECK_LZ4
+# ---------------
+# Adds a --enable-lz4 switch in order to enable/disable LZ4 compression
+# support, and checks if the needed libraries are available. If found, it will
+# return the flags to use in the LZ4_CFLAGS and LZ4_LIBS variables, and
+# it will define a USE_LZ4 preprocessor symbol.
+# conditional.
+# ---------------
+AC_DEFUN([SPICE_CHECK_LZ4], [
+ AC_ARG_ENABLE([lz4],
+ AS_HELP_STRING([--enable-lz4=@<:@yes/no/auto@:>@],
+ [Enable LZ4 compression support @<:@default=auto@:>@]),
+ [],
+ [enable_lz4="auto"])
+
+ have_lz4="no"
+ if test "x$enable_lz4" != "xno"; then
+ PKG_CHECK_MODULES([LZ4], [liblz4], [have_lz4="yes"], [have_lz4="no"])
+
+ if test "x$have_lz4" = "xyes"; then
+ AC_DEFINE(USE_LZ4, [1], [Define to build with lz4 support])
+ elif test "x$enable_lz4" = "xyes"; then
+ AC_MSG_ERROR([lz4 support requested but liblz4 could not be found])
+ fi
+ fi
+ AM_CONDITIONAL(HAVE_LZ4, test "x$have_lz4" = "xyes")
+])
+
+
+# SPICE_CHECK_GSTREAMER(VAR, version, packages-to-check-for, [action-if-found, [action-if-not-found]])
+# ---------------------
+# Checks whether the specified GStreamer modules are present and sets the
+# corresponding autoconf variables and preprocessor definitions.
+# ---------------------
+AC_DEFUN([SPICE_CHECK_GSTREAMER], [
+ AS_VAR_PUSHDEF([have_gst],[have_]m4_tolower([$1]))dnl
+ AS_VAR_PUSHDEF([gst_inspect],[GST_INSPECT_$2])dnl
+ PKG_CHECK_MODULES([$1], [$3],
+ [have_gst="yes"
+ AC_SUBST(AS_TR_SH([[$1]_CFLAGS]))
+ AC_SUBST(AS_TR_SH([[$1]_LIBS]))
+ AS_VAR_APPEND([SPICE_REQUIRES], [" $3"])
+ AC_DEFINE(AS_TR_SH([HAVE_$1]), [1], [Define if supporting GStreamer $2])
+ AC_PATH_PROG(gst_inspect, gst-inspect-$2)
+ AS_IF([test "x$gst_inspect" = x],
+ SPICE_WARNING([Cannot verify that the required runtime GStreamer $2 elements are present because gst-inspect-$2 is missing]))
+ $4],
+ [have_gst="no"
+ $5])
+ AS_VAR_POPDEF([gst_inspect])dnl
+ AS_VAR_POPDEF([have_gst])dnl
+])
+
+# SPICE_CHECK_GSTREAMER_ELEMENTS(gst-inspect, package, elements-to-check-for)
+# ---------------------
+# Checks that the specified GStreamer elements are installed. If not it
+# issues a warning and sets missing_gstreamer_elements.
+# ---------------------
+AC_DEFUN([SPICE_CHECK_GSTREAMER_ELEMENTS], [
+AS_IF([test "x$1" != x],
+ [missing=""
+ for element in $3
+ do
+ AS_VAR_PUSHDEF([cache_var],[spice_cv_prog_${1}_${element}])dnl
+ AC_CACHE_CHECK([for the $element GStreamer element], cache_var,
+ [found=no
+ "$1" $element >/dev/null 2>/dev/null && found=yes
+ eval "cache_var=$found"])
+ AS_VAR_COPY(res, cache_var)
+ AS_IF([test "x$res" = "xno"], [missing="$missing $element"])
+ AS_VAR_POPDEF([cache_var])dnl
+ done
+ AS_IF([test "x$missing" != x],
+ [SPICE_WARNING([The$missing GStreamer element(s) are missing. You should be able to find them in the $2 package.])
+ missing_gstreamer_elements="yes"],
+ [test "x$missing_gstreamer_elements" = x],
+ [missing_gstreamer_elements="no"])
+ ])
+])
+
+# SPICE_CHECK_SASL
+# ----------------
+# Adds a --with-sasl switch to allow using SASL for authentication.
+# Checks whether the required library is available. If it is present,
+# it will return the flags to use in SASL_CFLAGS and SASL_LIBS variables,
+# and it will define a have_sasl configure variable and a HAVE_SASL preprocessor
+# symbol.
+# ----------------
+AC_DEFUN([SPICE_CHECK_SASL], [
+ AC_ARG_WITH([sasl],
+ [AS_HELP_STRING([--with-sasl=@<:@yes/no/auto@:>@],
+ [use cyrus SASL for authentication @<:@default=auto@:>@])],
+ [],
+ [with_sasl="auto"])
+
+ have_sasl=no
+ if test "x$with_sasl" != "xno"; then
+ PKG_CHECK_MODULES([SASL], [libsasl2], [have_sasl=yes],[have_sasl=no])
+ if test "x$have_sasl" = "xno" && test "x$with_sasl" = "xyes"; then
+ AC_MSG_ERROR([Cyrus SASL support requested but libsasl2 could not be found])
+ fi
+ if test "x$have_sasl" = "xyes"; then
+ AC_DEFINE([HAVE_SASL], 1, [whether Cyrus SASL is available for authentication])
+ fi
+ fi
+])
+
+# SPICE_CHECK_OPENSSL
+# -----------------
+# Check for the availability of openssl. If found, it will return the flags to
+# use in the OPENSSL_CFLAGS and OPENSSL_LIBS variables.
+#------------------
+AC_DEFUN([SPICE_CHECK_OPENSSL], [
+ PKG_CHECK_MODULES(OPENSSL, openssl)
+])
--- /dev/null
+NULL =
+
+PYTHON_MODULES = \
+ __init__.py \
+ codegen.py \
+ demarshal.py \
+ marshal.py \
+ ptypes.py \
+ spice_parser.py \
+ $(NULL)
+
+EXTRA_DIST = $(PYTHON_MODULES)
+
+DISTCLEANFILES = *.pyc
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = python_modules
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_module.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CELT051_CFLAGS = @CELT051_CFLAGS@
+CELT051_LIBS = @CELT051_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPUS_CFLAGS = @OPUS_CFLAGS@
+OPUS_LIBS = @OPUS_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PROTOCOL_CFLAGS = @PROTOCOL_CFLAGS@
+PROTOCOL_LIBS = @PROTOCOL_LIBS@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_COMMON_CFLAGS = @SPICE_COMMON_CFLAGS@
+SPICE_COMMON_LIBS = @SPICE_COMMON_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+PYTHON_MODULES = \
+ __init__.py \
+ codegen.py \
+ demarshal.py \
+ marshal.py \
+ ptypes.py \
+ spice_parser.py \
+ $(NULL)
+
+EXTRA_DIST = $(PYTHON_MODULES)
+DISTCLEANFILES = *.pyc
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign python_modules/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign python_modules/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+
+import six
+from io import StringIO
+
+def camel_to_underscores(s, upper = False):
+ res = ""
+ for i in range(len(s)):
+ c = s[i]
+ if i > 0 and c.isupper():
+ res = res + "_"
+ if upper:
+ res = res + c.upper()
+ else:
+ res = res + c.lower()
+ return res
+
+def underscores_to_camel(s):
+ res = ""
+ do_upper = True
+ for i in range(len(s)):
+ c = s[i]
+ if c == "_":
+ do_upper = True
+ else:
+ if do_upper:
+ res = res + c.upper()
+ else:
+ res = res + c
+ do_upper = False
+ return res
+
+proto_prefix = "Temp"
+
+def set_prefix(prefix):
+ global proto_prefix
+ global proto_prefix_upper
+ global proto_prefix_lower
+ proto_prefix = prefix
+ proto_prefix_upper = prefix.upper()
+ proto_prefix_lower = prefix.lower()
+
+def prefix_underscore_upper(*args):
+ s = proto_prefix_upper
+ for arg in args:
+ s = s + "_" + arg
+ return s
+
+def prefix_underscore_lower(*args):
+ s = proto_prefix_lower
+ for arg in args:
+ s = s + "_" + arg
+ return s
+
+def prefix_camel(*args):
+ s = proto_prefix
+ for arg in args:
+ s = s + underscores_to_camel(arg)
+ return s
+
+def increment_identifier(idf):
+ v = idf[-1:]
+ if v.isdigit():
+ return idf[:-1] + str(int(v) + 1)
+ return idf + "2"
+
+def sum_array(array):
+ if len(array) == 0:
+ return 0
+ return " + ".join(array)
+
+class CodeWriter:
+ def __init__(self):
+ self.out = StringIO()
+ self.contents = [self.out]
+ self.indentation = 0
+ self.at_line_start = True
+ self.indexes = ["i", "j", "k", "ii", "jj", "kk"]
+ self.current_index = 0
+ self.generated = {}
+ self.vars = []
+ self.has_error_check = False
+ self.options = {}
+ self.function_helper_writer = None
+ self.index_type = 'uint32_t'
+
+ def set_option(self, opt, value = True):
+ self.options[opt] = value
+
+ def has_option(self, opt):
+ return opt in self.options
+
+ def set_is_generated(self, kind, name):
+ if kind not in self.generated:
+ v = {}
+ self.generated[kind] = v
+ else:
+ v = self.generated[kind]
+ v[name] = 1
+
+ def is_generated(self, kind, name):
+ if kind not in self.generated:
+ return False
+ v = self.generated[kind]
+ return name in v
+
+ def getvalue(self):
+ strs = [writer.getvalue() for writer in self.contents]
+ return "".join(strs)
+
+ def get_subwriter(self):
+ writer = CodeWriter()
+ self.contents.append(writer)
+ self.out = StringIO()
+ self.contents.append(self.out)
+ writer.indentation = self.indentation
+ writer.at_line_start = self.at_line_start
+ writer.index_type = self.index_type
+ writer.generated = self.generated
+ writer.options = self.options
+ writer.public_prefix = self.public_prefix
+
+ return writer
+
+ def write(self, s):
+ # Ensure its a unicode string
+ if six.PY3:
+ s = str(s)
+ else:
+ s = unicode(s)
+
+ if len(s) == 0:
+ return
+
+ if self.at_line_start:
+ self.out.write(u" " * self.indentation)
+ self.at_line_start = False
+ self.out.write(s)
+ return self
+
+ def newline(self):
+ self.out.write(u"\n")
+ self.at_line_start = True
+ return self
+
+ def writeln(self, s):
+ self.write(s)
+ self.newline()
+ return self
+
+ def label(self, s):
+ self.indentation = self.indentation - 1
+ self.write(s + ":")
+ self.indentation = self.indentation + 1
+ self.newline()
+
+ def statement(self, s):
+ self.write(s)
+ self.write(";")
+ self.newline()
+ return self
+
+ def assign(self, var, val):
+ self.write("%s = %s" % (var, val))
+ self.write(";")
+ self.newline()
+ return self
+
+ def increment(self, var, val):
+ self.write("%s += %s" % (var, val))
+ self.write(";")
+ self.newline()
+ return self
+
+ def comment(self, str):
+ self.write("/* " + str + " */")
+ return self
+
+ def todo(self, str):
+ self.comment("TODO: *** %s ***" % str).newline()
+ return self
+
+ def error_check(self, check, label = "error"):
+ self.has_error_check = True
+ with self.block("if (SPICE_UNLIKELY(%s))" % check):
+ if self.has_option("print_error"):
+ self.statement('printf("%%s: Caught error - %s", __PRETTY_FUNCTION__)' % check)
+ if self.has_option("assert_on_error"):
+ self.statement("assert(0)")
+ self.statement("goto %s" % label)
+
+ def indent(self):
+ self.indentation += 4
+
+ def unindent(self):
+ self.indentation -= 4
+ if self.indentation < 0:
+ self.indentation = 0
+
+ def begin_block(self, prefix= "", comment = ""):
+ if len(prefix) > 0:
+ self.write(prefix)
+ if self.at_line_start:
+ self.write("{")
+ else:
+ self.write(" {")
+ if len(comment) > 0:
+ self.write(" ")
+ self.comment(comment)
+ self.newline()
+ self.indent()
+
+ def end_block(self, semicolon=False, newline=True):
+ self.unindent()
+ if self.at_line_start:
+ self.write("}")
+ else:
+ self.write(" }")
+ if semicolon:
+ self.write(";")
+ if newline:
+ self.newline()
+
+ class Block:
+ def __init__(self, writer, semicolon, newline):
+ self.writer = writer
+ self.semicolon = semicolon
+ self.newline = newline
+
+ def __enter__(self):
+ return self.writer.get_subwriter()
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self.writer.end_block(self.semicolon, self.newline)
+
+ class PartialBlock:
+ def __init__(self, writer, scope, semicolon, newline):
+ self.writer = writer
+ self.scope = scope
+ self.semicolon = semicolon
+ self.newline = newline
+
+ def __enter__(self):
+ return self.scope
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self.writer.end_block(self.semicolon, self.newline)
+
+ class NoBlock:
+ def __init__(self, scope):
+ self.scope = scope
+
+ def __enter__(self):
+ return self.scope
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ pass
+
+ def block(self, prefix= "", comment = "", semicolon=False, newline=True):
+ self.begin_block(prefix, comment)
+ return self.Block(self, semicolon, newline)
+
+ def partial_block(self, scope, semicolon=False, newline=True):
+ return self.PartialBlock(self, scope, semicolon, newline)
+
+ def no_block(self, scope):
+ return self.NoBlock(scope)
+
+ def optional_block(self, scope):
+ if scope != None:
+ return self.NoBlock(scope)
+ return self.block()
+
+ def for_loop(self, index, limit):
+ return self.block("for (%s = 0; %s < %s; %s++)" % (index, index, limit, index))
+
+ def while_loop(self, expr):
+ return self.block("while (%s)" % (expr))
+
+ def if_block(self, check, elseif=False, newline=True):
+ s = "if (%s)" % (check)
+ if elseif:
+ s = " else " + s
+ self.begin_block(s, "")
+ return self.Block(self, False, newline)
+
+ def variable_defined(self, name):
+ for n in self.vars:
+ if n == name:
+ return True
+ return False
+
+ def variable_def(self, ctype, *names):
+ for n in names:
+ # Strip away initialization
+ i = n.find("=")
+ if i != -1:
+ n = n[0:i]
+ self.vars.append(n.strip())
+ # only add space for non-pointer types
+ if ctype[-1] == "*":
+ ctype = ctype[:-1].rstrip()
+ self.writeln("%s *%s;"%(ctype, ", *".join(names)))
+ else:
+ self.writeln("%s %s;"%(ctype, ", ".join(names)))
+ return self
+
+ def function_helper(self):
+ if self.function_helper_writer != None:
+ writer = self.function_helper_writer.get_subwriter()
+ self.function_helper_writer.newline()
+ else:
+ writer = self.get_subwriter()
+ return writer
+
+ def function(self, name, return_type, args, static = False):
+ self.has_error_check = False
+ self.function_helper_writer = self.get_subwriter()
+ if static:
+ self.write("static ")
+ self.write(return_type)
+ self.write(" %s(%s)"% (name, args)).newline()
+ self.begin_block()
+ self.function_variables_writer = self.get_subwriter()
+ self.function_variables = {}
+ return self.function_variables_writer
+
+ def macro(self, name, args, define):
+ self.write("#define %s(%s) %s" % (name, args, define)).newline()
+
+ def ifdef(self, name):
+ indentation = self.indentation
+ self.indentation = 0;
+ self.write("#ifdef %s" % (name)).newline()
+ self.indentation = indentation
+
+ def ifdef_else(self, name):
+ indentation = self.indentation
+ self.indentation = 0;
+ self.write("#else /* %s */" % (name)).newline()
+ self.indentation = indentation
+
+ def endif(self, name):
+ indentation = self.indentation
+ self.indentation = 0;
+ self.write("#endif /* %s */" % (name)).newline()
+ self.indentation = indentation
+
+ def add_function_variable(self, ctype, name):
+ if name in self.function_variables:
+ assert(self.function_variables[name] == ctype)
+ else:
+ self.function_variables[name] = ctype
+ self.function_variables_writer.variable_def(ctype, name)
+
+ def pop_index(self):
+ index = self.indexes[self.current_index]
+ self.current_index = self.current_index + 1
+ self.add_function_variable(self.index_type, index)
+ return index
+
+ def push_index(self):
+ assert self.current_index > 0
+ self.current_index = self.current_index - 1
+
+ class Index:
+ def __init__(self, writer, val):
+ self.writer = writer
+ self.val = val
+
+ def __enter__(self):
+ return self.val
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self.writer.push_index()
+
+ def index(self, no_block = False):
+ if no_block:
+ return self.no_block(None)
+ val = self.pop_index()
+ return self.Index(self, val)
--- /dev/null
+
+from . import ptypes
+from . import codegen
+
+# The handling of sizes is somewhat complex, as there are several types of size:
+# * nw_size
+# This is the network size, i.e. the number of bytes on the network
+#
+# * mem_size
+# The total amount of memory used for the representation of something inside
+# spice. This is generally sizeof(C struct), but can be larger if for instance
+# the type has a variable size array at the end or has a pointer in it that
+# points to another data chunk (which will be allocated after the main
+# data chunk). This is essentially how much memory you need to allocate to
+# contain the data type.
+#
+# * extra_size
+# This is the size of anything that is not part of the containing structure.
+# For instance, a primitive (say uint32_t) member has no extra size, because
+# when allocating its part of the sizeof(MessageStructType) struct. However
+# a variable array can be places at the end of a structure (@end) and its
+# size is then extra_size. Note that this extra_size is included in the
+# mem_size of the enclosing struct, and even if you request the mem_size
+# of the array itself. However, extra_size is typically not requested
+# when the full mem_size is also requested.
+#
+# extra sizes come in two flavours. contains_extra_size means that the item
+# has a normal presence in the parent container, but has some additional
+# extra_size it references. For instance via a pointer somewhere in it.
+# There is also is_extra_size(). This indicates that the whole elements
+# "normal" mem size should be considered extra size for the container, so
+# when computing the parent mem_size you should add the mem_size of this
+# part as extra_size
+
+def write_parser_helpers(writer):
+ if writer.is_generated("helper", "demarshaller"):
+ return
+
+ writer.set_is_generated("helper", "demarshaller")
+
+ writer = writer.function_helper()
+
+ writer.writeln("#ifdef WORDS_BIGENDIAN")
+ for size in [8, 16, 32, 64]:
+ for sign in ["", "u"]:
+ utype = "uint%d" % (size)
+ type = "%sint%d" % (sign, size)
+ swap = "SPICE_BYTESWAP%d" % size
+ if size == 8:
+ writer.macro("read_%s" % type, "ptr", "(*((%s_t *)(ptr)))" % type)
+ writer.macro("write_%s" % type, "ptr, val", "*(%s_t *)(ptr) = val" % (type))
+ else:
+ writer.macro("read_%s" % type, "ptr", "((%s_t)%s(*((%s_t *)(ptr))))" % (type, swap, utype))
+ writer.macro("write_%s" % type, "ptr, val", "*(%s_t *)(ptr) = %s((%s_t)val)" % (utype, swap, utype))
+ writer.writeln("#else")
+ for size in [8, 16, 32, 64]:
+ for sign in ["", "u"]:
+ type = "%sint%d" % (sign, size)
+ writer.macro("read_%s" % type, "ptr", "(*((%s_t *)(ptr)))" % type)
+ writer.macro("write_%s" % type, "ptr, val", "(*((%s_t *)(ptr))) = val" % type)
+ writer.writeln("#endif")
+
+ for size in [8, 16, 32, 64]:
+ for sign in ["", "u"]:
+ writer.newline()
+ type = "%sint%d" % (sign, size)
+ ctype = "%s_t" % type
+ scope = writer.function("SPICE_GNUC_UNUSED consume_%s" % type, ctype, "uint8_t **ptr", True)
+ scope.variable_def(ctype, "val")
+ writer.assign("val", "read_%s(*ptr)" % type)
+ writer.increment("*ptr", size // 8)
+ writer.statement("return val")
+ writer.end_block()
+
+ writer.function("SPICE_GNUC_UNUSED consume_fd", "int", "uint8_t **ptr", True)
+ writer.statement("return -1")
+ writer.end_block()
+
+ writer.newline()
+ writer.statement("typedef struct PointerInfo PointerInfo")
+ writer.statement("typedef void (*message_destructor_t)(uint8_t *message)")
+ writer.statement("typedef uint8_t * (*parse_func_t)(uint8_t *message_start, uint8_t *message_end, uint8_t *struct_data, PointerInfo *ptr_info, int minor)")
+ writer.statement("typedef uint8_t * (*parse_msg_func_t)(uint8_t *message_start, uint8_t *message_end, int minor, size_t *size_out, message_destructor_t *free_message)")
+ writer.statement("typedef uint8_t * (*spice_parse_channel_func_t)(uint8_t *message_start, uint8_t *message_end, uint16_t message_type, int minor, size_t *size_out, message_destructor_t *free_message)")
+
+ writer.newline()
+ writer.begin_block("struct PointerInfo")
+ writer.variable_def("uint64_t", "offset")
+ writer.variable_def("parse_func_t", "parse")
+ writer.variable_def("void **", "dest")
+ writer.variable_def("uint32_t", "nelements")
+ writer.end_block(semicolon=True)
+
+def write_read_primitive(writer, start, container, name, scope):
+ m = container.lookup_member(name)
+ assert(m.is_primitive())
+ writer.assign("pos", start + " + " + container.get_nw_offset(m, "", "__nw_size"))
+ writer.error_check("pos + %s > message_end" % m.member_type.get_fixed_nw_size())
+
+ var = "%s__value" % (name.replace(".", "_"))
+ if not scope.variable_defined(var):
+ scope.variable_def(m.member_type.c_type(), var)
+ writer.assign(var, "read_%s(pos)" % (m.member_type.primitive_type()))
+ return var
+
+def write_write_primitive(writer, start, container, name, val):
+ m = container.lookup_member(name)
+ assert(m.is_primitive())
+ writer.assign("pos", start + " + " + container.get_nw_offset(m, "", "__nw_size"))
+
+ var = "%s__value" % (name)
+ writer.statement("write_%s(pos, %s)" % (m.member_type.primitive_type(), val))
+ return var
+
+def write_read_primitive_item(writer, item, scope):
+ assert(item.type.is_primitive())
+ writer.assign("pos", item.get_position())
+ writer.error_check("pos + %s > message_end" % item.type.get_fixed_nw_size())
+ var = "%s__value" % (item.subprefix.replace(".", "_"))
+ scope.variable_def(item.type.c_type(), var)
+ writer.assign(var, "read_%s(pos)" % (item.type.primitive_type()))
+ return var
+
+class ItemInfo:
+ def __init__(self, type, prefix, position):
+ self.type = type
+ self.prefix = prefix
+ self.subprefix = prefix
+ self.position = position
+ self.member = None
+
+ def nw_size(self):
+ return self.prefix + "__nw_size"
+
+ def mem_size(self):
+ return self.prefix + "__mem_size"
+
+ def extra_size(self):
+ return self.prefix + "__extra_size"
+
+ def get_position(self):
+ return self.position
+
+class MemberItemInfo(ItemInfo):
+ def __init__(self, member, mprefix, container, start):
+ if not member.is_switch():
+ self.type = member.member_type
+ self.prefix = member.name
+ if mprefix:
+ mprefix = mprefix + "_"
+ self.prefix = mprefix + self.prefix
+ self.subprefix = member.name
+ self.position = "(%s + %s)" % (start, container.get_nw_offset(member, mprefix or "", "__nw_size"))
+ self.member = member
+
+def write_validate_switch_member(writer, mprefix, container, switch_member, scope, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size):
+ var = container.lookup_member(switch_member.variable)
+ var_type = var.member_type
+
+ v = write_read_primitive(writer, start, container, switch_member.variable, parent_scope)
+
+ item = MemberItemInfo(switch_member, mprefix, container, start)
+
+ first = True
+ for c in switch_member.cases:
+ check = c.get_check(v, var_type)
+ m = c.member
+ with writer.if_block(check, not first, False) as if_scope:
+ item.type = c.member.member_type
+ item.subprefix = item.prefix + "_" + m.name
+ item.member = c.member
+
+ all_as_extra_size = m.is_extra_size() and want_extra_size
+ if not want_mem_size and all_as_extra_size and not scope.variable_defined(item.mem_size()):
+ scope.variable_def("uint32_t", item.mem_size())
+
+ sub_want_mem_size = want_mem_size or all_as_extra_size
+ sub_want_extra_size = want_extra_size and not all_as_extra_size
+
+ write_validate_item(writer, container, item, if_scope, scope, start,
+ want_nw_size, sub_want_mem_size, sub_want_extra_size)
+
+ if all_as_extra_size:
+ writer.assign(item.extra_size(), item.mem_size())
+
+ first = False
+
+ with writer.block(" else"):
+ if want_nw_size:
+ writer.assign(item.nw_size(), 0)
+ if want_mem_size:
+ writer.assign(item.mem_size(), 0)
+ if want_extra_size:
+ writer.assign(item.extra_size(), 0)
+
+ writer.newline()
+
+def write_validate_struct_function(writer, struct):
+ validate_function = "validate_%s" % struct.c_type()
+ if writer.is_generated("validator", validate_function):
+ return validate_function
+
+ writer.set_is_generated("validator", validate_function)
+ writer = writer.function_helper()
+ scope = writer.function(validate_function, "static intptr_t", "uint8_t *message_start, uint8_t *message_end, uint64_t offset, SPICE_GNUC_UNUSED int minor")
+ scope.variable_def("uint8_t *", "start = message_start + offset")
+ scope.variable_def("SPICE_GNUC_UNUSED uint8_t *", "pos")
+ scope.variable_def("size_t", "mem_size", "nw_size")
+ num_pointers = struct.get_num_pointers()
+ if num_pointers != 0:
+ scope.variable_def("SPICE_GNUC_UNUSED intptr_t", "ptr_size")
+
+ writer.newline()
+ with writer.if_block("offset == 0"):
+ writer.statement("return 0")
+
+ writer.newline()
+ writer.error_check("start >= message_end")
+
+ writer.newline()
+ write_validate_container(writer, None, struct, "start", scope, True, True, False)
+
+ writer.newline()
+ writer.comment("Check if struct fits in reported side").newline()
+ writer.error_check("start + nw_size > message_end")
+
+ writer.statement("return mem_size")
+
+ writer.newline()
+ writer.label("error")
+ writer.statement("return -1")
+
+ writer.end_block()
+
+ return validate_function
+
+def write_validate_pointer_item(writer, container, item, scope, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size):
+ if want_nw_size:
+ writer.assign(item.nw_size(), item.type.get_fixed_nw_size())
+
+ if want_mem_size or want_extra_size:
+ target_type = item.type.target_type
+
+ v = write_read_primitive_item(writer, item, scope)
+ if item.type.has_attr("nonnull"):
+ writer.error_check("%s == 0" % v)
+
+ # pointer target is struct, or array of primitives
+ # if array, need no function check
+
+ if target_type.is_array():
+ writer.error_check("message_start + %s >= message_end" % v)
+
+
+ assert target_type.element_type.is_primitive()
+
+ array_item = ItemInfo(target_type, "%s__array" % item.prefix, start)
+ scope.variable_def("uint32_t", array_item.nw_size())
+ # don't create a variable that isn't used, fixes -Werror=unused-but-set-variable
+ need_mem_size = want_mem_size or (
+ want_extra_size and not item.member.has_attr("chunk")
+ and not target_type.is_cstring_length())
+ if need_mem_size:
+ scope.variable_def("uint32_t", array_item.mem_size())
+ if target_type.is_cstring_length():
+ writer.assign(array_item.nw_size(), "spice_strnlen((char *)message_start + %s, message_end - (message_start + %s))" % (v, v))
+ writer.error_check("*(message_start + %s + %s) != 0" % (v, array_item.nw_size()))
+ else:
+ write_validate_array_item(writer, container, array_item, scope, parent_scope, start,
+ True, want_mem_size=need_mem_size, want_extra_size=False)
+ writer.error_check("message_start + %s + %s > message_end" % (v, array_item.nw_size()))
+
+ if want_extra_size:
+ if item.member and item.member.has_attr("chunk"):
+ writer.assign(item.extra_size(), "sizeof(SpiceChunks) + sizeof(SpiceChunk)")
+ elif item.member and item.member.has_attr("nocopy"):
+ writer.comment("@nocopy, so no extra size").newline()
+ writer.assign(item.extra_size(), 0)
+ elif target_type.element_type.get_fixed_nw_size == 1:
+ writer.assign(item.extra_size(), array_item.mem_size())
+ # If not bytes or zero, add padding needed for alignment
+ else:
+ writer.assign(item.extra_size(), "%s + /* for alignment */ 3" % array_item.mem_size())
+ if want_mem_size:
+ writer.assign(item.mem_size(), "sizeof(void *) + %s" % array_item.mem_size())
+
+ elif target_type.is_struct():
+ validate_function = write_validate_struct_function(writer, target_type)
+ writer.assign("ptr_size", "%s(message_start, message_end, %s, minor)" % (validate_function, v))
+ writer.error_check("ptr_size < 0")
+
+ if want_extra_size:
+ writer.assign(item.extra_size(), "ptr_size + /* for alignment */ 3")
+ if want_mem_size:
+ writer.assign(item.mem_size(), "sizeof(void *) + ptr_size")
+ else:
+ raise NotImplementedError("pointer to unsupported type %s" % target_type)
+
+
+def write_validate_array_item(writer, container, item, scope, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size):
+ array = item.type
+ is_byte_size = False
+ element_type = array.element_type
+ if array.is_bytes_length():
+ nelements = "%s__nbytes" %(item.prefix)
+ real_nelements = "%s__nelements" %(item.prefix)
+ if not parent_scope.variable_defined(real_nelements):
+ parent_scope.variable_def("uint32_t", real_nelements)
+ else:
+ nelements = "%s__nelements" %(item.prefix)
+ if not parent_scope.variable_defined(nelements):
+ parent_scope.variable_def("uint32_t", nelements)
+
+ if array.is_constant_length():
+ writer.assign(nelements, array.size)
+ elif array.is_remaining_length():
+ if element_type.is_fixed_nw_size():
+ if element_type.get_fixed_nw_size() == 1:
+ writer.assign(nelements, "message_end - %s" % item.get_position())
+ else:
+ writer.assign(nelements, "(message_end - %s) / (%s)" %(item.get_position(), element_type.get_fixed_nw_size()))
+ else:
+ raise NotImplementedError("TODO array[] of dynamic element size not done yet")
+ elif array.is_identifier_length():
+ v = write_read_primitive(writer, start, container, array.size, scope)
+ writer.assign(nelements, v)
+ elif array.is_image_size_length():
+ bpp = array.size[1]
+ width = array.size[2]
+ rows = array.size[3]
+ width_v = write_read_primitive(writer, start, container, width, scope)
+ rows_v = write_read_primitive(writer, start, container, rows, scope)
+ # TODO: Handle multiplication overflow
+ if bpp == 8:
+ writer.assign(nelements, "%s * %s" % (width_v, rows_v))
+ elif bpp == 1:
+ writer.assign(nelements, "((%s + 7) / 8 ) * %s" % (width_v, rows_v))
+ else:
+ writer.assign(nelements, "((%s * %s + 7) / 8 ) * %s" % (bpp, width_v, rows_v))
+ elif array.is_bytes_length():
+ is_byte_size = True
+ v = write_read_primitive(writer, start, container, array.size[1], scope)
+ writer.assign(nelements, v)
+ writer.assign(real_nelements, 0)
+ elif array.is_cstring_length():
+ writer.todo("cstring array size type not handled yet")
+ else:
+ writer.todo("array size type not handled yet")
+
+ writer.newline()
+
+ nw_size = item.nw_size()
+ mem_size = item.mem_size()
+ extra_size = item.extra_size()
+
+ if is_byte_size and want_nw_size:
+ writer.assign(nw_size, nelements)
+ want_nw_size = False
+
+ if element_type.is_fixed_nw_size() and want_nw_size:
+ element_size = element_type.get_fixed_nw_size()
+ # TODO: Overflow check the multiplication
+ if element_size == 1:
+ writer.assign(nw_size, nelements)
+ else:
+ writer.assign(nw_size, "(%s) * %s" % (element_size, nelements))
+ want_nw_size = False
+
+ if array.has_attr("as_ptr") and want_mem_size:
+ writer.assign(mem_size, "sizeof(void *)")
+ want_mem_size = False
+
+ if array.has_attr("chunk"):
+ if want_mem_size:
+ writer.assign(extra_size, "sizeof(SpiceChunks *)")
+ want_mem_size = False
+ if want_extra_size:
+ writer.assign(extra_size, "sizeof(SpiceChunks) + sizeof(SpiceChunk)")
+ want_extra_size = False
+
+ if element_type.is_fixed_sizeof() and want_mem_size and not is_byte_size:
+ # TODO: Overflow check the multiplication
+ if array.has_attr("ptr_array"):
+ writer.assign(mem_size, "sizeof(void *) + SPICE_ALIGN(%s * %s, 4)" % (element_type.sizeof(), nelements))
+ else:
+ writer.assign(mem_size, "%s * %s" % (element_type.sizeof(), nelements))
+ want_mem_size = False
+
+ if not element_type.contains_extra_size() and want_extra_size:
+ writer.assign(extra_size, 0)
+ want_extra_size = False
+
+ if not (want_mem_size or want_nw_size or want_extra_size):
+ return
+
+ start2 = codegen.increment_identifier(start)
+ scope.variable_def("uint8_t *", "%s = %s" % (start2, item.get_position()))
+ if is_byte_size:
+ start2_end = "%s_array_end" % start2
+ scope.variable_def("uint8_t *", start2_end)
+
+ element_item = ItemInfo(element_type, "%s__element" % item.prefix, start2)
+
+ element_nw_size = element_item.nw_size()
+ element_mem_size = element_item.mem_size()
+ element_extra_size = element_item.extra_size()
+ scope.variable_def("uint32_t", element_nw_size)
+ scope.variable_def("uint32_t", element_mem_size)
+ if want_extra_size:
+ scope.variable_def("uint32_t", element_extra_size)
+
+ if want_nw_size:
+ writer.assign(nw_size, 0)
+ if want_mem_size:
+ writer.assign(mem_size, 0)
+ if want_extra_size:
+ writer.assign(extra_size, 0)
+
+ want_element_nw_size = want_nw_size
+ if element_type.is_fixed_nw_size():
+ start_increment = element_type.get_fixed_nw_size()
+ else:
+ want_element_nw_size = True
+ start_increment = element_nw_size
+
+ if is_byte_size:
+ writer.assign(start2_end, "%s + %s" % (start2, nelements))
+
+ with writer.index(no_block = is_byte_size) as index:
+ with writer.while_loop("%s < %s" % (start2, start2_end) ) if is_byte_size else writer.for_loop(index, nelements) as scope:
+ if is_byte_size:
+ writer.increment(real_nelements, 1)
+ write_validate_item(writer, container, element_item, scope, parent_scope, start2,
+ want_element_nw_size, want_mem_size, want_extra_size)
+
+ if want_nw_size:
+ writer.increment(nw_size, element_nw_size)
+ if want_mem_size:
+ if array.has_attr("ptr_array"):
+ writer.increment(mem_size, "sizeof(void *) + SPICE_ALIGN(%s, 4)" % element_mem_size)
+ else:
+ writer.increment(mem_size, element_mem_size)
+ if want_extra_size:
+ writer.increment(extra_size, element_extra_size)
+
+ writer.increment(start2, start_increment)
+ if is_byte_size:
+ writer.error_check("%s != %s" % (start2, start2_end))
+ write_write_primitive(writer, start, container, array.size[1], real_nelements)
+
+def write_validate_struct_item(writer, container, item, scope, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size):
+ struct = item.type
+ start2 = codegen.increment_identifier(start)
+ scope.variable_def("SPICE_GNUC_UNUSED uint8_t *", start2 + " = %s" % (item.get_position()))
+
+ write_validate_container(writer, item.prefix, struct, start2, scope, want_nw_size, want_mem_size, want_extra_size)
+
+def write_validate_primitive_item(writer, container, item, scope, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size):
+ if want_nw_size:
+ nw_size = item.nw_size()
+ writer.assign(nw_size, item.type.get_fixed_nw_size())
+ if want_mem_size:
+ mem_size = item.mem_size()
+ writer.assign(mem_size, item.type.sizeof())
+ if want_extra_size:
+ writer.assign(item.extra_size(), 0)
+
+def write_validate_item(writer, container, item, scope, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size):
+ if item.member and item.member.has_attr("to_ptr"):
+ want_nw_size = True
+ if item.type.is_pointer():
+ write_validate_pointer_item(writer, container, item, scope, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size)
+ elif item.type.is_array():
+ write_validate_array_item(writer, container, item, scope, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size)
+ elif item.type.is_struct():
+ write_validate_struct_item(writer, container, item, scope, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size)
+ elif item.type.is_primitive():
+ write_validate_primitive_item(writer, container, item, scope, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size)
+ else:
+ writer.todo("Implement validation of %s" % item.type)
+
+ if item.member and item.member.has_attr("to_ptr"):
+ saved_size = "%s__saved_size" % item.member.name
+ writer.add_function_variable("uint32_t", saved_size + " = 0")
+ writer.assign(saved_size, item.nw_size())
+
+def write_validate_member(writer, mprefix, container, member, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size):
+ if member.has_attr("virtual"):
+ return
+
+ if member.has_minor_attr():
+ prefix = "if (minor >= %s)" % (member.get_minor_attr())
+ newline = False
+ else:
+ prefix = ""
+ newline = True
+ item = MemberItemInfo(member, mprefix, container, start)
+ with writer.block(prefix, newline=newline, comment=member.name) as scope:
+ if member.is_switch():
+ write_validate_switch_member(writer, mprefix, container, member, scope, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size)
+ else:
+ write_validate_item(writer, container, item, scope, parent_scope, start,
+ want_nw_size, want_mem_size, want_extra_size)
+
+ if member.has_minor_attr():
+ with writer.block(" else", comment = "minor < %s" % (member.get_minor_attr())):
+ if member.is_array():
+ nelements = "%s__nelements" %(item.prefix)
+ writer.assign(nelements, 0)
+ if want_nw_size:
+ writer.assign(item.nw_size(), 0)
+
+ if want_mem_size:
+ if member.is_fixed_sizeof():
+ writer.assign(item.mem_size(), member.sizeof())
+ elif member.is_array():
+ writer.assign(item.mem_size(), 0)
+ else:
+ raise NotImplementedError("TODO minor check for non-constant items")
+
+ assert not want_extra_size
+
+def write_validate_container(writer, prefix, container, start, parent_scope, want_nw_size, want_mem_size, want_extra_size):
+ def prefix_m(prefix, m):
+ name = m.name
+ if prefix:
+ name = prefix + "_" + name
+ return name
+
+ for m in container.members:
+ sub_want_nw_size = want_nw_size and not m.is_fixed_nw_size()
+ sub_want_mem_size = m.is_extra_size() and want_mem_size
+ sub_want_extra_size = not m.is_extra_size() and m.contains_extra_size()
+ defs = ["size_t"]
+ name = prefix_m(prefix, m)
+ if sub_want_nw_size:
+
+ defs.append (name + "__nw_size")
+ if sub_want_mem_size:
+ defs.append (name + "__mem_size")
+ if sub_want_extra_size:
+ defs.append (name + "__extra_size")
+
+ if sub_want_nw_size or sub_want_mem_size or sub_want_extra_size:
+ parent_scope.variable_def(*defs)
+ write_validate_member(writer, prefix, container, m, parent_scope, start,
+ sub_want_nw_size, sub_want_mem_size, sub_want_extra_size)
+ writer.newline()
+
+ if want_nw_size:
+ if prefix:
+ nw_size = prefix + "__nw_size"
+ else:
+ nw_size = "nw_size"
+
+ size = 0
+ for m in container.members:
+ if m.is_fixed_nw_size():
+ size = size + m.get_fixed_nw_size()
+
+ nm_sum = str(size)
+ for m in container.members:
+ name = prefix_m(prefix, m)
+ if not m.is_fixed_nw_size():
+ nm_sum = nm_sum + " + " + name + "__nw_size"
+
+ writer.assign(nw_size, nm_sum)
+
+ if want_mem_size:
+ if prefix:
+ mem_size = prefix + "__mem_size"
+ else:
+ mem_size = "mem_size"
+
+ mem_sum = container.sizeof()
+ for m in container.members:
+ name = prefix_m(prefix, m)
+ if m.is_extra_size():
+ mem_sum = mem_sum + " + " + name + "__mem_size"
+ elif m.contains_extra_size():
+ mem_sum = mem_sum + " + " + name + "__extra_size"
+
+ writer.assign(mem_size, mem_sum)
+
+ if want_extra_size:
+ if prefix:
+ extra_size = prefix + "__extra_size"
+ else:
+ extra_size = "extra_size"
+
+ extra_sum = []
+ for m in container.members:
+ name = prefix_m(prefix, m)
+ if m.is_extra_size():
+ extra_sum.append(name + "__mem_size")
+ elif m.contains_extra_size():
+ extra_sum.append(name + "__extra_size")
+ writer.assign(extra_size, codegen.sum_array(extra_sum))
+
+class DemarshallingDestination:
+ def __init__(self):
+ pass
+
+ def child_at_end(self, writer, t):
+ return RootDemarshallingDestination(self, t.c_type(), t.sizeof())
+
+ def child_sub(self, member):
+ return SubDemarshallingDestination(self, member)
+
+ def declare(self, writer):
+ return writer.optional_block(self.reuse_scope)
+
+ def is_toplevel(self):
+ return self.parent_dest == None and not self.is_helper
+
+class RootDemarshallingDestination(DemarshallingDestination):
+ def __init__(self, parent_dest, c_type, sizeof, pointer = None):
+ self.is_helper = False
+ self.reuse_scope = None
+ self.parent_dest = parent_dest
+ if parent_dest:
+ self.base_var = codegen.increment_identifier(parent_dest.base_var)
+ else:
+ self.base_var = "out"
+ self.c_type = c_type
+ self.sizeof = sizeof
+ self.pointer = pointer # None == at "end"
+
+ def get_ref(self, member):
+ return self.base_var + "->" + member
+
+ def declare(self, writer):
+ if self.reuse_scope:
+ scope = self.reuse_scope
+ else:
+ writer.begin_block()
+ scope = writer.get_subwriter()
+
+ scope.variable_def(self.c_type + " *", self.base_var)
+ if not self.reuse_scope:
+ scope.newline()
+
+ if self.pointer:
+ writer.assign(self.base_var, "(%s *)%s" % (self.c_type, self.pointer))
+ else:
+ writer.assign(self.base_var, "(%s *)end" % (self.c_type))
+ writer.increment("end", self.sizeof)
+ writer.newline()
+
+ if self.reuse_scope:
+ return writer.no_block(self.reuse_scope)
+ else:
+ return writer.partial_block(scope)
+
+class SubDemarshallingDestination(DemarshallingDestination):
+ def __init__(self, parent_dest, member):
+ self.reuse_scope = None
+ self.parent_dest = parent_dest
+ self.base_var = parent_dest.base_var
+ self.member = member
+ self.is_helper = False
+
+ def get_ref(self, member):
+ return self.parent_dest.get_ref(self.member) + "." + member
+
+# Note: during parsing, byte_size types have been converted to count during validation
+def read_array_len(writer, prefix, array, dest, scope, is_ptr):
+ if is_ptr:
+ nelements = "%s__array__nelements" % prefix
+ else:
+ nelements = "%s__nelements" % prefix
+ if dest.is_toplevel() and scope.variable_defined(nelements):
+ return nelements # Already there for toplevel, need not recalculate
+ element_type = array.element_type
+ scope.variable_def("uint32_t", nelements)
+ if array.is_constant_length():
+ writer.assign(nelements, array.size)
+ elif array.is_identifier_length():
+ writer.assign(nelements, dest.get_ref(array.size))
+ elif array.is_remaining_length():
+ if element_type.is_fixed_nw_size():
+ writer.assign(nelements, "(message_end - in) / (%s)" %(element_type.get_fixed_nw_size()))
+ else:
+ raise NotImplementedError("TODO array[] of dynamic element size not done yet")
+ elif array.is_image_size_length():
+ bpp = array.size[1]
+ width = array.size[2]
+ rows = array.size[3]
+ width_v = dest.get_ref(width)
+ rows_v = dest.get_ref(rows)
+ # TODO: Handle multiplication overflow
+ if bpp == 8:
+ writer.assign(nelements, "%s * %s" % (width_v, rows_v))
+ elif bpp == 1:
+ writer.assign(nelements, "((%s + 7) / 8 ) * %s" % (width_v, rows_v))
+ else:
+ writer.assign(nelements, "((%s * %s + 7) / 8 ) * %s" % (bpp, width_v, rows_v))
+ elif array.is_bytes_length():
+ writer.assign(nelements, dest.get_ref(array.size[2]))
+ else:
+ raise NotImplementedError("TODO array size type not handled yet")
+ return nelements
+
+def write_switch_parser(writer, container, switch, dest, scope):
+ var = container.lookup_member(switch.variable)
+ var_type = var.member_type
+
+ if switch.has_attr("fixedsize"):
+ scope.variable_def("uint8_t *", "in_save")
+ writer.assign("in_save", "in")
+
+ first = True
+ for c in switch.cases:
+ check = c.get_check(dest.get_ref(switch.variable), var_type)
+ m = c.member
+ with writer.if_block(check, not first, False) as block:
+ t = m.member_type
+ if switch.has_end_attr():
+ dest2 = dest.child_at_end(writer, m.member_type)
+ elif switch.has_attr("anon"):
+ if t.is_struct() and not m.has_attr("to_ptr"):
+ dest2 = dest.child_sub(m.name)
+ else:
+ dest2 = dest
+ else:
+ if t.is_struct():
+ dest2 = dest.child_sub(switch.name + "." + m.name)
+ else:
+ dest2 = dest.child_sub(switch.name)
+ dest2.reuse_scope = block
+
+ if m.has_attr("to_ptr"):
+ write_parse_to_pointer(writer, t, False, dest2, m.name, block)
+ elif t.is_pointer():
+ write_parse_pointer(writer, t, False, dest2, m.name, block)
+ elif t.is_struct():
+ write_container_parser(writer, t, dest2)
+ elif t.is_primitive():
+ if m.has_attr("zero"):
+ writer.statement("consume_%s(&in)" % (t.primitive_type()))
+ else:
+ writer.assign(dest2.get_ref(m.name), "consume_%s(&in)" % (t.primitive_type()))
+ #TODO validate e.g. flags and enums
+ elif t.is_array():
+ nelements = read_array_len(writer, m.name, t, dest, block, False)
+ write_array_parser(writer, m, nelements, t, dest2, block)
+ else:
+ writer.todo("Can't handle type %s" % m.member_type)
+
+ first = False
+
+ writer.newline()
+
+ if switch.has_attr("fixedsize"):
+ writer.assign("in", "in_save + %s" % switch.get_fixed_nw_size())
+
+def write_parse_ptr_function(writer, target_type):
+ if target_type.is_array():
+ parse_function = "parse_array_%s" % target_type.element_type.primitive_type()
+ else:
+ parse_function = "parse_struct_%s" % target_type.c_type()
+ if writer.is_generated("parser", parse_function):
+ return parse_function
+
+ writer.set_is_generated("parser", parse_function)
+
+ writer = writer.function_helper()
+ scope = writer.function(parse_function, "static uint8_t *", "uint8_t *message_start, SPICE_GNUC_UNUSED uint8_t *message_end, uint8_t *struct_data, PointerInfo *this_ptr_info, SPICE_GNUC_UNUSED int minor")
+ scope.variable_def("uint8_t *", "in = message_start + this_ptr_info->offset")
+ scope.variable_def("uint8_t *", "end")
+
+ num_pointers = target_type.get_num_pointers()
+ if num_pointers != 0:
+ scope.variable_def("SPICE_GNUC_UNUSED intptr_t", "ptr_size")
+ scope.variable_def("uint32_t", "n_ptr=0")
+ scope.variable_def("PointerInfo", "ptr_info[%s]" % num_pointers)
+
+ writer.newline()
+ if target_type.is_array():
+ writer.assign("end", "struct_data")
+ else:
+ writer.assign("end", "struct_data + %s" % (target_type.sizeof()))
+
+ dest = RootDemarshallingDestination(None, target_type.c_type(), target_type.sizeof(), "struct_data")
+ dest.is_helper = True
+ dest.reuse_scope = scope
+ if target_type.is_array():
+ write_array_parser(writer, None, "this_ptr_info->nelements", target_type, dest, scope)
+ else:
+ write_container_parser(writer, target_type, dest)
+
+ if num_pointers != 0:
+ write_ptr_info_check(writer)
+
+ writer.statement("return end")
+
+ if writer.has_error_check:
+ writer.newline()
+ writer.label("error")
+ writer.statement("return NULL")
+
+ writer.end_block()
+
+ return parse_function
+
+def write_array_parser(writer, member, nelements, array, dest, scope):
+ is_byte_size = array.is_bytes_length()
+
+ element_type = array.element_type
+ if member:
+ array_start = dest.get_ref(member.name)
+ at_end = member.has_attr("end")
+ else:
+ array_start = "end"
+ at_end = True
+
+ if element_type == ptypes.uint8 or element_type == ptypes.int8:
+ writer.statement("memcpy(%s, in, %s)" % (array_start, nelements))
+ writer.increment("in", nelements)
+ if at_end:
+ writer.increment("end", nelements)
+ else:
+ with writer.index() as index:
+ if member:
+ array_pos = "%s[%s]" % (array_start, index)
+ else:
+ array_pos = "*(%s *)end" % (element_type.c_type())
+
+ if array.has_attr("ptr_array"):
+ scope.variable_def("void **", "ptr_array")
+ scope.variable_def("int", "ptr_array_index")
+ writer.assign("ptr_array_index", 0)
+ writer.assign("ptr_array", "(void **)%s" % array_start)
+ writer.increment("end", "sizeof(void *) * %s" % nelements)
+ array_start = "end"
+ array_pos = "*(%s *)end" % (element_type.c_type())
+ at_end = True
+
+ with writer.for_loop(index, nelements) as array_scope:
+ if array.has_attr("ptr_array"):
+ writer.statement("ptr_array[ptr_array_index++] = end")
+ if element_type.is_primitive():
+ writer.statement("%s = consume_%s(&in)" % (array_pos, element_type.primitive_type()))
+ if at_end:
+ writer.increment("end", element_type.sizeof())
+ else:
+ if at_end:
+ dest2 = dest.child_at_end(writer, element_type)
+ else:
+ dest2 = RootDemarshallingDestination(dest, element_type.c_type(), element_type.c_type(), array_pos)
+ dest2.reuse_scope = array_scope
+ write_container_parser(writer, element_type, dest2)
+ if array.has_attr("ptr_array"):
+ writer.comment("Align ptr_array element to 4 bytes").newline()
+ writer.assign("end", "(uint8_t *)SPICE_ALIGN((size_t)end, 4)")
+
+def write_parse_pointer_core(writer, target_type, offset, at_end, dest, member_name, scope):
+ writer.assign("ptr_info[n_ptr].offset", offset)
+ writer.assign("ptr_info[n_ptr].parse", write_parse_ptr_function(writer, target_type))
+ if at_end:
+ writer.assign("ptr_info[n_ptr].dest", "(void **)end")
+ writer.increment("end", "sizeof(void *)")
+ else:
+ writer.assign("ptr_info[n_ptr].dest", "(void **)&%s" % dest.get_ref(member_name))
+ if target_type.is_array():
+ nelements = read_array_len(writer, member_name, target_type, dest, scope, True)
+ writer.assign("ptr_info[n_ptr].nelements", nelements)
+
+ writer.statement("n_ptr++")
+
+def write_parse_pointer(writer, t, at_end, dest, member_name, scope):
+ write_parse_pointer_core(writer, t.target_type, "consume_%s(&in)" % t.primitive_type(),
+ at_end, dest, member_name, scope)
+
+def write_parse_to_pointer(writer, t, at_end, dest, member_name, scope):
+ write_parse_pointer_core(writer, t, "in - start",
+ at_end, dest, member_name, scope)
+ writer.increment("in", "%s__saved_size" % member_name)
+
+def write_member_parser(writer, container, member, dest, scope):
+ if member.has_attr("virtual"):
+ writer.assign(dest.get_ref(member.name), member.attributes["virtual"][0])
+ return
+
+ if member.is_switch():
+ write_switch_parser(writer, container, member, dest, scope)
+ return
+
+ t = member.member_type
+
+ if member.has_attr("to_ptr"):
+ write_parse_to_pointer(writer, t, member.has_end_attr(), dest, member.name, scope)
+ elif t.is_pointer():
+ if member.has_attr("chunk"):
+ assert(t.target_type.is_array())
+ nelements = read_array_len(writer, member.name, t.target_type, dest, scope, True)
+ writer.comment("Reuse data from network message as chunk").newline()
+ scope.variable_def("SpiceChunks *", "chunks")
+ writer.assign("chunks", "(SpiceChunks *)end")
+ writer.increment("end", "sizeof(SpiceChunks) + sizeof(SpiceChunk)")
+ writer.assign(dest.get_ref(member.name), "chunks")
+ writer.assign("chunks->data_size", nelements)
+ writer.assign("chunks->flags", 0)
+ writer.assign("chunks->num_chunks", 1)
+ writer.assign("chunks->chunk[0].len", nelements)
+ writer.assign("chunks->chunk[0].data", "message_start + consume_%s(&in)" % t.primitive_type())
+ elif member.has_attr("nocopy"):
+ writer.comment("Reuse data from network message").newline()
+ writer.assign(dest.get_ref(member.name), "(size_t)(message_start + consume_%s(&in))" % t.primitive_type())
+ else:
+ write_parse_pointer(writer, t, member.has_end_attr(), dest, member.name, scope)
+ elif t.is_primitive():
+ if member.has_attr("zero"):
+ writer.statement("consume_%s(&in)" % t.primitive_type())
+ elif member.has_end_attr():
+ writer.statement("*(%s *)end = consume_%s(&in)" % (t.c_type(), t.primitive_type()))
+ writer.increment("end", t.sizeof())
+ else:
+ if member.has_attr("bytes_count"):
+ dest_var = dest.get_ref(member.attributes["bytes_count"][0])
+ else:
+ dest_var = dest.get_ref(member.name)
+ writer.assign(dest_var, "consume_%s(&in)" % (t.primitive_type()))
+ #TODO validate e.g. flags and enums
+ elif t.is_array():
+ nelements = read_array_len(writer, member.name, t, dest, scope, False)
+ if member.has_attr("chunk") and t.element_type.is_fixed_nw_size() and t.element_type.get_fixed_nw_size() == 1:
+ writer.comment("use array as chunk").newline()
+
+ scope.variable_def("SpiceChunks *", "chunks")
+ writer.assign("chunks", "(SpiceChunks *)end")
+ writer.increment("end", "sizeof(SpiceChunks) + sizeof(SpiceChunk)")
+ writer.assign(dest.get_ref(member.name), "chunks")
+ writer.assign("chunks->data_size", nelements)
+ writer.assign("chunks->flags", 0)
+ writer.assign("chunks->num_chunks", 1)
+ writer.assign("chunks->chunk[0].len", nelements)
+ writer.assign("chunks->chunk[0].data", "in")
+ writer.increment("in", "%s" % (nelements))
+ elif member.has_attr("as_ptr") and t.element_type.is_fixed_nw_size():
+ writer.comment("use array as pointer").newline()
+ writer.assign(dest.get_ref(member.name), "(%s *)in" % t.element_type.c_type())
+ len_var = member.attributes["as_ptr"]
+ if len(len_var) > 0:
+ writer.assign(dest.get_ref(len_var[0]), nelements)
+ el_size = t.element_type.get_fixed_nw_size()
+ if el_size != 1:
+ writer.increment("in", "%s * %s" % (nelements, el_size))
+ else:
+ writer.increment("in", "%s" % (nelements))
+ else:
+ write_array_parser(writer, member, nelements, t, dest, scope)
+ elif t.is_struct():
+ if member.has_end_attr():
+ dest2 = dest.child_at_end(writer, t)
+ else:
+ dest2 = dest.child_sub(member.name)
+ writer.comment(member.name)
+ write_container_parser(writer, t, dest2)
+ else:
+ raise NotImplementedError("TODO can't handle parsing of %s" % t)
+
+def write_container_parser(writer, container, dest):
+ with dest.declare(writer) as scope:
+ for m in container.members:
+ if m.has_minor_attr():
+ writer.begin_block("if (minor >= %s)" % m.get_minor_attr())
+ write_member_parser(writer, container, m, dest, scope)
+ if m.has_minor_attr():
+ # We need to zero out the fixed part of all optional fields
+ if not m.member_type.is_array():
+ writer.end_block(newline=False)
+ writer.begin_block(" else")
+ # TODO: This is not right for fields that don't exist in the struct
+ if m.has_attr("zero"):
+ pass
+ elif m.member_type.is_primitive():
+ writer.assign(dest.get_ref(m.name), "0")
+ elif m.is_fixed_sizeof():
+ writer.statement("memset ((char *)&%s, 0, %s)" % (dest.get_ref(m.name), m.sizeof()))
+ else:
+ raise NotImplementedError("TODO Clear optional dynamic fields")
+ writer.end_block()
+
+def write_ptr_info_check(writer):
+ writer.newline()
+ with writer.index() as index:
+ with writer.for_loop(index, "n_ptr") as scope:
+ offset = "ptr_info[%s].offset" % index
+ function = "ptr_info[%s].parse" % index
+ dest = "ptr_info[%s].dest" % index
+ with writer.if_block("%s == 0" % offset, newline=False):
+ writer.assign("*%s" % dest, "NULL")
+ with writer.block(" else"):
+ writer.comment("Align to 32 bit").newline()
+ writer.assign("end", "(uint8_t *)SPICE_ALIGN((size_t)end, 4)")
+ writer.assign("*%s" % dest, "(void *)end")
+ writer.assign("end", "%s(message_start, message_end, end, &ptr_info[%s], minor)" % (function, index))
+ writer.error_check("end == NULL")
+ writer.newline()
+
+def write_nofree(writer):
+ if writer.is_generated("helper", "nofree"):
+ return
+ writer = writer.function_helper()
+ scope = writer.function("nofree", "static void", "SPICE_GNUC_UNUSED uint8_t *data")
+ writer.end_block()
+
+def write_msg_parser(writer, message):
+ msg_name = message.c_name()
+ function_name = "parse_%s" % msg_name
+ if writer.is_generated("demarshaller", function_name):
+ return function_name
+ writer.set_is_generated("demarshaller", function_name)
+
+ msg_type = message.c_type()
+ msg_sizeof = message.sizeof()
+
+ want_mem_size = (len(message.members) != 1 or message.members[0].is_fixed_nw_size()
+ or not message.members[0].is_array())
+
+ writer.newline()
+ if message.has_attr("ifdef"):
+ writer.ifdef(message.attributes["ifdef"][0])
+ parent_scope = writer.function(function_name,
+ "uint8_t *",
+ "uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message", True)
+ parent_scope.variable_def("SPICE_GNUC_UNUSED uint8_t *", "pos")
+ parent_scope.variable_def("uint8_t *", "start = message_start")
+ parent_scope.variable_def("uint8_t *", "data = NULL")
+ parent_scope.variable_def("size_t", "nw_size")
+ if want_mem_size:
+ parent_scope.variable_def("size_t", "mem_size")
+ if not message.has_attr("nocopy"):
+ parent_scope.variable_def("uint8_t *", "in", "end")
+ num_pointers = message.get_num_pointers()
+ if num_pointers != 0:
+ parent_scope.variable_def("SPICE_GNUC_UNUSED intptr_t", "ptr_size")
+ parent_scope.variable_def("uint32_t", "n_ptr=0")
+ parent_scope.variable_def("PointerInfo", "ptr_info[%s]" % num_pointers)
+ writer.newline()
+
+ write_parser_helpers(writer)
+
+ write_validate_container(writer, None, message, "start", parent_scope, True,
+ want_mem_size=want_mem_size, want_extra_size=False)
+
+ writer.newline()
+
+ writer.comment("Check if message fits in reported side").newline()
+ with writer.block("if (start + nw_size > message_end)"):
+ writer.statement("return NULL")
+
+ writer.newline().comment("Validated extents and calculated size").newline()
+
+ if message.has_attr("nocopy"):
+ write_nofree(writer)
+ writer.assign("data", "message_start")
+ writer.assign("*size", "message_end - message_start")
+ writer.assign("*free_message", "nofree")
+ else:
+ writer.assign("data", "(uint8_t *)malloc(mem_size)")
+ writer.error_check("data == NULL")
+ writer.assign("end", "data + %s" % (msg_sizeof))
+ writer.assign("in", "start").newline()
+
+ # avoid defined and assigned but not used warnings of gcc 4.6.0+
+ if message.is_extra_size() or not message.is_fixed_nw_size() or message.get_fixed_nw_size() > 0:
+ dest = RootDemarshallingDestination(None, msg_type, msg_sizeof, "data")
+ dest.reuse_scope = parent_scope
+ write_container_parser(writer, message, dest)
+
+ writer.newline()
+ writer.statement("assert(in <= message_end)")
+
+ if num_pointers != 0:
+ write_ptr_info_check(writer)
+
+ writer.statement("assert(end <= data + mem_size)")
+
+ writer.newline()
+ writer.assign("*size", "end - data")
+ writer.assign("*free_message", "(message_destructor_t) free")
+
+ writer.statement("return data")
+ writer.newline()
+ if writer.has_error_check:
+ writer.label("error")
+ with writer.block("if (data != NULL)"):
+ writer.statement("free(data)")
+ writer.statement("return NULL")
+ writer.end_block()
+
+ if message.has_attr("ifdef"):
+ writer.endif(message.attributes["ifdef"][0])
+
+ return function_name
+
+def write_channel_parser(writer, channel, server):
+ writer.newline()
+ ids = {}
+ min_id = 1000000
+ if server:
+ messages = channel.server_messages
+ else:
+ messages = channel.client_messages
+ for m in messages:
+ ids[m.value] = m
+
+ ranges = []
+ ids2 = ids.copy()
+ while len(ids2) > 0:
+ end = start = min(ids2.keys())
+ while end in ids2:
+ del ids2[end]
+ end = end + 1
+
+ ranges.append( (start, end) )
+
+ if server:
+ function_name = "parse_%s_msg" % channel.name
+ else:
+ function_name = "parse_%s_msgc" % channel.name
+ writer.newline()
+ if channel.has_attr("ifdef"):
+ writer.ifdef(channel.attributes["ifdef"][0])
+ scope = writer.function(function_name,
+ "static uint8_t *",
+ "uint8_t *message_start, uint8_t *message_end, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message")
+
+ helpers = writer.function_helper()
+
+ d = 0
+ for r in ranges:
+ d = d + 1
+ writer.write("static parse_msg_func_t funcs%d[%d] = " % (d, r[1] - r[0]))
+ writer.begin_block()
+ for i in range(r[0], r[1]):
+ func = write_msg_parser(helpers, ids[i].message_type)
+ writer.write(func)
+ if i != r[1] -1:
+ writer.write(",")
+ writer.newline()
+
+ writer.end_block(semicolon = True)
+
+ d = 0
+ for r in ranges:
+ d = d + 1
+ with writer.if_block("message_type >= %d && message_type < %d" % (r[0], r[1]), d > 1, False):
+ writer.statement("return funcs%d[message_type-%d](message_start, message_end, minor, size_out, free_message)" % (d, r[0]))
+ writer.newline()
+
+ writer.statement("return NULL")
+ writer.end_block()
+ if channel.has_attr("ifdef"):
+ writer.endif(channel.attributes["ifdef"][0])
+
+ return function_name
+
+def write_get_channel_parser(writer, channel_parsers, max_channel, is_server):
+ writer.newline()
+ if is_server:
+ function_name = "spice_get_server_channel_parser" + writer.public_prefix
+ else:
+ function_name = "spice_get_client_channel_parser" + writer.public_prefix
+
+ scope = writer.function(function_name,
+ "spice_parse_channel_func_t",
+ "uint32_t channel, unsigned int *max_message_type")
+
+ writer.write("static struct {spice_parse_channel_func_t func; unsigned int max_messages; } channels[%d] = " % (max_channel+1))
+ writer.begin_block()
+ channel = None
+ for i in range(0, max_channel + 1):
+ if i in channel_parsers:
+ channel = channel_parsers[i][0]
+ if channel.has_attr("ifdef"):
+ writer.ifdef(channel.attributes["ifdef"][0])
+ writer.write("{ ")
+ writer.write(channel_parsers[i][1])
+ writer.write(", ")
+
+ max_msg = 0
+ if is_server:
+ messages = channel.server_messages
+ else:
+ messages = channel.client_messages
+ for m in messages:
+ max_msg = max(max_msg, m.value)
+ writer.write(max_msg)
+ writer.write("}")
+ else:
+ writer.write("{ NULL, 0 }")
+
+ if i != max_channel:
+ writer.write(",")
+ writer.newline()
+ if channel and channel.has_attr("ifdef"):
+ writer.ifdef_else(channel.attributes["ifdef"][0])
+ writer.write("{ NULL, 0 }")
+ if i != max_channel:
+ writer.write(",")
+ writer.newline()
+ writer.endif(channel.attributes["ifdef"][0])
+ writer.end_block(semicolon = True)
+
+ with writer.if_block("channel < %d" % (max_channel + 1)):
+ with writer.if_block("max_message_type != NULL"):
+ writer.assign("*max_message_type", "channels[channel].max_messages")
+ writer.statement("return channels[channel].func")
+
+ writer.statement("return NULL")
+ writer.end_block()
+
+
+def write_full_protocol_parser(writer, is_server):
+ writer.newline()
+ if is_server:
+ function_name = "spice_parse_msg"
+ else:
+ function_name = "spice_parse_reply"
+ scope = writer.function(function_name + writer.public_prefix,
+ "uint8_t *",
+ "uint8_t *message_start, uint8_t *message_end, uint32_t channel, uint16_t message_type, SPICE_GNUC_UNUSED int minor, size_t *size_out, message_destructor_t *free_message")
+ scope.variable_def("spice_parse_channel_func_t", "func" )
+
+ if is_server:
+ writer.assign("func", "spice_get_server_channel_parser%s(channel, NULL)" % writer.public_prefix)
+ else:
+ writer.assign("func", "spice_get_client_channel_parser%s(channel, NULL)" % writer.public_prefix)
+
+ with writer.if_block("func != NULL"):
+ writer.statement("return func(message_start, message_end, message_type, minor, size_out, free_message)")
+
+ writer.statement("return NULL")
+ writer.end_block()
+
+def write_protocol_parser(writer, proto, is_server):
+ max_channel = 0
+ parsers = {}
+
+ for channel in proto.channels:
+ max_channel = max(max_channel, channel.value)
+
+ parsers[channel.value] = (channel.channel_type, write_channel_parser(writer, channel.channel_type, is_server))
+
+ write_get_channel_parser(writer, parsers, max_channel, is_server)
+ write_full_protocol_parser(writer, is_server)
+
+def write_includes(writer):
+ writer.writeln("#include <string.h>")
+ writer.writeln("#include <assert.h>")
+ writer.writeln("#include <stdlib.h>")
+ writer.writeln("#include <stdio.h>")
+ writer.writeln("#include <spice/protocol.h>")
+ writer.writeln("#include <spice/macros.h>")
+ writer.writeln('#include <common/mem.h>')
+ writer.newline()
+ writer.writeln("#ifdef _MSC_VER")
+ writer.writeln("#pragma warning(disable:4101)")
+ writer.writeln("#endif")
--- /dev/null
+
+from . import ptypes
+from . import codegen
+import re
+
+def write_includes(writer):
+ writer.header.writeln("#include <spice/protocol.h>")
+ writer.header.writeln('#include "common/marshaller.h"')
+ writer.header.newline()
+ if writer.header.has_option("dest_file"):
+ src = writer.header.options["dest_file"]
+ else:
+ src = "generated_headers.h"
+ src = re.sub(r'[^a-z0-9]+', '_', src, flags=re.IGNORECASE)
+ src = src.upper()
+ if src.endswith("_H"):
+ src = "_H_"+src[:-2]
+ writer.header.writeln("#ifndef %s" % src)
+ writer.header.writeln("#define %s" % src)
+ writer.header.newline()
+ writer.header.writeln("SPICE_BEGIN_DECLS")
+ writer.header.newline()
+
+ writer.writeln("#include <string.h>")
+ writer.writeln("#include <assert.h>")
+ writer.writeln("#include <stdlib.h>")
+ writer.writeln("#include <stdio.h>")
+ writer.writeln("#include <spice/protocol.h>")
+ writer.writeln("#include <spice/macros.h>")
+ writer.writeln('#include "common/marshaller.h"')
+ writer.newline()
+ writer.writeln("#ifdef _MSC_VER")
+ writer.writeln("#pragma warning(disable:4101)")
+ writer.writeln("#pragma warning(disable:4018)")
+ writer.writeln("#endif")
+ writer.newline()
+
+class MarshallingSource:
+ def __init__(self):
+ pass
+
+ def child_at_end(self, t):
+ return RootMarshallingSource(self, t.c_type(), t.sizeof())
+
+ def child_sub(self, containee):
+ return SubMarshallingSource(self, containee)
+
+ def declare(self, writer):
+ return writer.optional_block(self.reuse_scope)
+
+ def is_toplevel(self):
+ return self.parent_src == None and not self.is_helper
+
+class RootMarshallingSource(MarshallingSource):
+ def __init__(self, parent_src, c_type, sizeof, pointer = None):
+ self.is_helper = False
+ self.reuse_scope = None
+ self.parent_src = parent_src
+ if parent_src:
+ self.base_var = codegen.increment_identifier(parent_src.base_var)
+ else:
+ self.base_var = "src"
+ self.c_type = c_type
+ self.sizeof = sizeof
+ self.pointer = pointer
+ assert pointer != None
+
+ def get_self_ref(self):
+ return self.base_var
+
+ def get_ref(self, member):
+ return self.base_var + "->" + member
+
+ def declare(self, writer):
+ if self.reuse_scope:
+ scope = self.reuse_scope
+ else:
+ writer.begin_block()
+ scope = writer.get_subwriter()
+
+ scope.variable_def(self.c_type + " *", self.base_var)
+ if not self.reuse_scope:
+ scope.newline()
+
+ writer.assign(self.base_var, "(%s *)%s" % (self.c_type, self.pointer))
+ writer.newline()
+
+ if self.reuse_scope:
+ return writer.no_block(self.reuse_scope)
+ else:
+ return writer.partial_block(scope)
+
+class SubMarshallingSource(MarshallingSource):
+ def __init__(self, parent_src, containee):
+ self.reuse_scope = None
+ self.parent_src = parent_src
+ self.base_var = parent_src.base_var
+ self.containee = containee
+ self.name = containee.name
+ self.is_helper = False
+
+ def get_self_ref(self):
+ if self.containee.has_attr("to_ptr"):
+ return "%s" % self.parent_src.get_ref(self.name)
+ else:
+ return "&%s" % self.parent_src.get_ref(self.name)
+
+ def get_ref(self, member):
+ if self.containee.has_attr("to_ptr"):
+ return self.parent_src.get_ref(self.name) + "->" + member
+ else:
+ return self.parent_src.get_ref(self.name) + "." + member
+
+def write_marshal_ptr_function(writer, target_type, is_helper=True):
+ if target_type.is_array():
+ marshal_function = "spice_marshall_array_%s" % target_type.element_type.primitive_type()
+ else:
+ marshal_function = "spice_marshall_%s" % target_type.name
+ if writer.is_generated("marshaller", marshal_function):
+ return marshal_function
+
+ writer.set_is_generated("marshaller", marshal_function)
+
+ names = target_type.get_pointer_names(False)
+ names_args = ""
+ if len(names) > 0:
+ n = [", SpiceMarshaller **%s_out" % name for name in names]
+ names_args = "".join(n)
+
+ header = writer.header
+ if is_helper:
+ writer = writer.function_helper()
+ writer.header = header
+ writer.out_prefix = ""
+ if target_type.is_array():
+ scope = writer.function(marshal_function, "SPICE_GNUC_UNUSED static void", "SpiceMarshaller *m, %s_t *ptr, unsigned count" % target_type.element_type.primitive_type() + names_args)
+ else:
+ scope = writer.function(marshal_function, "void", "SpiceMarshaller *m, %s *ptr" % target_type.c_type() + names_args)
+ header.writeln("void " + marshal_function + "(SpiceMarshaller *m, %s *msg" % target_type.c_type() + names_args + ");")
+ scope.variable_def("SPICE_GNUC_UNUSED SpiceMarshaller *", "m2")
+
+ for n in names:
+ writer.assign("*%s_out" % n, "NULL")
+
+ writer.newline()
+
+ if target_type.is_struct():
+ src = RootMarshallingSource(None, target_type.c_type(), target_type.sizeof(), "ptr")
+ src.reuse_scope = scope
+ write_container_marshaller(writer, target_type, src)
+ elif target_type.is_array() and target_type.element_type.is_primitive():
+ with writer.index() as index:
+ with writer.for_loop(index, "count") as array_scope:
+ writer.statement("spice_marshaller_add_%s(m, *ptr++)" % (target_type.element_type.primitive_type()))
+ else:
+ writer.todo("Unsuppored pointer marshaller type")
+
+ writer.end_block()
+
+ return marshal_function
+
+def get_array_size(array, container_src):
+ if array.is_constant_length():
+ return array.size
+ elif array.is_identifier_length():
+ return container_src.get_ref(array.size)
+ elif array.is_remaining_length():
+ raise NotImplementedError("remaining size array sizes marshalling not supported")
+ elif array.is_image_size_length():
+ bpp = array.size[1]
+ width = array.size[2]
+ rows = array.size[3]
+ width_v = container_src.get_ref(width)
+ rows_v = container_src.get_ref(rows)
+ # TODO: Handle multiplication overflow
+ if bpp == 8:
+ return "(unsigned) (%s * %s)" % (width_v, rows_v)
+ elif bpp == 1:
+ return "(unsigned) (((%s + 7) / 8 ) * %s)" % (width_v, rows_v)
+ else:
+ return "(unsigned) (((%s * %s + 7) / 8 ) * %s)" % (bpp, width_v, rows_v)
+ elif array.is_bytes_length():
+ return container_src.get_ref(array.size[2])
+ else:
+ raise NotImplementedError("TODO array size type not handled yet: %s" % array)
+
+def write_array_marshaller(writer, member, array, container_src, scope):
+ element_type = array.element_type
+
+ if array.is_remaining_length():
+ writer.comment("Remaining data must be appended manually").newline()
+ return
+
+ nelements = get_array_size(array, container_src)
+ is_byte_size = array.is_bytes_length()
+
+ element = "%s__element" % member.name
+
+ if not scope.variable_defined(element):
+ if array.has_attr("ptr_array"):
+ stars = " **"
+ else:
+ stars = " *"
+ scope.variable_def(element_type.c_type() + stars, element)
+ element_array = element
+ if array.has_attr("ptr_array"):
+ element = "*" + element
+
+ writer.assign(element_array, container_src.get_ref(member.name))
+
+ if is_byte_size:
+ size_start_var = "%s__size_start" % member.name
+ scope.variable_def("size_t", size_start_var)
+ writer.assign(size_start_var, "spice_marshaller_get_size(m)")
+
+ with writer.index() as index:
+ with writer.for_loop(index, nelements) as array_scope:
+ if element_type.is_primitive():
+ writer.statement("spice_marshaller_add_%s(m, *%s)" % (element_type.primitive_type(), element))
+ elif element_type.is_struct():
+ src2 = RootMarshallingSource(container_src, element_type.c_type(), element_type.sizeof(), element)
+ src2.reuse_scope = array_scope
+ write_container_marshaller(writer, element_type, src2)
+ else:
+ writer.todo("array element unhandled type").newline()
+
+ writer.statement("%s++" % element_array)
+
+ if is_byte_size:
+ size_var = member.container.lookup_member(array.size[1])
+ size_var_type = size_var.member_type
+ var = "%s__ref" % array.size[1]
+ writer.statement("spice_marshaller_set_%s(m, %s, spice_marshaller_get_size(m) - %s)" % (size_var_type.primitive_type(), var, size_start_var))
+
+def write_pointer_marshaller(writer, member, src):
+ t = member.member_type
+ ptr_func = write_marshal_ptr_function(writer, t.target_type)
+ submarshaller = "spice_marshaller_get_ptr_submarshaller(m, %d)" % (1 if member.get_fixed_nw_size() == 8 else 0)
+ if member.has_attr("marshall"):
+ rest_args = ""
+ if t.target_type.is_array():
+ rest_args = ", %s" % get_array_size(t.target_type, src)
+ writer.assign("m2", submarshaller)
+ if t.has_attr("nonnull"):
+ writer.statement("%s(m2, %s%s)" % (ptr_func, src.get_ref(member.name), rest_args))
+ else:
+ with writer.if_block("%s != NULL" % src.get_ref(member.name)) as block:
+ writer.statement("%s(m2, %s%s)" % (ptr_func, src.get_ref(member.name), rest_args))
+ else:
+ writer.assign("*%s_out" % (writer.out_prefix + member.name), submarshaller)
+
+def write_switch_marshaller(writer, container, switch, src, scope):
+ var = container.lookup_member(switch.variable)
+ var_type = var.member_type
+
+ saved_out_prefix = writer.out_prefix
+ first = True
+ for c in switch.cases:
+ check = c.get_check(src.get_ref(switch.variable), var_type)
+ m = c.member
+ writer.out_prefix = saved_out_prefix
+ if m.has_attr("outvar"):
+ writer.out_prefix = "%s_%s" % (m.attributes["outvar"][0], writer.out_prefix)
+ with writer.if_block(check, not first, False) as block:
+ t = m.member_type
+ if switch.has_attr("anon"):
+ if t.is_struct():
+ src2 = src.child_sub(m)
+ else:
+ src2 = src
+ else:
+ if t.is_struct():
+ src2 = src.child_sub(switch).child_sub(m)
+ else:
+ src2 = src.child_sub(switch)
+ src2.reuse_scope = block
+
+ if t.is_struct():
+ write_container_marshaller(writer, t, src2)
+ elif t.is_pointer():
+ write_pointer_marshaller(writer, m, src2)
+ elif t.is_primitive():
+ if m.has_attr("zero"):
+ writer.statement("spice_marshaller_add_%s(m, 0)" % (t.primitive_type()))
+ else:
+ writer.statement("spice_marshaller_add_%s(m, %s)" % (t.primitive_type(), src2.get_ref(m.name)))
+ #TODO validate e.g. flags and enums
+ elif t.is_array():
+ write_array_marshaller(writer, m, t, src2, scope)
+ else:
+ writer.todo("Can't handle type %s" % m.member_type)
+
+ if switch.has_attr("fixedsize"):
+ remaining = switch.get_fixed_nw_size() - t.get_fixed_nw_size()
+ if remaining != 0:
+ writer.statement("spice_marshaller_reserve_space(m, %s)" % remaining)
+
+ first = False
+ if switch.has_attr("fixedsize"):
+ with writer.block(" else"):
+ writer.statement("spice_marshaller_reserve_space(m, %s)" % switch.get_fixed_nw_size())
+
+ writer.newline()
+
+def write_member_marshaller(writer, container, member, src, scope):
+ if member.has_attr("outvar"):
+ writer.out_prefix = "%s_%s" % (member.attributes["outvar"][0], writer.out_prefix)
+ if member.has_attr("virtual"):
+ writer.comment("Don't marshall @virtual %s" % member.name).newline()
+ return
+ if member.has_attr("nomarshal"):
+ writer.comment("Don't marshall @nomarshal %s" % member.name).newline()
+ return
+ if member.is_switch():
+ write_switch_marshaller(writer, container, member, src, scope)
+ return
+
+ t = member.member_type
+
+ if t.is_pointer():
+ write_pointer_marshaller(writer, member, src)
+ elif t.is_primitive():
+ if member.has_attr("zero"):
+ writer.statement("spice_marshaller_add_%s(m, 0)" % (t.primitive_type()))
+ if member.has_attr("bytes_count"):
+ var = "%s__ref" % member.name
+ scope.variable_def("void *", var)
+ writer.statement("%s = spice_marshaller_add_%s(m, %s)" % (var, t.primitive_type(), 0))
+
+ else:
+ writer.statement("spice_marshaller_add_%s(m, %s)" % (t.primitive_type(), src.get_ref(member.name)))
+ elif t.is_array():
+ write_array_marshaller(writer, member, t, src, scope)
+ elif t.is_struct():
+ src2 = src.child_sub(member)
+ writer.comment(member.name)
+ write_container_marshaller(writer, t, src2)
+ else:
+ raise NotImplementedError("TODO can't handle parsing of %s" % t)
+
+def write_container_marshaller(writer, container, src):
+ saved_out_prefix = writer.out_prefix
+ with src.declare(writer) as scope:
+ for m in container.members:
+ writer.out_prefix = saved_out_prefix
+ write_member_marshaller(writer, container, m, src, scope)
+
+def write_message_marshaller(writer, message, private):
+ if message.has_attr("ifdef"):
+ writer.ifdef(message.attributes["ifdef"][0])
+ writer.header.ifdef(message.attributes["ifdef"][0])
+ writer.out_prefix = ""
+ function_name = "spice_marshall_" + message.c_name()
+ if writer.is_generated("marshaller", function_name):
+ return function_name
+ writer.set_is_generated("marshaller", function_name)
+
+ names = message.get_pointer_names(False)
+ names_args = ""
+ if len(names) > 0:
+ n = [", SpiceMarshaller **%s_out" % name for name in names]
+ names_args = "".join(n)
+
+ if private:
+ message_name = message.c_name()
+ if (not message_name.startswith("msgc_")):
+ #small bug above, checks for startswith("msg") which
+ #matches "msgc" and appends "msg_" if this fails causing
+ #inconsistencies
+ message_name = "msg_" + message_name
+ writer.header.writeln("void (*" + message_name + ")(SpiceMarshaller *m, %s *msg" % message.c_type() + names_args + ");")
+ else:
+ writer.header.writeln("void " + function_name + "(SpiceMarshaller *m, %s *msg" % message.c_type() + names_args + ");")
+
+ scope = writer.function(function_name,
+ "static void" if private else "void",
+ "SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED %s *msg" % message.c_type() + names_args)
+ scope.variable_def("SPICE_GNUC_UNUSED SpiceMarshaller *", "m2")
+
+ for n in names:
+ writer.assign("*%s_out" % n, "NULL")
+
+ # fix warnings about unused variables by not creating body if no members to parse
+ if any(x.is_fixed_nw_size() for x in message.members):
+ src = RootMarshallingSource(None, message.c_type(), message.sizeof(), "msg")
+ src.reuse_scope = scope
+
+ write_container_marshaller(writer, message, src)
+
+ writer.end_block()
+ if message.has_attr("ifdef"):
+ writer.endif(message.attributes["ifdef"][0])
+ writer.header.endif(message.attributes["ifdef"][0])
+
+ writer.newline()
+ return function_name
+
+def write_protocol_marshaller(writer, proto, is_server, private_marshallers):
+ functions = {}
+ if private_marshallers:
+ writer.header.begin_block("typedef struct")
+ for c in proto.channels:
+ channel = c.channel_type
+ if channel.has_attr("ifdef"):
+ writer.ifdef(channel.attributes["ifdef"][0])
+ writer.header.ifdef(channel.attributes["ifdef"][0])
+ if is_server:
+ messages = channel.client_messages
+ else:
+ messages = channel.server_messages
+ for m in messages:
+ message = m.message_type
+ f = write_message_marshaller(writer, message, private_marshallers)
+ if channel.has_attr("ifdef") and f not in functions:
+ functions[f] = channel.attributes["ifdef"][0]
+ elif message.has_attr("ifdef") and f not in functions:
+ functions[f] = message.attributes["ifdef"][0]
+ else:
+ functions[f] = True
+ if channel.has_attr("ifdef"):
+ writer.endif(channel.attributes["ifdef"][0])
+ writer.header.endif(channel.attributes["ifdef"][0])
+
+ if private_marshallers:
+ writer.header.end_block(newline=False)
+ writer.header.writeln(" SpiceMessageMarshallers;")
+ writer.header.newline()
+ writer.header.statement("SpiceMessageMarshallers *spice_message_marshallers_get" + writer.public_prefix+"(void)")
+ writer.header.newline()
+
+ scope = writer.function("spice_message_marshallers_get" + writer.public_prefix,
+ "SpiceMessageMarshallers *",
+ "void")
+ writer.writeln("static SpiceMessageMarshallers marshallers = {NULL};").newline()
+ for f in sorted(functions.keys()):
+ member = f[len("spice_marshall_"):]
+ if not member.startswith("msg"):
+ member = "msg_" + member
+ if functions[f] != True:
+ writer.ifdef(functions[f])
+ writer.assign("marshallers.%s" % member, f)
+ if functions[f] != True:
+ writer.endif(functions[f])
+
+ writer.newline()
+ writer.statement("return &marshallers")
+ writer.end_block()
+ writer.newline()
+
+def write_trailer(writer):
+ writer.header.newline()
+ writer.header.writeln("SPICE_END_DECLS")
+ writer.header.newline()
+
+ writer.header.writeln("#endif")
--- /dev/null
+from . import codegen
+import types
+
+_types_by_name = {}
+_types = []
+
+default_pointer_size = 4
+
+def type_exists(name):
+ return name in _types_by_name
+
+def lookup_type(name):
+ return _types_by_name[name]
+
+def get_named_types():
+ return _types
+
+class FixedSize:
+ def __init__(self, val = 0, minor = 0):
+ if isinstance(val, FixedSize):
+ self.vals = val.vals
+ else:
+ self.vals = [0] * (minor + 1)
+ self.vals[minor] = val
+
+ def __add__(self, other):
+ if isinstance(other, int):
+ other = FixedSize(other)
+
+ new = FixedSize()
+ l = max(len(self.vals), len(other.vals))
+ shared = min(len(self.vals), len(other.vals))
+
+ new.vals = [0] * l
+
+ for i in range(shared):
+ new.vals[i] = self.vals[i] + other.vals[i]
+
+ for i in range(shared,len(self.vals)):
+ new.vals[i] = self.vals[i]
+
+ for i in range(shared,len(other.vals)):
+ new.vals[i] = new.vals[i] + other.vals[i]
+
+ return new
+
+ def __radd__(self, other):
+ return self.__add__(other)
+
+ def __str__(self):
+ s = "%d" % (self.vals[0])
+
+ for i in range(1,len(self.vals)):
+ if self.vals[i] > 0:
+ s = s + " + ((minor >= %d)?%d:0)" % (i, self.vals[i])
+ return s
+
+# Some attribute are propagated from member to the type as they really
+# are part of the type definition, rather than the member. This applies
+# only to attributes that affect pointer or array attributes, as these
+# are member local types, unlike e.g. a Struct that may be used by
+# other members
+propagated_attributes=["ptr_array", "nonnull", "chunk"]
+
+valid_attributes=set([
+ # embedded/appended at the end of the resulting C structure
+ 'end',
+ # the C structure contains a pointer to data
+ # for instance we want to write an array to an allocated array
+ 'to_ptr',
+ # write output to this C structure
+ 'ctype',
+ # prefix for flags/values enumerations
+ 'prefix',
+ # used in demarshaller to use directly data from message without a copy
+ 'nocopy',
+ # store member array in a pointer
+ # similar to to_ptr but has an additional argument which is the name of a C
+ # field which will store the array length
+ 'as_ptr',
+ # do not generate marshall code
+ # used for last members to be able to marshall them manually
+ 'nomarshal',
+ # ??? not used by python code
+ 'zero_terminated',
+ 'marshall',
+ # this pointer member cannot be null
+ 'nonnull',
+ # this flag member contains only a single flag
+ 'unique_flag',
+ 'ptr_array',
+ 'outvar',
+ # C structure has an anonymous member (used in switch)
+ 'anon',
+ 'chunk',
+ # this channel is contained in an #ifdef section
+ # the argument specifies the preprocessor define to check
+ 'ifdef',
+ # write this member as zero on network
+ 'zero',
+ # specify minor version required for these members
+ 'minor',
+ # this member contains the byte count for an array.
+ # the argument is the member name for item count (not bytes)
+ 'bytes_count',
+ # this attribute does not exist on the network, fill just structure with the value
+ 'virtual',
+ # for a switch this indicates that on network
+ # it will occupy always the same size (maximum size required for all members)
+ 'fixedsize',
+])
+
+attributes_with_arguments=set([
+ 'ctype',
+ 'prefix',
+ 'as_ptr',
+ 'outvar',
+ 'ifdef',
+ 'minor',
+ 'bytes_count',
+ 'virtual',
+])
+
+def fix_attributes(attribute_list):
+ attrs = {}
+ for attr in attribute_list:
+ name = attr[0][1:]
+ lst = attr[1:]
+ if not name in valid_attributes:
+ raise Exception("Attribute %s not recognized" % name)
+ if not name in attributes_with_arguments:
+ if len(lst) > 0:
+ raise Exception("Attribute %s specified with options" % name)
+ elif len(lst) > 1:
+ raise Exception("Attribute %s has more than 1 argument" % name)
+ attrs[name] = lst
+ return attrs
+
+class Type:
+ def __init__(self):
+ self.attributes = {}
+ self.registered = False
+ self.name = None
+
+ def has_name(self):
+ return self.name != None
+
+ def get_type(self, recursive=False):
+ return self
+
+ def is_primitive(self):
+ return False
+
+ def is_fixed_sizeof(self):
+ return True
+
+ def is_extra_size(self):
+ return False
+
+ def contains_extra_size(self):
+ return False
+
+ def is_fixed_nw_size(self):
+ return True
+
+ def is_array(self):
+ return isinstance(self, ArrayType)
+
+ def contains_member(self, member):
+ return False
+
+ def is_struct(self):
+ return isinstance(self, StructType)
+
+ def is_pointer(self):
+ return isinstance(self, PointerType)
+
+ def get_num_pointers(self):
+ return 0
+
+ def get_pointer_names(self, marshalled):
+ return []
+
+ def sizeof(self):
+ return "sizeof(%s)" % (self.c_type())
+
+ def __repr__(self):
+ return self.__str__()
+
+ def __str__(self):
+ if self.name != None:
+ return self.name
+ return "anonymous type"
+
+ def resolve(self):
+ return self
+
+ def register(self):
+ if self.registered or self.name == None:
+ return
+ self.registered = True
+ if self.name in _types_by_name:
+ raise Exception("Type %s already defined" % self.name)
+ _types.append(self)
+ _types_by_name[self.name] = self
+
+ def has_attr(self, name):
+ if not name in valid_attributes:
+ raise Exception('attribute %s not expected' % name)
+ return name in self.attributes
+
+class TypeRef(Type):
+ def __init__(self, name):
+ Type.__init__(self)
+ self.name = name
+
+ def __str__(self):
+ return "ref to %s" % (self.name)
+
+ def resolve(self):
+ if self.name not in _types_by_name:
+ raise Exception("Unknown type %s" % self.name)
+ return _types_by_name[self.name]
+
+ def register(self):
+ assert False, "Can't register TypeRef!"
+
+
+class IntegerType(Type):
+ def __init__(self, bits, signed):
+ Type.__init__(self)
+ self.bits = bits
+ self.signed = signed
+
+ if signed:
+ self.name = "int%d" % bits
+ else:
+ self.name = "uint%d" % bits
+
+ def primitive_type(self):
+ return self.name
+
+ def c_type(self):
+ return self.name + "_t"
+
+ def get_fixed_nw_size(self):
+ return self.bits // 8
+
+ def is_primitive(self):
+ return True
+
+class TypeAlias(Type):
+ def __init__(self, name, the_type, attribute_list):
+ Type.__init__(self)
+ self.name = name
+ self.the_type = the_type
+ self.attributes = fix_attributes(attribute_list)
+
+ def get_type(self, recursive=False):
+ if recursive:
+ return self.the_type.get_type(True)
+ else:
+ return self.the_type
+
+ def primitive_type(self):
+ return self.the_type.primitive_type()
+
+ def resolve(self):
+ self.the_type = self.the_type.resolve()
+ return self
+
+ def __str__(self):
+ return "alias %s" % self.name
+
+ def is_primitive(self):
+ return self.the_type.is_primitive()
+
+ def is_fixed_sizeof(self):
+ return self.the_type.is_fixed_sizeof()
+
+ def is_fixed_nw_size(self):
+ return self.the_type.is_fixed_nw_size()
+
+ def get_fixed_nw_size(self):
+ return self.the_type.get_fixed_nw_size()
+
+ def get_num_pointers(self):
+ return self.the_type.get_num_pointers()
+
+ def get_pointer_names(self, marshalled):
+ return self.the_type.get_pointer_names(marshalled)
+
+ def c_type(self):
+ if self.has_attr("ctype"):
+ return self.attributes["ctype"][0]
+ return self.name
+
+class EnumBaseType(Type):
+ def is_enum(self):
+ return isinstance(self, EnumType)
+
+ def primitive_type(self):
+ return "uint%d" % (self.bits)
+
+ def c_type(self):
+ return "uint%d_t" % (self.bits)
+
+ def c_name(self):
+ return codegen.prefix_camel(self.name)
+
+ def c_enumname(self, value):
+ return self.c_enumname_by_name(self.names[value])
+
+ def c_enumname_by_name(self, name):
+ if self.has_attr("prefix"):
+ return self.attributes["prefix"][0] + name
+ return codegen.prefix_underscore_upper(self.name.upper(), name)
+
+ def is_primitive(self):
+ return True
+
+ def get_fixed_nw_size(self):
+ return self.bits // 8
+
+ # generates a value-name table suitable for use with the wireshark protocol
+ # dissector
+ def c_describe(self, writer):
+ writer.write("static const value_string %s_vs[] = " % codegen.prefix_underscore_lower(self.name))
+ writer.begin_block()
+ values = list(self.names.keys())
+ values.sort()
+ for i in values:
+ writer.write("{ ")
+ writer.write(self.c_enumname(i))
+ writer.write(", \"%s\" }," % self.names[i])
+ writer.newline()
+ writer.write("{ 0, NULL }")
+ writer.end_block(semicolon=True)
+ writer.newline()
+
+
+class EnumType(EnumBaseType):
+ def __init__(self, bits, name, enums, attribute_list):
+ Type.__init__(self)
+ self.bits = bits
+ self.name = name
+
+ last = -1
+ names = {}
+ values = {}
+ for v in enums:
+ name = v[0]
+ if len(v) > 1:
+ value = v[1]
+ else:
+ value = last + 1
+ last = value
+
+ assert value not in names
+ names[value] = name
+ values[name] = value
+
+ self.names = names
+ self.values = values
+
+ self.attributes = fix_attributes(attribute_list)
+
+ def __str__(self):
+ return "enum %s" % self.name
+
+ def c_define(self, writer):
+ writer.write("typedef enum ")
+ writer.write(self.c_name())
+ writer.begin_block()
+ values = list(self.names.keys())
+ values.sort()
+ current_default = 0
+ for i in values:
+ writer.write(self.c_enumname(i))
+ if i != current_default:
+ writer.write(" = %d" % (i))
+ writer.write(",")
+ writer.newline()
+ current_default = i + 1
+ writer.newline()
+ writer.write(codegen.prefix_underscore_upper(self.name.upper(), "ENUM_END"))
+ writer.newline()
+ writer.end_block(newline=False)
+ writer.write(" ")
+ writer.write(self.c_name())
+ writer.write(";")
+ writer.newline()
+ writer.newline()
+
+class FlagsType(EnumBaseType):
+ def __init__(self, bits, name, flags, attribute_list):
+ Type.__init__(self)
+ self.bits = bits
+ self.name = name
+
+ last = -1
+ names = {}
+ values = {}
+ for v in flags:
+ name = v[0]
+ if len(v) > 1:
+ value = v[1]
+ else:
+ value = last + 1
+ last = value
+
+ assert value not in names
+ names[value] = name
+ values[name] = value
+
+ self.names = names
+ self.values = values
+
+ self.attributes = fix_attributes(attribute_list)
+
+ def __str__(self):
+ return "flags %s" % self.name
+
+ def c_define(self, writer):
+ writer.write("typedef enum ")
+ writer.write(self.c_name())
+ writer.begin_block()
+ values = list(self.names.keys())
+ values.sort()
+ mask = 0
+ for i in values:
+ writer.write(self.c_enumname(i))
+ mask = mask | (1<<i)
+ writer.write(" = (1 << %d)" % (i))
+ writer.write(",")
+ writer.newline()
+ current_default = i + 1
+ writer.newline()
+ writer.write(codegen.prefix_underscore_upper(self.name.upper(), "MASK"))
+ writer.write(" = 0x%x" % (mask))
+ writer.newline()
+ writer.end_block(newline=False)
+ writer.write(" ")
+ writer.write(self.c_name())
+ writer.write(";")
+ writer.newline()
+ writer.newline()
+
+class ArrayType(Type):
+ def __init__(self, element_type, size):
+ Type.__init__(self)
+ self.name = None
+
+ self.element_type = element_type
+ self.size = size
+
+ def __str__(self):
+ if self.size == None:
+ return "%s[]" % (str(self.element_type))
+ else:
+ return "%s[%s]" % (str(self.element_type), str(self.size))
+
+ def resolve(self):
+ self.element_type = self.element_type.resolve()
+ return self
+
+ def is_constant_length(self):
+ return isinstance(self.size, int)
+
+ def is_remaining_length(self):
+ return isinstance(self.size, str) and len(self.size) == 0
+
+ def is_identifier_length(self):
+ return isinstance(self.size, str) and len(self.size) > 0
+
+ def is_image_size_length(self):
+ if isinstance(self.size, int) or isinstance(self.size, str):
+ return False
+ return self.size[0] == "image_size"
+
+ def is_bytes_length(self):
+ if isinstance(self.size, int) or isinstance(self.size, str):
+ return False
+ return self.size[0] == "bytes"
+
+ def is_cstring_length(self):
+ if isinstance(self.size, int) or isinstance(self.size, str):
+ return False
+ return self.size[0] == "cstring"
+
+ def is_fixed_sizeof(self):
+ return self.is_constant_length() and self.element_type.is_fixed_sizeof()
+
+ def is_fixed_nw_size(self):
+ return self.is_constant_length() and self.element_type.is_fixed_nw_size()
+
+ def get_fixed_nw_size(self):
+ if not self.is_fixed_nw_size():
+ raise Exception("Not a fixed size type")
+
+ return self.element_type.get_fixed_nw_size() * self.size
+
+ def get_num_pointers(self):
+ element_count = self.element_type.get_num_pointers()
+ if element_count == 0:
+ return 0
+ if self.is_constant_length(self):
+ return element_count * self.size
+ raise Exception("Pointers in dynamic arrays not supported")
+
+ def get_pointer_names(self, marshalled):
+ element_count = self.element_type.get_num_pointers()
+ if element_count == 0:
+ return []
+ raise Exception("Pointer names in arrays not supported")
+
+ def is_extra_size(self):
+ return self.has_attr("ptr_array")
+
+ def contains_extra_size(self):
+ return self.element_type.contains_extra_size() or self.has_attr("chunk")
+
+ def sizeof(self):
+ return "%s * %s" % (self.element_type.sizeof(), self.size)
+
+ def c_type(self):
+ return self.element_type.c_type()
+
+class PointerType(Type):
+ def __init__(self, target_type):
+ Type.__init__(self)
+ self.name = None
+ self.target_type = target_type
+ self.pointer_size = default_pointer_size
+
+ def __str__(self):
+ return "%s*" % (str(self.target_type))
+
+ def resolve(self):
+ self.target_type = self.target_type.resolve()
+ return self
+
+ def set_ptr_size(self, new_size):
+ self.pointer_size = new_size
+
+ def is_fixed_nw_size(self):
+ return True
+
+ def is_primitive(self):
+ return True
+
+ def primitive_type(self):
+ if self.pointer_size == 4:
+ return "uint32"
+ else:
+ return "uint64"
+
+ def get_fixed_nw_size(self):
+ return self.pointer_size
+
+ def c_type(self):
+ if self.pointer_size == 4:
+ return "uint32_t"
+ else:
+ return "uint64_t"
+
+ def contains_extra_size(self):
+ return True
+
+ def get_num_pointers(self):
+ return 1
+
+class Containee:
+ def __init__(self):
+ self.attributes = {}
+
+ def is_switch(self):
+ return False
+
+ def is_pointer(self):
+ return not self.is_switch() and self.member_type.is_pointer()
+
+ def is_array(self):
+ return not self.is_switch() and self.member_type.is_array()
+
+ def is_struct(self):
+ return not self.is_switch() and self.member_type.is_struct()
+
+ def is_primitive(self):
+ return not self.is_switch() and self.member_type.is_primitive()
+
+ def has_attr(self, name):
+ if not name in valid_attributes:
+ raise Exception('attribute %s not expected' % name)
+ return name in self.attributes
+
+ def has_minor_attr(self):
+ return self.has_attr("minor")
+
+ def has_end_attr(self):
+ return self.has_attr("end")
+
+ def get_minor_attr(self):
+ return self.attributes["minor"][0]
+
+class Member(Containee):
+ def __init__(self, name, member_type, attribute_list):
+ Containee.__init__(self)
+ self.name = name
+ self.member_type = member_type
+ self.attributes = fix_attributes(attribute_list)
+
+ def resolve(self, container):
+ self.container = container
+ self.member_type = self.member_type.resolve()
+ self.member_type.register()
+ for i in propagated_attributes:
+ if self.has_attr(i):
+ self.member_type.attributes[i] = self.attributes[i]
+ return self
+
+ def contains_member(self, member):
+ return self.member_type.contains_member(member)
+
+ def is_primitive(self):
+ return self.member_type.is_primitive()
+
+ def is_fixed_sizeof(self):
+ if self.has_end_attr():
+ return False
+ return self.member_type.is_fixed_sizeof()
+
+ def is_extra_size(self):
+ return self.has_end_attr() or self.has_attr("to_ptr") or self.member_type.is_extra_size()
+
+ def is_fixed_nw_size(self):
+ if self.has_attr("virtual"):
+ return True
+ return self.member_type.is_fixed_nw_size()
+
+ def get_fixed_nw_size(self):
+ if self.has_attr("virtual"):
+ return 0
+ size = self.member_type.get_fixed_nw_size()
+ if self.has_minor_attr():
+ minor = self.get_minor_attr()
+ size = FixedSize(size, minor)
+ return size
+
+ def contains_extra_size(self):
+ return self.member_type.contains_extra_size()
+
+ def sizeof(self):
+ return self.member_type.sizeof()
+
+ def __repr__(self):
+ return "%s (%s)" % (str(self.name), str(self.member_type))
+
+ def get_num_pointers(self):
+ if self.has_attr("to_ptr"):
+ return 1
+ return self.member_type.get_num_pointers()
+
+ def get_pointer_names(self, marshalled):
+ if self.member_type.is_pointer():
+ if self.has_attr("marshall") == marshalled:
+ names = [self.name]
+ else:
+ names = []
+ else:
+ names = self.member_type.get_pointer_names(marshalled)
+ if self.has_attr("outvar"):
+ prefix = self.attributes["outvar"][0]
+ names = [prefix + "_" + name for name in names]
+ return names
+
+class SwitchCase:
+ def __init__(self, values, member):
+ self.values = values
+ self.member = member
+ self.members = [member]
+
+ def get_check(self, var_cname, var_type):
+ checks = []
+ for v in self.values:
+ if v == None:
+ return "1"
+ elif var_type.is_enum():
+ assert v[0] == "", "Negation of enumeration in switch is not supported"
+ checks.append("%s == %s" % (var_cname, var_type.c_enumname_by_name(v[1])))
+ else:
+ checks.append("%s(%s & %s)" % (v[0], var_cname, var_type.c_enumname_by_name(v[1])))
+ return " || ".join(checks)
+
+ def resolve(self, container):
+ self.switch = container
+ self.member = self.member.resolve(self)
+ return self
+
+ def get_num_pointers(self):
+ return self.member.get_num_pointers()
+
+ def get_pointer_names(self, marshalled):
+ return self.member.get_pointer_names(marshalled)
+
+class Switch(Containee):
+ def __init__(self, variable, cases, name, attribute_list):
+ Containee.__init__(self)
+ self.variable = variable
+ self.name = name
+ self.cases = cases
+ self.attributes = fix_attributes(attribute_list)
+
+ def is_switch(self):
+ return True
+
+ def lookup_case_member(self, name):
+ for c in self.cases:
+ if c.member.name == name:
+ return c.member
+ return None
+
+ def has_switch_member(self, member):
+ for c in self.cases:
+ if c.member == member:
+ return True
+ return False
+
+ def resolve(self, container):
+ self.container = container
+ self.cases = [c.resolve(self) for c in self.cases]
+ return self
+
+ def __repr__(self):
+ return "switch on %s %s" % (str(self.variable),str(self.name))
+
+ def is_fixed_sizeof(self):
+ # Kinda weird, but we're unlikely to have a real struct if there is an @end
+ if self.has_end_attr():
+ return False
+ return True
+
+ def is_fixed_nw_size(self):
+ if self.has_attr("fixedsize"):
+ return True
+
+ size = None
+ has_default = False
+ for c in self.cases:
+ for v in c.values:
+ if v == None:
+ has_default = True
+ if not c.member.is_fixed_nw_size():
+ return False
+ if size == None:
+ size = c.member.get_fixed_nw_size()
+ elif size != c.member.get_fixed_nw_size():
+ return False
+ # Fixed size if all elements listed, or has default
+ if has_default:
+ return True
+ key = self.container.lookup_member(self.variable)
+ return len(self.cases) == len(key.member_type.values)
+
+ def is_extra_size(self):
+ return self.has_end_attr()
+
+ def contains_extra_size(self):
+ for c in self.cases:
+ if c.member.is_extra_size():
+ return True
+ if c.member.contains_extra_size():
+ return True
+ return False
+
+ def get_fixed_nw_size(self):
+ if not self.is_fixed_nw_size():
+ raise Exception("Not a fixed size type")
+ size = 0
+ for c in self.cases:
+ size = max(size, c.member.get_fixed_nw_size())
+ return size
+
+ def sizeof(self):
+ return "sizeof(((%s *)NULL)->%s)" % (self.container.c_type(),
+ self.name)
+
+ def contains_member(self, member):
+ return False # TODO: Don't support switch deep member lookup yet
+
+ def get_num_pointers(self):
+ count = 0
+ for c in self.cases:
+ count = max(count, c.get_num_pointers())
+ return count
+
+ def get_pointer_names(self, marshalled):
+ names = []
+ for c in self.cases:
+ names = names + c.get_pointer_names(marshalled)
+ return names
+
+class ContainerType(Type):
+ def is_fixed_sizeof(self):
+ for m in self.members:
+ if not m.is_fixed_sizeof():
+ return False
+ return True
+
+ def contains_extra_size(self):
+ for m in self.members:
+ if m.is_extra_size():
+ return True
+ if m.contains_extra_size():
+ return True
+ return False
+
+ def is_fixed_nw_size(self):
+ for i in self.members:
+ if not i.is_fixed_nw_size():
+ return False
+ return True
+
+ def get_fixed_nw_size(self):
+ size = 0
+ for i in self.members:
+ size = size + i.get_fixed_nw_size()
+ return size
+
+ def contains_member(self, member):
+ for m in self.members:
+ if m == member or m.contains_member(member):
+ return True
+ return False
+
+ def get_fixed_nw_offset(self, member):
+ size = 0
+ for i in self.members:
+ if i == member:
+ break
+ if i.contains_member(member):
+ size = size + i.member_type.get_fixed_nw_offset(member)
+ break
+ if i.is_fixed_nw_size():
+ size = size + i.get_fixed_nw_size()
+ return size
+
+ def resolve(self):
+ self.members = [m.resolve(self) for m in self.members]
+ return self
+
+ def get_num_pointers(self):
+ count = 0
+ for m in self.members:
+ count = count + m.get_num_pointers()
+ return count
+
+ def get_pointer_names(self, marshalled):
+ names = []
+ for m in self.members:
+ names = names + m.get_pointer_names(marshalled)
+ return names
+
+ def get_nw_offset(self, member, prefix = "", postfix = ""):
+ fixed = self.get_fixed_nw_offset(member)
+ v = []
+ container = self
+ while container != None:
+ members = container.members
+ container = None
+ for m in members:
+ if m == member:
+ break
+ if m.contains_member(member):
+ container = m.member_type
+ break
+ if m.is_switch() and m.has_switch_member(member):
+ break
+ if not m.is_fixed_nw_size():
+ v.append(prefix + m.name + postfix)
+ if len(v) > 0:
+ return str(fixed) + " + " + (" + ".join(v))
+ else:
+ return str(fixed)
+
+ def lookup_member(self, name):
+ dot = name.find('.')
+ rest = None
+ if dot >= 0:
+ rest = name[dot+1:]
+ name = name[:dot]
+
+ member = None
+ if name in self.members_by_name:
+ member = self.members_by_name[name]
+ else:
+ for m in self.members:
+ if m.is_switch():
+ member = m.lookup_case_member(name)
+ if member != None:
+ break
+ if member != None:
+ break
+
+ if member == None:
+ raise Exception("No member called %s found" % name)
+
+ if rest != None:
+ return member.member_type.lookup_member(rest)
+
+ return member
+
+class StructType(ContainerType):
+ def __init__(self, name, members, attribute_list):
+ Type.__init__(self)
+ self.name = name
+ self.members = members
+ self.members_by_name = {}
+ for m in members:
+ self.members_by_name[m.name] = m
+ self.attributes = fix_attributes(attribute_list)
+
+ def __str__(self):
+ if self.name == None:
+ return "anonymous struct"
+ else:
+ return "struct %s" % self.name
+
+ def c_type(self):
+ if self.has_attr("ctype"):
+ return self.attributes["ctype"][0]
+ return codegen.prefix_camel(self.name)
+
+class MessageType(ContainerType):
+ def __init__(self, name, members, attribute_list):
+ Type.__init__(self)
+ self.name = name
+ self.members = members
+ self.members_by_name = {}
+ for m in members:
+ self.members_by_name[m.name] = m
+ self.reverse_members = {} # ChannelMembers referencing this message
+ self.attributes = fix_attributes(attribute_list)
+
+ def __str__(self):
+ if self.name == None:
+ return "anonymous message"
+ else:
+ return "message %s" % self.name
+
+ def c_name(self):
+ if self.name == None:
+ cms = list(self.reverse_members.keys())
+ if len(cms) != 1:
+ raise "Unknown typename for message"
+ cm = cms[0]
+ channelname = cm.channel.member_name
+ if channelname == None:
+ channelname = ""
+ else:
+ channelname = channelname + "_"
+ if cm.is_server:
+ return "msg_" + channelname + cm.name
+ else:
+ return "msgc_" + channelname + cm.name
+ else:
+ return codegen.prefix_camel("Msg", self.name)
+
+ def c_type(self):
+ if self.has_attr("ctype"):
+ return self.attributes["ctype"][0]
+ if self.name == None:
+ cms = list(self.reverse_members.keys())
+ if len(cms) != 1:
+ raise "Unknown typename for message"
+ cm = cms[0]
+ channelname = cm.channel.member_name
+ if channelname == None:
+ channelname = ""
+ if cm.is_server:
+ return codegen.prefix_camel("Msg", channelname, cm.name)
+ else:
+ return codegen.prefix_camel("Msgc", channelname, cm.name)
+ else:
+ return codegen.prefix_camel("Msg", self.name)
+
+class ChannelMember(Containee):
+ def __init__(self, name, message_type, value):
+ Containee.__init__(self)
+ self.name = name
+ self.message_type = message_type
+ self.value = value
+
+ def resolve(self, channel):
+ self.channel = channel
+ self.message_type = self.message_type.resolve()
+ self.message_type.reverse_members[self] = 1
+
+ return self
+
+ def __repr__(self):
+ return "%s (%s)" % (str(self.name), str(self.message_type))
+
+class ChannelType(Type):
+ def __init__(self, name, base, members, attribute_list):
+ Type.__init__(self)
+ self.name = name
+ self.base = base
+ self.member_name = None
+ self.members = members
+ self.attributes = fix_attributes(attribute_list)
+
+ def __str__(self):
+ if self.name == None:
+ return "anonymous channel"
+ else:
+ return "channel %s" % self.name
+
+ def is_fixed_nw_size(self):
+ return False
+
+ def get_client_message(self, name):
+ return self.client_messages_byname[name]
+
+ def get_server_message(self, name):
+ return self.server_messages_byname[name]
+
+ def resolve(self):
+ if self.base != None:
+ self.base = self.base.resolve()
+
+ server_messages = self.base.server_messages[:]
+ server_messages_byname = self.base.server_messages_byname.copy()
+ client_messages = self.base.client_messages[:]
+ client_messages_byname = self.base.client_messages_byname.copy()
+
+ # Set default member_name, FooChannel -> foo
+ self.member_name = self.name[:-7].lower()
+ else:
+ server_messages = []
+ server_messages_byname = {}
+ client_messages = []
+ client_messages_byname = {}
+
+ server_count = 1
+ client_count = 1
+
+ server = True
+ for m in self.members:
+ if m == "server":
+ server = True
+ elif m == "client":
+ server = False
+ elif server:
+ m.is_server = True
+ m = m.resolve(self)
+ if m.value:
+ server_count = m.value + 1
+ else:
+ m.value = server_count
+ server_count = server_count + 1
+ server_messages.append(m)
+ server_messages_byname[m.name] = m
+ else:
+ m.is_server = False
+ m = m.resolve(self)
+ if m.value:
+ client_count = m.value + 1
+ else:
+ m.value = client_count
+ client_count = client_count + 1
+ client_messages.append(m)
+ client_messages_byname[m.name] = m
+
+ self.server_messages = server_messages
+ self.server_messages_byname = server_messages_byname
+ self.client_messages = client_messages
+ self.client_messages_byname = client_messages_byname
+
+ return self
+
+class ProtocolMember:
+ def __init__(self, name, channel_type, value):
+ self.name = name
+ self.channel_type = channel_type
+ self.value = value
+
+ def resolve(self, protocol):
+ self.channel_type = self.channel_type.resolve()
+ self.channel_type.member_name = self.name
+ return self
+
+ def __repr__(self):
+ return "%s (%s)" % (str(self.name), str(self.channel_type))
+
+class ProtocolType(Type):
+ def __init__(self, name, channels):
+ Type.__init__(self)
+ self.name = name
+ self.channels = channels
+
+ def __str__(self):
+ if self.name == None:
+ return "anonymous protocol"
+ else:
+ return "protocol %s" % self.name
+
+ def is_fixed_nw_size(self):
+ return False
+
+ def resolve(self):
+ count = 1
+ for m in self.channels:
+ m = m.resolve(self)
+ if m.value:
+ count = m.value + 1
+ else:
+ m.value = count
+ count = count + 1
+
+ return self
+
+class FdType(IntegerType):
+ def __init__(self):
+ IntegerType.__init__(self, 0, False)
+ self.name = "fd"
+
+ def c_type(self):
+ return "int"
+
+int8 = IntegerType(8, True)
+uint8 = IntegerType(8, False)
+int16 = IntegerType(16, True)
+uint16 = IntegerType(16, False)
+int32 = IntegerType(32, True)
+uint32 = IntegerType(32, False)
+int64 = IntegerType(64, True)
+uint64 = IntegerType(64, False)
+unix_fd = FdType()
--- /dev/null
+import six
+
+try:
+ from pyparsing import Literal, CaselessLiteral, Word, OneOrMore, ZeroOrMore, \
+ Forward, delimitedList, Group, Optional, Combine, alphas, nums, restOfLine, cStyleComment, \
+ alphanums, ParseException, ParseResults, Keyword, StringEnd, replaceWith
+except ImportError:
+ six.print_("Module pyparsing not found.")
+ exit(1)
+
+
+from . import ptypes
+import sys
+
+cvtInt = lambda toks: int(toks[0])
+
+def parseVariableDef(toks):
+ t = toks[0][0]
+ pointer = toks[0][1]
+ name = toks[0][2]
+ array_size = toks[0][3]
+ attributes = toks[0][4]
+
+ if array_size != None:
+ t = ptypes.ArrayType(t, array_size)
+
+ if pointer != None:
+ t = ptypes.PointerType(t)
+
+ return ptypes.Member(name, t, attributes)
+
+bnf = None
+def SPICE_BNF():
+ global bnf
+
+ if not bnf:
+
+ # punctuation
+ colon = Literal(":").suppress()
+ lbrace = Literal("{").suppress()
+ rbrace = Literal("}").suppress()
+ lbrack = Literal("[").suppress()
+ rbrack = Literal("]").suppress()
+ lparen = Literal("(").suppress()
+ rparen = Literal(")").suppress()
+ equals = Literal("=").suppress()
+ comma = Literal(",").suppress()
+ semi = Literal(";").suppress()
+
+ # primitive types
+ int8_ = Keyword("int8").setParseAction(replaceWith(ptypes.int8))
+ uint8_ = Keyword("uint8").setParseAction(replaceWith(ptypes.uint8))
+ int16_ = Keyword("int16").setParseAction(replaceWith(ptypes.int16))
+ uint16_ = Keyword("uint16").setParseAction(replaceWith(ptypes.uint16))
+ int32_ = Keyword("int32").setParseAction(replaceWith(ptypes.int32))
+ uint32_ = Keyword("uint32").setParseAction(replaceWith(ptypes.uint32))
+ int64_ = Keyword("int64").setParseAction(replaceWith(ptypes.int64))
+ uint64_ = Keyword("uint64").setParseAction(replaceWith(ptypes.uint64))
+ unix_fd_ = Keyword("unix_fd").setParseAction(replaceWith(ptypes.unix_fd))
+
+ # keywords
+ enum32_ = Keyword("enum32").setParseAction(replaceWith(32))
+ enum16_ = Keyword("enum16").setParseAction(replaceWith(16))
+ enum8_ = Keyword("enum8").setParseAction(replaceWith(8))
+ flags32_ = Keyword("flags32").setParseAction(replaceWith(32))
+ flags16_ = Keyword("flags16").setParseAction(replaceWith(16))
+ flags8_ = Keyword("flags8").setParseAction(replaceWith(8))
+ channel_ = Keyword("channel")
+ server_ = Keyword("server")
+ client_ = Keyword("client")
+ protocol_ = Keyword("protocol")
+ typedef_ = Keyword("typedef")
+ struct_ = Keyword("struct")
+ message_ = Keyword("message")
+ image_size_ = Keyword("image_size")
+ bytes_ = Keyword("bytes")
+ cstring_ = Keyword("cstring")
+ switch_ = Keyword("switch")
+ default_ = Keyword("default")
+ case_ = Keyword("case")
+
+ identifier = Word( alphas, alphanums + "_" )
+ enumname = Word( alphanums + "_" )
+
+ integer = ( Combine( CaselessLiteral("0x") + Word( nums+"abcdefABCDEF" ) ) |
+ Word( nums+"+-", nums ) ).setName("int").setParseAction(cvtInt)
+
+ typename = identifier.copy().setParseAction(lambda toks : ptypes.TypeRef(str(toks[0])))
+
+ # This is just normal "types", i.e. not channels or messages
+ typeSpec = Forward()
+
+ attributeValue = integer ^ identifier
+ attribute = Group(Combine ("@" + identifier) + Optional(lparen + delimitedList(attributeValue) + rparen))
+ attributes = Group(ZeroOrMore(attribute))
+ arraySizeSpecImage = Group(image_size_ + lparen + integer + comma + identifier + comma + identifier + rparen)
+ arraySizeSpecBytes = Group(bytes_ + lparen + identifier + comma + identifier + rparen)
+ arraySizeSpecCString = Group(cstring_ + lparen + rparen)
+ arraySizeSpec = lbrack + Optional(identifier ^ integer ^ arraySizeSpecImage ^ arraySizeSpecBytes ^arraySizeSpecCString, default="") + rbrack
+ variableDef = Group(typeSpec + Optional("*", default=None) + identifier + Optional(arraySizeSpec, default=None) + attributes - semi) \
+ .setParseAction(parseVariableDef)
+
+ switchCase = Group(Group(OneOrMore(default_.setParseAction(replaceWith(None)) + colon | Group(case_.suppress() + Optional("!", default="") + identifier) + colon)) + variableDef) \
+ .setParseAction(lambda toks: ptypes.SwitchCase(toks[0][0], toks[0][1]))
+ switchBody = Group(switch_ + lparen + delimitedList(identifier,delim='.', combine=True) + rparen + lbrace + Group(OneOrMore(switchCase)) + rbrace + identifier + attributes - semi) \
+ .setParseAction(lambda toks: ptypes.Switch(toks[0][1], toks[0][2], toks[0][3], toks[0][4]))
+ messageBody = structBody = Group(lbrace + ZeroOrMore(variableDef | switchBody) + rbrace)
+ structSpec = Group(struct_ + identifier + structBody + attributes).setParseAction(lambda toks: ptypes.StructType(toks[0][1], toks[0][2], toks[0][3]))
+
+ # have to use longest match for type, in case a user-defined type name starts with a keyword type, like "channel_type"
+ typeSpec << ( structSpec ^ int8_ ^ uint8_ ^ int16_ ^ uint16_ ^
+ int32_ ^ uint32_ ^ int64_ ^ uint64_ ^ unix_fd_ ^
+ typename).setName("type")
+
+ flagsBody = enumBody = Group(lbrace + delimitedList(Group (enumname + Optional(equals + integer))) + Optional(comma) + rbrace)
+
+ messageSpec = Group(message_ + messageBody + attributes).setParseAction(lambda toks: ptypes.MessageType(None, toks[0][1], toks[0][2])) | typename
+
+ channelParent = Optional(colon + typename, default=None)
+ channelMessage = Group(messageSpec + identifier + Optional(equals + integer, default=None) + semi) \
+ .setParseAction(lambda toks: ptypes.ChannelMember(toks[0][1], toks[0][0], toks[0][2]))
+ channelBody = channelParent + Group(lbrace + ZeroOrMore( server_ + colon | client_ + colon | channelMessage) + rbrace)
+
+ enum_ = (enum32_ | enum16_ | enum8_)
+ flags_ = (flags32_ | flags16_ | flags8_)
+ enumDef = Group(enum_ + identifier + enumBody + attributes - semi).setParseAction(lambda toks: ptypes.EnumType(toks[0][0], toks[0][1], toks[0][2], toks[0][3]))
+ flagsDef = Group(flags_ + identifier + flagsBody + attributes - semi).setParseAction(lambda toks: ptypes.FlagsType(toks[0][0], toks[0][1], toks[0][2], toks[0][3]))
+ messageDef = Group(message_ + identifier + messageBody + attributes - semi).setParseAction(lambda toks: ptypes.MessageType(toks[0][1], toks[0][2], toks[0][3]))
+ channelDef = Group(channel_ + identifier + channelBody + attributes - semi).setParseAction(lambda toks: ptypes.ChannelType(toks[0][1], toks[0][2], toks[0][3], toks[0][4]))
+ structDef = Group(struct_ + identifier + structBody + attributes - semi).setParseAction(lambda toks: ptypes.StructType(toks[0][1], toks[0][2], toks[0][3]))
+ typedefDef = Group(typedef_ + identifier + typeSpec + attributes - semi).setParseAction(lambda toks: ptypes.TypeAlias(toks[0][1], toks[0][2], toks[0][3]))
+
+ definitions = typedefDef | structDef | enumDef | flagsDef | messageDef | channelDef
+
+ protocolChannel = Group(typename + identifier + Optional(equals + integer, default=None) + semi) \
+ .setParseAction(lambda toks: ptypes.ProtocolMember(toks[0][1], toks[0][0], toks[0][2]))
+ protocolDef = Group(protocol_ + identifier + Group(lbrace + ZeroOrMore(protocolChannel) + rbrace) + semi) \
+ .setParseAction(lambda toks: ptypes.ProtocolType(toks[0][1], toks[0][2]))
+
+ bnf = ZeroOrMore (definitions) + protocolDef + StringEnd()
+
+ singleLineComment = "//" + restOfLine
+ bnf.ignore( singleLineComment )
+ bnf.ignore( cStyleComment )
+
+ return bnf
+
+
+def parse(filename):
+ try:
+ bnf = SPICE_BNF()
+ types = bnf.parseFile(filename)
+ except ParseException as err:
+ six.print_(err.line, file=sys.stderr)
+ six.print_(" "*(err.column-1) + "^", file=sys.stderr)
+ six.print_(err, file=sys.stderr)
+ return None
+
+ for t in types:
+ t.resolve()
+ t.register()
+ protocol = types[-1]
+ return protocol
--- /dev/null
+/* built in types:
+ int8, uint8, 16, 32, 64
+*/
+
+typedef fixed28_4 int32 @ctype(SPICE_FIXED28_4);
+
+struct Point {
+ int32 x;
+ int32 y;
+};
+
+struct Point16 {
+ int16 x;
+ int16 y;
+};
+
+struct PointFix {
+ fixed28_4 x;
+ fixed28_4 y;
+};
+
+struct Rect {
+ int32 top;
+ int32 left;
+ int32 bottom;
+ int32 right;
+};
+
+struct Transform {
+ uint32 t00;
+ uint32 t01;
+ uint32 t02;
+ uint32 t10;
+ uint32 t11;
+ uint32 t12;
+};
+
+enum32 link_err {
+ OK,
+ ERROR,
+ INVALID_MAGIC,
+ INVALID_DATA,
+ VERSION_MISMATCH,
+ NEED_SECURED,
+ NEED_UNSECURED,
+ PERMISSION_DENIED,
+ BAD_CONNECTION_ID,
+ CHANNEL_NOT_AVAILABLE
+};
+
+enum32 warn_code {
+ WARN_GENERAL
+} @prefix(SPICE_);
+
+enum32 info_code {
+ INFO_GENERAL
+} @prefix(SPICE_);
+
+flags32 migrate_flags {
+ NEED_FLUSH,
+ NEED_DATA_TRANSFER
+} @prefix(SPICE_MIGRATE_);
+
+flags32 composite_flags {
+ OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7,
+ SRC_FILTER0, SRC_FILTER1, SRC_FILTER2,
+ MASK_FILTER0, MASK_FITLER1, MASK_FILTER2,
+
+ SRC_REPEAT0, SRC_REPEAT1,
+ MASK_REPEAT0, MASK_REPEAT1,
+ COMPONENT_ALPHA,
+
+ HAS_MASK,
+ HAS_SRC_TRANSFORM,
+ HAS_MASK_TRANSFORM,
+
+ /* These are used to override the formats given in the images. For
+ * example, if the mask image has format a8r8g8b8, but MASK_OPAQUE
+ * is set, the image should be treated as if it were x8r8g8b8
+ */
+ SOURCE_OPAQUE,
+ MASK_OPAQUE,
+ DEST_OPAQUE,
+} @prefix(SPICE_COMPOSITE_);
+
+enum32 notify_severity {
+ INFO,
+ WARN,
+ ERROR,
+};
+
+enum32 notify_visibility {
+ LOW,
+ MEDIUM,
+ HIGH,
+};
+
+flags16 mouse_mode {
+ SERVER,
+ CLIENT,
+};
+
+enum16 pubkey_type {
+ INVALID,
+ RSA,
+ RSA2,
+ DSA,
+ DSA1,
+ DSA2,
+ DSA3,
+ DSA4,
+ DH,
+ EC,
+};
+
+message Empty {
+};
+
+message Data {
+ uint8 data[] @end @ctype(uint8_t);
+} @nocopy;
+
+enum8 data_compression_type {
+ NONE,
+ LZ4,
+};
+
+struct EmptyStructure {
+};
+
+message CompressedData {
+ data_compression_type type;
+ switch (type) {
+ /* we cannot use !NONE (works only with flags) */
+ case NONE:
+ /* due to the way cases are defined after NONE we must have something */
+ /* due to a bug we cannot use @virtual to write 0 to compressed_size */
+ EmptyStructure empty;
+ default:
+ uint32 uncompressed_size;
+ } u @anon;
+ uint8 compressed_data[] @as_ptr(compressed_size);
+} @ctype(SpiceMsgCompressedData);
+
+struct ChannelWait {
+ uint8 channel_type;
+ uint8 channel_id;
+ uint64 message_serial;
+} @ctype(SpiceWaitForChannel);
+
+channel BaseChannel {
+ server:
+ message {
+ migrate_flags flags;
+ } migrate;
+
+ Data migrate_data;
+
+ message {
+ uint32 generation;
+ uint32 window;
+ } set_ack;
+
+ message {
+ uint32 id;
+ uint64 timestamp;
+ uint8 data[] @ctype(uint8_t) @as_ptr(data_len);
+ } ping;
+
+ message {
+ uint8 wait_count;
+ ChannelWait wait_list[wait_count] @end;
+ } wait_for_channels;
+
+ message {
+ uint64 time_stamp;
+ link_err reason;
+ } @ctype(SpiceMsgDisconnect) disconnecting;
+
+ message {
+ uint64 time_stamp;
+ notify_severity severity;
+ notify_visibility visibilty;
+ uint32 what; /* error_code/warn_code/info_code */
+ uint32 message_len;
+ uint8 message[message_len] @end @nomarshal;
+ } notify;
+
+ Data list; /* the msg body is SpiceSubMessageList */
+
+ Empty base_last = 100;
+
+ client:
+ message {
+ uint32 generation;
+ } ack_sync;
+
+ Empty ack;
+
+ message {
+ uint32 id;
+ uint64 timestamp;
+ } @ctype(SpiceMsgPing) pong;
+
+ Empty migrate_flush_mark;
+
+ Data migrate_data;
+
+ message {
+ uint64 time_stamp;
+ link_err reason;
+ } @ctype(SpiceMsgDisconnect) disconnecting;
+};
+
+struct ChannelId {
+ uint8 type;
+ uint8 id;
+};
+
+struct DstInfo {
+ uint16 port;
+ uint16 sport;
+ uint32 host_size;
+ uint8 *host_data[host_size] @zero_terminated @marshall @nonnull;
+ uint32 cert_subject_size;
+ uint8 *cert_subject_data[cert_subject_size] @zero_terminated @marshall;
+} @ctype(SpiceMigrationDstInfo);
+
+channel MainChannel : BaseChannel {
+ server:
+ message {
+ DstInfo dst_info;
+ } @ctype(SpiceMsgMainMigrationBegin) migrate_begin = 101;
+
+ Empty migrate_cancel;
+
+ message {
+ uint32 session_id;
+ uint32 display_channels_hint;
+ uint32 supported_mouse_modes;
+ uint32 current_mouse_mode;
+ uint32 agent_connected;
+ uint32 agent_tokens;
+ uint32 multi_media_time;
+ uint32 ram_hint;
+ } init;
+
+ message {
+ uint32 num_of_channels;
+ ChannelId channels[num_of_channels] @end;
+ } @ctype(SpiceMsgChannels) channels_list;
+
+ message {
+ mouse_mode supported_modes;
+ mouse_mode current_mode @unique_flag;
+ } mouse_mode;
+
+ message {
+ uint32 time;
+ } @ctype(SpiceMsgMainMultiMediaTime) multi_media_time;
+
+ Empty agent_connected;
+
+ message {
+ link_err error_code;
+ } @ctype(SpiceMsgMainAgentDisconnect) agent_disconnected;
+
+ Data agent_data;
+
+ message {
+ uint32 num_tokens;
+ } @ctype(SpiceMsgMainAgentTokens) agent_token;
+
+ message {
+ uint16 port;
+ uint16 sport;
+ uint32 host_size;
+ uint8 *host_data[host_size] @zero_terminated @marshall;
+ uint32 cert_subject_size;
+ uint8 *cert_subject_data[cert_subject_size] @zero_terminated @marshall;
+ } @ctype(SpiceMsgMainMigrationSwitchHost) migrate_switch_host;
+
+ Empty migrate_end;
+
+ message {
+ uint32 name_len;
+ uint8 name[name_len] @end;
+ } name;
+
+ message {
+ uint8 uuid[16];
+ } uuid;
+
+ message {
+ uint32 num_tokens;
+ } agent_connected_tokens;
+
+ message {
+ DstInfo dst_info;
+ uint32 src_mig_version;
+ } migrate_begin_seamless;
+
+ Empty migrate_dst_seamless_ack;
+ Empty migrate_dst_seamless_nack;
+
+ client:
+ message {
+ uint64 cache_size;
+ } @ctype(SpiceMsgcClientInfo) client_info = 101;
+
+ Empty migrate_connected;
+
+ Empty migrate_connect_error;
+
+ Empty attach_channels;
+
+ message {
+ mouse_mode mode;
+ } mouse_mode_request;
+
+ message {
+ uint32 num_tokens;
+ } agent_start;
+
+ Data agent_data;
+
+ message {
+ uint32 num_tokens;
+ } @ctype(SpiceMsgcMainAgentTokens) agent_token;
+
+ Empty migrate_end;
+
+ message {
+ uint32 src_version;
+ } migrate_dst_do_seamless;
+
+ Empty migrate_connected_seamless;
+};
+
+enum8 clip_type {
+ NONE,
+ RECTS
+};
+
+flags8 path_flags { /* TODO: C enum names changes */
+ BEGIN = 0,
+ END = 1,
+ CLOSE = 3,
+ BEZIER = 4,
+} @prefix(SPICE_PATH_);
+
+enum8 video_codec_type {
+ MJPEG = 1,
+ VP8,
+ H264,
+};
+
+flags8 stream_flags {
+ TOP_DOWN = 0,
+};
+
+enum8 brush_type {
+ NONE,
+ SOLID,
+ PATTERN,
+};
+
+flags8 mask_flags {
+ INVERS,
+};
+
+enum8 image_type {
+ BITMAP,
+ QUIC,
+ RESERVED,
+ LZ_PLT = 100,
+ LZ_RGB,
+ GLZ_RGB,
+ FROM_CACHE,
+ SURFACE,
+ JPEG,
+ FROM_CACHE_LOSSLESS,
+ ZLIB_GLZ_RGB,
+ JPEG_ALPHA,
+ LZ4,
+};
+
+enum8 image_compression {
+ INVALID = 0,
+ OFF,
+ AUTO_GLZ,
+ AUTO_LZ,
+ QUIC,
+ GLZ,
+ LZ,
+ LZ4,
+};
+
+flags8 image_flags {
+ CACHE_ME,
+ HIGH_BITS_SET,
+ CACHE_REPLACE_ME,
+};
+
+enum8 bitmap_fmt {
+ INVALID,
+ 1BIT_LE,
+ 1BIT_BE,
+ 4BIT_LE,
+ 4BIT_BE,
+ 8BIT /* 8bit indexed mode */,
+ 16BIT, /* 0555 mode */
+ 24BIT /* 3 byte, brg */,
+ 32BIT /* 4 byte, xrgb in little endian format */,
+ RGBA /* 4 byte, argb in little endian format */,
+ 8BIT_A /* 1 byte, alpha */
+};
+
+flags8 bitmap_flags {
+ PAL_CACHE_ME,
+ PAL_FROM_CACHE,
+ TOP_DOWN,
+};
+
+flags8 jpeg_alpha_flags {
+ TOP_DOWN,
+};
+
+enum8 image_scale_mode {
+ INTERPOLATE,
+ NEAREST,
+};
+
+flags16 ropd {
+ INVERS_SRC,
+ INVERS_BRUSH,
+ INVERS_DEST,
+ OP_PUT,
+ OP_OR,
+ OP_AND,
+ OP_XOR,
+ OP_BLACKNESS,
+ OP_WHITENESS,
+ OP_INVERS,
+ INVERS_RES,
+};
+
+/* This *must* remain with values identical to api/winddi.h
+ LA_STYLED == 0x8 (log_2)=> 3
+ LA_STARTGAP == 0x4 (log_2)=> 2
+ This is used by the windows driver.
+ */
+flags8 line_flags {
+ STYLED = 3,
+ START_WITH_GAP = 2,
+};
+
+flags8 string_flags {
+ RASTER_A1,
+ RASTER_A4,
+ RASTER_A8,
+ RASTER_TOP_DOWN,
+};
+
+flags32 surface_flags {
+ /* Adding flags requires some caps check, since old clients only
+ treat the value as an enum and not as a flag (flag == PRIMARY) */
+ PRIMARY
+};
+
+enum32 surface_fmt {
+ INVALID,
+ 1_A = 1,
+ 8_A = 8,
+ 16_555 = 16 ,
+ 16_565 = 80,
+ 32_xRGB = 32,
+ 32_ARGB = 96
+};
+
+flags8 alpha_flags {
+ DEST_HAS_ALPHA,
+ SRC_SURFACE_HAS_ALPHA
+};
+
+enum8 resource_type {
+ INVALID,
+ PIXMAP
+} @prefix(SPICE_RES_TYPE_);
+
+struct ClipRects {
+ uint32 num_rects;
+ Rect rects[num_rects] @end;
+};
+
+struct PathSegment {
+ path_flags flags;
+ uint32 count;
+ PointFix points[count] @end;
+} @ctype(SpicePathSeg);
+
+struct Path {
+ uint32 num_segments;
+ PathSegment segments[num_segments] @ptr_array;
+};
+
+struct Clip {
+ clip_type type;
+ switch (type) {
+ case RECTS:
+ ClipRects rects @outvar(cliprects) @to_ptr;
+ } u @anon;
+};
+
+struct DisplayBase {
+ uint32 surface_id;
+ Rect box;
+ Clip clip;
+} @ctype(SpiceMsgDisplayBase);
+
+struct ResourceID {
+ uint8 type;
+ uint64 id;
+};
+
+struct WaitForChannel {
+ uint8 channel_type;
+ uint8 channel_id;
+ uint64 message_serial;
+};
+
+struct Palette {
+ uint64 unique;
+ uint16 num_ents;
+ uint32 ents[num_ents] @end;
+};
+
+struct BitmapData {
+ bitmap_fmt format;
+ bitmap_flags flags;
+ uint32 x;
+ uint32 y;
+ uint32 stride;
+ switch (flags) {
+ case PAL_FROM_CACHE:
+ uint64 palette_id;
+ default:
+ Palette *palette @outvar(bitmap);
+ } pal @anon;
+ uint8 data[image_size(8, stride, y)] @chunk @nomarshal;
+} @ctype(SpiceBitmap);
+
+struct BinaryData {
+ uint32 data_size;
+ uint8 data[data_size] @nomarshal @chunk;
+} @ctype(SpiceQUICData);
+
+struct LZPLTData {
+ bitmap_flags flags;
+ uint32 data_size;
+ switch (flags) {
+ case PAL_FROM_CACHE:
+ uint64 palette_id;
+ default:
+ Palette *palette @nonnull @outvar(lzplt);
+ } pal @anon;
+ uint8 data[data_size] @nomarshal @chunk;
+};
+
+struct ZlibGlzRGBData {
+ uint32 glz_data_size;
+ uint32 data_size;
+ uint8 data[data_size] @nomarshal @chunk;
+} @ctype(SpiceZlibGlzRGBData);
+
+struct JPEGAlphaData {
+ jpeg_alpha_flags flags;
+ uint32 jpeg_size;
+ uint32 data_size;
+ uint8 data[data_size] @nomarshal @chunk;
+} @ctype(SpiceJPEGAlphaData);
+
+struct Surface {
+ uint32 surface_id;
+};
+
+
+struct Image {
+ struct ImageDescriptor {
+ uint64 id;
+ image_type type;
+ image_flags flags;
+ uint32 width;
+ uint32 height;
+ } descriptor;
+
+ switch (descriptor.type) {
+ case BITMAP:
+ BitmapData bitmap;
+ case QUIC:
+ BinaryData quic;
+ case LZ_RGB:
+ case GLZ_RGB:
+ BinaryData lz_rgb;
+ case JPEG:
+ BinaryData jpeg;
+ case LZ4:
+ BinaryData lz4;
+ case LZ_PLT:
+ LZPLTData lz_plt;
+ case ZLIB_GLZ_RGB:
+ ZlibGlzRGBData zlib_glz;
+ case JPEG_ALPHA:
+ JPEGAlphaData jpeg_alpha;
+ case SURFACE:
+ Surface surface;
+ } u;
+};
+
+struct Pattern {
+ Image *pat @nonnull;
+ Point pos;
+};
+
+struct Brush {
+ brush_type type;
+ switch (type) {
+ case SOLID:
+ uint32 color;
+ case PATTERN:
+ Pattern pattern;
+ } u;
+};
+
+struct QMask {
+ mask_flags flags;
+ Point pos;
+ Image *bitmap;
+};
+
+struct LineAttr {
+ line_flags flags;
+ switch (flags) {
+ case STYLED:
+ uint8 style_nseg;
+ } u1 @anon;
+ switch (flags) {
+ case STYLED:
+ fixed28_4 *style[style_nseg];
+ } u2 @anon;
+};
+
+struct RasterGlyphA1 {
+ Point render_pos;
+ Point glyph_origin;
+ uint16 width;
+ uint16 height;
+ uint8 data[image_size(1, width, height)] @end;
+} @ctype(SpiceRasterGlyph);
+
+struct RasterGlyphA4 {
+ Point render_pos;
+ Point glyph_origin;
+ uint16 width;
+ uint16 height;
+ uint8 data[image_size(4, width, height)] @end;
+} @ctype(SpiceRasterGlyph);
+
+struct RasterGlyphA8 {
+ Point render_pos;
+ Point glyph_origin;
+ uint16 width;
+ uint16 height;
+ uint8 data[image_size(8, width, height)] @end;
+} @ctype(SpiceRasterGlyph);
+
+struct String {
+ uint16 length;
+ string_flags flags; /* Special: Only one of a1/a4/a8 set */
+ switch (flags) {
+ case RASTER_A1:
+ RasterGlyphA1 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array;
+ case RASTER_A4:
+ RasterGlyphA4 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array;
+ case RASTER_A8:
+ RasterGlyphA8 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array;
+ } u @anon;
+};
+
+struct StreamDataHeader {
+ uint32 id;
+ uint32 multi_media_time;
+};
+
+struct Head {
+ uint32 id;
+ uint32 surface_id;
+ uint32 width;
+ uint32 height;
+ uint32 x;
+ uint32 y;
+ uint32 flags;
+};
+
+flags32 gl_scanout_flags {
+ Y0TOP
+};
+
+channel DisplayChannel : BaseChannel {
+ server:
+ message {
+ uint32 x_res;
+ uint32 y_res;
+ uint32 bits;
+ } mode = 101;
+
+ Empty mark;
+ Empty reset;
+ message {
+ DisplayBase base;
+ Point src_pos;
+ } copy_bits;
+
+ message {
+ uint16 count;
+ ResourceID resources[count] @end;
+ } @ctype(SpiceResourceList) inval_list;
+
+ message {
+ uint8 wait_count;
+ WaitForChannel wait_list[wait_count] @end;
+ } @ctype(SpiceMsgWaitForChannels) inval_all_pixmaps;
+
+ message {
+ uint64 id;
+ } @ctype(SpiceMsgDisplayInvalOne) inval_palette;
+
+ Empty inval_all_palettes;
+
+ message {
+ uint32 surface_id;
+ uint32 id;
+ stream_flags flags;
+ video_codec_type codec_type;
+ uint64 stamp;
+ uint32 stream_width;
+ uint32 stream_height;
+ uint32 src_width;
+ uint32 src_height;
+ Rect dest;
+ Clip clip;
+ } stream_create = 122;
+
+ message {
+ StreamDataHeader base;
+ uint32 data_size;
+ uint8 data[data_size] @end @nomarshal;
+ } stream_data;
+
+ message {
+ uint32 id;
+ Clip clip;
+ } stream_clip;
+
+ message {
+ uint32 id;
+ } stream_destroy;
+
+ Empty stream_destroy_all;
+
+ message {
+ DisplayBase base;
+ struct Fill {
+ Brush brush @outvar(brush);
+ ropd rop_descriptor;
+ QMask mask @outvar(mask);
+ } data;
+ } draw_fill = 302;
+
+ message {
+ DisplayBase base;
+ struct Opaque {
+ Image *src_bitmap;
+ Rect src_area;
+ Brush brush;
+ ropd rop_descriptor;
+ image_scale_mode scale_mode;
+ QMask mask @outvar(mask);
+ } data;
+ } draw_opaque;
+
+ message {
+ DisplayBase base;
+ struct Copy {
+ Image *src_bitmap;
+ Rect src_area;
+ ropd rop_descriptor;
+ image_scale_mode scale_mode;
+ QMask mask @outvar(mask);
+ } data;
+ } draw_copy;
+
+ message {
+ DisplayBase base;
+ struct Blend {
+ Image *src_bitmap;
+ Rect src_area;
+ ropd rop_descriptor;
+ image_scale_mode scale_mode;
+ QMask mask @outvar(mask);
+ } @ctype(SpiceCopy) data;
+ } draw_blend;
+
+ message {
+ DisplayBase base;
+ struct Blackness {
+ QMask mask @outvar(mask);
+ } data;
+ } draw_blackness;
+
+ message {
+ DisplayBase base;
+ struct Whiteness {
+ QMask mask @outvar(mask);
+ } data;
+ } draw_whiteness;
+
+ message {
+ DisplayBase base;
+ struct Invers {
+ QMask mask @outvar(mask);
+ } data;
+ } draw_invers;
+
+ message {
+ DisplayBase base;
+ struct Rop3 {
+ Image *src_bitmap;
+ Rect src_area;
+ Brush brush;
+ uint8 rop3;
+ image_scale_mode scale_mode;
+ QMask mask @outvar(mask);
+ } data;
+ } draw_rop3;
+
+ message {
+ DisplayBase base;
+ struct Stroke {
+ Path *path @marshall @nonnull;
+ LineAttr attr;
+ Brush brush;
+ uint16 fore_mode;
+ uint16 back_mode;
+ } data;
+ } draw_stroke;
+
+ message {
+ DisplayBase base;
+ struct Text {
+ String *str @marshall @nonnull;
+ Rect back_area;
+ Brush fore_brush @outvar(fore_brush);
+ Brush back_brush @outvar(back_brush);
+ uint16 fore_mode;
+ uint16 back_mode;
+ } data;
+ } draw_text;
+
+ message {
+ DisplayBase base;
+ struct Transparent {
+ Image *src_bitmap;
+ Rect src_area;
+ uint32 src_color;
+ uint32 true_color;
+ } data;
+ } draw_transparent;
+
+ message {
+ DisplayBase base;
+ struct AlphaBlend {
+ alpha_flags alpha_flags;
+ uint8 alpha;
+ Image *src_bitmap;
+ Rect src_area;
+ } data;
+ } draw_alpha_blend;
+
+ message {
+ uint32 surface_id;
+ uint32 width;
+ uint32 height;
+ surface_fmt format;
+ surface_flags flags;
+ } @ctype(SpiceMsgSurfaceCreate) surface_create;
+
+ message {
+ uint32 surface_id;
+ } @ctype(SpiceMsgSurfaceDestroy) surface_destroy;
+
+ message {
+ StreamDataHeader base;
+ uint32 width;
+ uint32 height;
+ Rect dest;
+ uint32 data_size;
+ uint8 data[data_size] @end @nomarshal;
+ } stream_data_sized;
+
+ message {
+ uint16 count;
+ uint16 max_allowed;
+ Head heads[count] @end;
+ } monitors_config;
+
+ message {
+ DisplayBase base;
+ struct Composite {
+ composite_flags flags;
+ Image *src_bitmap;
+ switch (flags) {
+ case HAS_MASK:
+ Image *mask_bitmap;
+ } a @anon;
+ switch (flags) {
+ case HAS_SRC_TRANSFORM:
+ Transform src_transform;
+ } b @anon;
+ switch (flags) {
+ case HAS_MASK_TRANSFORM:
+ Transform mask_transform;
+ } c @anon;
+ Point16 src_origin;
+ Point16 mask_origin;
+ } data;
+ } draw_composite;
+
+ message {
+ uint32 stream_id;
+ uint32 unique_id;
+ uint32 max_window_size;
+ uint32 timeout_ms;
+ } stream_activate_report;
+
+ message {
+ unix_fd drm_dma_buf_fd;
+ uint32 width;
+ uint32 height;
+ uint32 stride;
+ /* specifies the format of drm_dma_buf_fd defined in drm_fourcc.h */
+ uint32 drm_fourcc_format;
+ gl_scanout_flags flags;
+ } gl_scanout_unix;
+
+ message {
+ uint32 x;
+ uint32 y;
+ uint32 w;
+ uint32 h;
+ } gl_draw;
+
+ client:
+ message {
+ uint8 pixmap_cache_id;
+ int64 pixmap_cache_size; //in pixels
+ uint8 glz_dictionary_id;
+ int32 glz_dictionary_window_size; // in pixels
+ } init = 101;
+
+ message {
+ uint32 stream_id;
+ uint32 unique_id;
+ uint32 start_frame_mm_time;
+ uint32 end_frame_mm_time;
+ uint32 num_frames;
+ uint32 num_drops;
+ int32 last_frame_delay;
+ uint32 audio_delay;
+ } stream_report;
+
+ message {
+ image_compression image_compression;
+ } preferred_compression;
+
+ message {
+ } gl_draw_done;
+};
+
+flags16 keyboard_modifier_flags {
+ SCROLL_LOCK,
+ NUM_LOCK,
+ CAPS_LOCK
+};
+
+enum8 mouse_button {
+ INVALID,
+ LEFT,
+ MIDDLE,
+ RIGHT,
+ UP,
+ DOWN,
+};
+
+flags16 mouse_button_mask {
+ LEFT,
+ MIDDLE,
+ RIGHT
+};
+
+channel InputsChannel : BaseChannel {
+ client:
+ message {
+ uint32 code;
+ } @ctype(SpiceMsgcKeyDown) key_down = 101;
+
+ message {
+ uint32 code;
+ } @ctype(SpiceMsgcKeyUp) key_up;
+
+ message {
+ keyboard_modifier_flags modifiers;
+ } @ctype(SpiceMsgcKeyModifiers) key_modifiers;
+
+ Data key_scancode;
+
+ message {
+ int32 dx;
+ int32 dy;
+ mouse_button_mask buttons_state;
+ } @ctype(SpiceMsgcMouseMotion) mouse_motion = 111;
+
+ message {
+ uint32 x;
+ uint32 y;
+ mouse_button_mask buttons_state;
+ uint8 display_id;
+ } @ctype(SpiceMsgcMousePosition) mouse_position;
+
+ message {
+ mouse_button button;
+ mouse_button_mask buttons_state;
+ } @ctype(SpiceMsgcMousePress) mouse_press;
+
+ message {
+ mouse_button button;
+ mouse_button_mask buttons_state;
+ } @ctype(SpiceMsgcMouseRelease) mouse_release;
+
+ server:
+ message {
+ keyboard_modifier_flags keyboard_modifiers;
+ } init = 101;
+
+ message {
+ keyboard_modifier_flags modifiers;
+ } key_modifiers;
+
+ Empty mouse_motion_ack = 111;
+};
+
+enum8 cursor_type {
+ ALPHA,
+ MONO,
+ COLOR4,
+ COLOR8,
+ COLOR16,
+ COLOR24,
+ COLOR32,
+};
+
+flags16 cursor_flags {
+ NONE, /* Means no cursor */
+ CACHE_ME,
+ FROM_CACHE,
+};
+
+struct CursorHeader {
+ uint64 unique;
+ cursor_type type;
+ uint16 width;
+ uint16 height;
+ uint16 hot_spot_x;
+ uint16 hot_spot_y;
+};
+
+struct Cursor {
+ cursor_flags flags;
+ switch (flags) {
+ case !NONE:
+ CursorHeader header;
+ } u @anon;
+ uint8 data[] @as_ptr(data_size);
+};
+
+channel CursorChannel : BaseChannel {
+ server:
+ message {
+ Point16 position;
+ uint16 trail_length;
+ uint16 trail_frequency;
+ uint8 visible;
+ Cursor cursor;
+ } init = 101;
+
+ Empty reset;
+
+ message {
+ Point16 position;
+ uint8 visible;
+ Cursor cursor;
+ } set;
+
+ message {
+ Point16 position;
+ } move;
+
+ Empty hide;
+
+ message {
+ uint16 length;
+ uint16 frequency;
+ } trail;
+
+ message {
+ uint64 id;
+ } @ctype(SpiceMsgDisplayInvalOne) inval_one;
+
+ Empty inval_all;
+};
+
+enum16 audio_data_mode {
+ INVALID,
+ RAW,
+ CELT_0_5_1,
+ OPUS,
+};
+
+enum16 audio_fmt {
+ INVALID,
+ S16,
+};
+
+message AudioVolume {
+ uint8 nchannels;
+ uint16 volume[nchannels] @end;
+};
+
+message AudioMute {
+ uint8 mute;
+};
+
+channel PlaybackChannel : BaseChannel {
+ server:
+ message {
+ uint32 time;
+ uint8 data[] @as_ptr(data_size);
+ } @ctype(SpiceMsgPlaybackPacket) data = 101;
+
+ message {
+ uint32 time;
+ audio_data_mode mode;
+ uint8 data[] @as_ptr(data_size);
+ } mode;
+
+ message {
+ uint32 channels;
+ audio_fmt format;
+ uint32 frequency;
+ uint32 time;
+ } start;
+
+ Empty stop;
+ AudioVolume volume;
+ AudioMute mute;
+
+ message {
+ uint32 latency_ms;
+ } latency;
+};
+
+channel RecordChannel : BaseChannel {
+ server:
+ message {
+ uint32 channels;
+ audio_fmt format;
+ uint32 frequency;
+ } start = 101;
+
+ Empty stop;
+ AudioVolume volume;
+ AudioMute mute;
+ client:
+ message {
+ uint32 time;
+ uint8 data[] @nomarshal @as_ptr(data_size);
+ } @ctype(SpiceMsgcRecordPacket) data = 101;
+
+ message {
+ uint32 time;
+ audio_data_mode mode;
+ uint8 data[] @as_ptr(data_size);
+ } mode;
+
+ message {
+ uint32 time;
+ } start_mark;
+};
+
+enum16 tunnel_service_type {
+ INVALID,
+ GENERIC,
+ IPP,
+};
+
+enum16 tunnel_ip_type {
+ INVALID,
+ IPv4,
+};
+
+struct TunnelIpInfo {
+ tunnel_ip_type type;
+ switch (type) {
+ case IPv4:
+ uint8 ipv4[4];
+ } u;
+} @ctype(SpiceMsgTunnelIpInfo);
+
+channel TunnelChannel : BaseChannel {
+ server:
+ message {
+ uint16 max_num_of_sockets;
+ uint32 max_socket_data_size;
+ } init = 101;
+
+ message {
+ uint32 service_id;
+ TunnelIpInfo virtual_ip;
+ } service_ip_map;
+
+ message {
+ uint16 connection_id;
+ uint32 service_id;
+ uint32 tokens;
+ } socket_open;
+
+ message {
+ uint16 connection_id;
+ } socket_fin;
+
+ message {
+ uint16 connection_id;
+ } socket_close;
+
+ message {
+ uint16 connection_id;
+ uint8 data[] @end;
+ } socket_data;
+
+ message {
+ uint16 connection_id;
+ } socket_closed_ack;
+
+ message {
+ uint16 connection_id;
+ uint32 num_tokens;
+ } @ctype(SpiceMsgTunnelSocketTokens) socket_token;
+
+ client:
+ message {
+ tunnel_service_type type;
+ uint32 id;
+ uint32 group;
+ uint32 port;
+ uint8 *name[cstring()] @nocopy;
+ uint8 *description[cstring()] @nocopy;
+ switch (type) {
+ case IPP:
+ TunnelIpInfo ip @ctype(SpiceMsgTunnelIpInfo);
+ } u;
+ } @ctype(SpiceMsgcTunnelAddGenericService) service_add = 101;
+
+ message {
+ uint32 id;
+ } @ctype(SpiceMsgcTunnelRemoveService) service_remove;
+
+ message {
+ uint16 connection_id;
+ uint32 tokens;
+ } socket_open_ack;
+
+ message {
+ uint16 connection_id;
+ } socket_open_nack;
+
+ message {
+ uint16 connection_id;
+ } socket_fin;
+
+ message {
+ uint16 connection_id;
+ } socket_closed;
+
+ message {
+ uint16 connection_id;
+ } socket_closed_ack;
+
+ message {
+ uint16 connection_id;
+ uint8 data[] @end;
+ } socket_data;
+
+ message {
+ uint16 connection_id;
+ uint32 num_tokens;
+ } @ctype(SpiceMsgcTunnelSocketTokens) socket_token;
+};
+
+enum32 vsc_message_type {
+ Init = 1,
+ Error,
+ ReaderAdd,
+ ReaderRemove,
+ ATR,
+ CardRemove,
+ APDU,
+ Flush,
+ FlushComplete
+};
+
+struct VscMessageHeader {
+ vsc_message_type type;
+ uint32 reader_id;
+ uint32 length;
+} @ctype(VSCMsgHeader);
+
+struct VscMessageError {
+ uint32 code;
+} @ctype(VSCMsgError);
+
+struct VscMessageAPDU {
+ uint8 data[];
+} @ctype(VSCMsgAPDU);
+
+struct VscMessageATR {
+ uint8 data[];
+} @ctype(VSCMsgATR);
+
+struct VscMessageReaderAdd {
+ int8 *reader_name[] @zero_terminated @nonnull @end @nomarshal;
+} @ctype(VSCMsgReaderAdd);
+
+channel SmartcardChannel : BaseChannel {
+ server:
+ message {
+ vsc_message_type type;
+ uint32 reader_id;
+ uint32 length;
+ uint8 data[length] @end @nomarshal;
+ } @ctype(SpiceMsgSmartcard) data = 101;
+
+ client:
+ message {
+ VscMessageHeader header;
+ switch (header.type) {
+ case ReaderAdd:
+ VscMessageReaderAdd add;
+ case ATR:
+ case APDU:
+ VscMessageATR atr_data;
+ case Error:
+ VscMessageError error;
+ } u @anon;
+ } @ctype(SpiceMsgcSmartcard) data = 101;
+
+ message {
+ vsc_message_type type;
+ uint32 reader_id;
+ uint32 length;
+ } @ctype(VSCMsgHeader) header = 101;
+
+ message {
+ uint32 code;
+ } @ctype(VSCMsgError) error = 101;
+
+ message {
+ uint8 data[];
+ } @ctype(VSCMsgATR) atr = 101;
+
+ message {
+ int8 reader_name[] @zero_terminated @nonnull;
+ } @ctype(VSCMsgReaderAdd) reader_add = 101;
+} @ifdef(USE_SMARTCARD);
+
+channel SpicevmcChannel : BaseChannel {
+server:
+ Data data = 101;
+ CompressedData compressed_data = 102;
+client:
+ Data data = 101;
+ CompressedData compressed_data = 102;
+};
+
+channel UsbredirChannel : SpicevmcChannel {
+};
+
+channel PortChannel : SpicevmcChannel {
+ client:
+ message {
+ uint8 event;
+ } event = 201;
+ server:
+ message {
+ uint32 name_size;
+ uint8 *name[name_size] @zero_terminated @marshall @nonnull;
+ uint8 opened;
+ } init = 201;
+ message {
+ uint8 event;
+ } event;
+};
+
+channel WebDAVChannel : PortChannel {
+};
+
+protocol Spice {
+ MainChannel main = 1;
+ DisplayChannel display;
+ InputsChannel inputs;
+ CursorChannel cursor;
+ PlaybackChannel playback;
+ RecordChannel record;
+ TunnelChannel tunnel;
+ SmartcardChannel smartcard;
+ UsbredirChannel usbredir;
+ PortChannel port;
+ WebDAVChannel webdav;
+};
--- /dev/null
+/* built in types:
+ int8, uint8, 16, 32, 64
+*/
+
+typedef fixed28_4 int32 @ctype(SPICE_FIXED28_4);
+
+struct Point {
+ int32 x;
+ int32 y;
+};
+
+struct Point16 {
+ int16 x;
+ int16 y;
+};
+
+struct PointFix {
+ fixed28_4 x;
+ fixed28_4 y;
+};
+
+struct Rect {
+ int32 top;
+ int32 left;
+ int32 bottom;
+ int32 right;
+};
+
+enum32 link_err {
+ OK,
+ ERROR,
+ INVALID_MAGIC,
+ INVALID_DATA,
+ VERSION_MISMATCH,
+ NEED_SECURED,
+ NEED_UNSECURED,
+ PERMISSION_DENIED,
+ BAD_CONNECTION_ID,
+ CHANNEL_NOT_AVAILABLE
+};
+
+enum32 warn_code {
+ WARN_GENERAL
+} @prefix(SPICE_);
+
+enum32 info_code {
+ INFO_GENERAL
+} @prefix(SPICE_);
+
+flags32 migrate_flags {
+ NEED_FLUSH,
+ NEED_DATA_TRANSFER
+} @prefix(SPICE_MIGRATE_);
+
+enum32 notify_severity {
+ INFO,
+ WARN,
+ ERROR,
+};
+
+enum32 notify_visibility {
+ LOW,
+ MEDIUM,
+ HIGH,
+};
+
+flags32 mouse_mode {
+ SERVER,
+ CLIENT,
+};
+
+enum16 pubkey_type {
+ INVALID,
+ RSA,
+ RSA2,
+ DSA,
+ DSA1,
+ DSA2,
+ DSA3,
+ DSA4,
+ DH,
+ EC,
+};
+
+message Empty {
+};
+
+message Data {
+ uint8 data[] @end @ctype(uint8_t);
+} @nocopy;
+
+struct ChannelWait {
+ uint8 channel_type;
+ uint8 channel_id;
+ uint64 message_serial;
+} @ctype(SpiceWaitForChannel);
+
+channel BaseChannel {
+ server:
+ message {
+ migrate_flags flags;
+ } migrate;
+
+ Data migrate_data;
+
+ message {
+ uint32 generation;
+ uint32 window;
+ } set_ack;
+
+ message {
+ uint32 id;
+ uint64 timestamp;
+ uint8 data[] @ctype(uint8_t) @as_ptr(data_len);
+ } ping;
+
+ message {
+ uint8 wait_count;
+ ChannelWait wait_list[wait_count] @end;
+ } wait_for_channels;
+
+ message {
+ uint64 time_stamp;
+ link_err reason;
+ } @ctype(SpiceMsgDisconnect) disconnecting;
+
+ message {
+ uint64 time_stamp;
+ notify_severity severity;
+ notify_visibility visibilty;
+ uint32 what; /* error_code/warn_code/info_code */
+ uint32 message_len;
+ uint8 message[message_len] @end @nomarshal;
+ uint8 zero @end @ctype(uint8_t) @nomarshal;
+ } notify;
+
+ client:
+ message {
+ uint32 generation;
+ } ack_sync;
+
+ Empty ack;
+
+ message {
+ uint32 id;
+ uint64 timestamp;
+ } @ctype(SpiceMsgPing) pong;
+
+ Empty migrate_flush_mark;
+
+ Data migrate_data;
+
+ message {
+ uint64 time_stamp;
+ link_err reason;
+ } @ctype(SpiceMsgDisconnect) disconnecting;
+};
+
+struct ChannelId {
+ uint8 type;
+ uint8 id;
+};
+
+struct DstInfo {
+ uint16 port;
+ uint16 sport;
+ uint32 host_offset @zero;
+ uint32 host_size;
+ pubkey_type pub_key_type @minor(1);
+ uint32 pub_key_offset @minor(1) @zero;
+ uint32 pub_key_size @minor(1);
+ uint8 host_data[host_size] @as_ptr @zero_terminated;
+ uint8 pub_key_data[pub_key_size] @minor(1) @as_ptr @zero_terminated;
+} @ctype(SpiceMigrationDstInfo);
+
+channel MainChannel : BaseChannel {
+ server:
+ message {
+ DstInfo dst_info;
+ } @ctype(SpiceMsgMainMigrationBegin) migrate_begin = 101;
+
+ Empty migrate_cancel;
+
+ message {
+ uint32 session_id;
+ uint32 display_channels_hint;
+ uint32 supported_mouse_modes;
+ uint32 current_mouse_mode;
+ uint32 agent_connected;
+ uint32 agent_tokens;
+ uint32 multi_media_time;
+ uint32 ram_hint;
+ } init;
+
+ message {
+ uint32 num_of_channels;
+ ChannelId channels[num_of_channels] @end;
+ } @ctype(SpiceMsgChannels) channels_list;
+
+ message {
+ mouse_mode supported_modes;
+ mouse_mode current_mode @unique_flag;
+ } mouse_mode;
+
+ message {
+ uint32 time;
+ } @ctype(SpiceMsgMainMultiMediaTime) multi_media_time;
+
+ Empty agent_connected;
+
+ message {
+ link_err error_code;
+ } @ctype(SpiceMsgMainAgentDisconnect) agent_disconnected;
+
+ Data agent_data;
+
+ message {
+ uint32 num_tokens;
+ } @ctype(SpiceMsgMainAgentTokens) agent_token;
+
+ message {
+ uint16 port;
+ uint16 sport;
+ uint32 host_offset @zero;
+ uint32 host_size;
+ uint32 cert_subject_offset @zero;
+ uint32 cert_subject_size;
+ uint8 host_data[host_size] @as_ptr @zero_terminated;
+ uint8 cert_subject_data[cert_subject_size] @as_ptr @zero_terminated;
+ } @ctype(SpiceMsgMainMigrationSwitchHost) migrate_switch_host;
+
+ client:
+ message {
+ uint64 cache_size;
+ } @ctype(SpiceMsgcClientInfo) client_info = 101;
+
+ Empty migrate_connected;
+
+ Empty migrate_connect_error;
+
+ Empty attach_channels;
+
+ message {
+ mouse_mode mode;
+ } mouse_mode_request;
+
+ message {
+ uint32 num_tokens;
+ } agent_start;
+
+ Data agent_data;
+
+ message {
+ uint32 num_tokens;
+ } @ctype(SpiceMsgcMainAgentTokens) agent_token;
+};
+
+enum32 clip_type {
+ NONE,
+ RECTS
+};
+
+flags32 path_flags { /* TODO: C enum names changes */
+ BEGIN = 0,
+ END = 1,
+ CLOSE = 3,
+ BEZIER = 4,
+} @prefix(SPICE_PATH_);
+
+enum32 video_codec_type {
+ MJPEG = 1,
+};
+
+flags32 stream_flags {
+ TOP_DOWN = 0,
+};
+
+enum32 brush_type {
+ NONE,
+ SOLID,
+ PATTERN,
+};
+
+flags8 mask_flags {
+ INVERS,
+};
+
+enum8 image_type {
+ BITMAP,
+ QUIC,
+ RESERVED,
+ LZ_PLT = 100,
+ LZ_RGB,
+ GLZ_RGB,
+ FROM_CACHE,
+};
+
+flags8 image_flags {
+ CACHE_ME,
+};
+
+enum8 bitmap_fmt {
+ INVALID,
+ 1BIT_LE,
+ 1BIT_BE,
+ 4BIT_LE,
+ 4BIT_BE,
+ 8BIT /* 8bit indexed mode */,
+ 16BIT, /* 0555 mode */
+ 24BIT /* 3 byte, brg */,
+ 32BIT /* 4 byte, xrgb in little endian format */,
+ RGBA /* 4 byte, argb in little endian format */
+};
+
+flags8 bitmap_flags {
+ PAL_CACHE_ME,
+ PAL_FROM_CACHE,
+ TOP_DOWN,
+};
+
+enum8 image_scale_mode {
+ INTERPOLATE,
+ NEAREST,
+};
+
+flags16 ropd {
+ INVERS_SRC,
+ INVERS_BRUSH,
+ INVERS_DEST,
+ OP_PUT,
+ OP_OR,
+ OP_AND,
+ OP_XOR,
+ OP_BLACKNESS,
+ OP_WHITENESS,
+ OP_INVERS,
+ INVERS_RES,
+};
+
+flags8 line_flags {
+ STYLED = 3,
+ START_WITH_GAP = 2,
+};
+
+enum8 line_cap {
+ ROUND,
+ SQUARE,
+ BUTT,
+};
+
+enum8 line_join {
+ ROUND,
+ BEVEL,
+ MITER,
+};
+
+flags16 string_flags {
+ RASTER_A1,
+ RASTER_A4,
+ RASTER_A8,
+ RASTER_TOP_DOWN,
+};
+
+enum8 resource_type {
+ INVALID,
+ PIXMAP
+} @prefix(SPICE_RES_TYPE_);
+
+struct ClipRects {
+ uint32 num_rects;
+ Rect rects[num_rects] @end;
+};
+
+struct PathSegment {
+ path_flags flags;
+ uint32 count;
+ PointFix points[count] @end;
+} @ctype(SpicePathSeg);
+
+struct Path {
+ uint32 segments_size @bytes_count(num_segments);
+ PathSegment segments[bytes(segments_size, num_segments)] @ptr_array;
+};
+
+struct Clip {
+ clip_type type;
+ switch (type) {
+ case RECTS:
+ ClipRects *rects @outvar(cliprects);
+ default:
+ uint64 data @zero;
+ } u @anon;
+};
+
+struct DisplayBase {
+ uint32 surface_id @virtual(0);
+ Rect box;
+ Clip clip;
+} @ctype(SpiceMsgDisplayBase);
+
+struct ResourceID {
+ uint8 type;
+ uint64 id;
+};
+
+struct WaitForChannel {
+ uint8 channel_type;
+ uint8 channel_id;
+ uint64 message_serial;
+};
+
+struct Palette {
+ uint64 unique;
+ uint16 num_ents;
+ uint32 ents[num_ents] @end;
+};
+
+struct BitmapData {
+ bitmap_fmt format;
+ bitmap_flags flags;
+ uint32 x;
+ uint32 y;
+ uint32 stride;
+ switch (flags) {
+ case PAL_FROM_CACHE:
+ uint64 palette_id;
+ default:
+ Palette *palette @outvar(bitmap);
+ } pal @anon;
+ uint8 *data[image_size(8, stride, y)] @chunk; /* pointer to array, not array of pointers as in C */
+} @ctype(SpiceBitmap);
+
+struct BinaryData {
+ uint32 data_size;
+ uint8 data[data_size] @nomarshal @chunk;
+} @ctype(SpiceQUICData);
+
+struct LZPLTData {
+ bitmap_flags flags;
+ uint32 data_size;
+ switch (flags) {
+ case PAL_FROM_CACHE:
+ uint64 palette_id;
+ default:
+ Palette *palette @nonnull @outvar(lzplt);
+ } pal @anon;
+ uint8 data[data_size] @nomarshal @chunk;
+};
+
+struct Image {
+ struct ImageDescriptor {
+ uint64 id;
+ image_type type;
+ image_flags flags;
+ uint32 width;
+ uint32 height;
+ } descriptor;
+
+ switch (descriptor.type) {
+ case BITMAP:
+ BitmapData bitmap;
+ case QUIC:
+ BinaryData quic;
+ case LZ_RGB:
+ case GLZ_RGB:
+ BinaryData lz_rgb;
+ case LZ_PLT:
+ LZPLTData lz_plt;
+ } u;
+};
+
+struct Pattern {
+ Image *pat @nonnull;
+ Point pos;
+};
+
+struct Brush {
+ brush_type type;
+ switch (type) {
+ case SOLID:
+ uint32 color;
+ case PATTERN:
+ Pattern pattern;
+ } u @fixedsize;
+};
+
+struct QMask {
+ mask_flags flags;
+ Point pos;
+ Image *bitmap;
+};
+
+struct LineAttr {
+ line_flags flags;
+ line_join join_style @zero;
+ line_cap end_style @zero;
+ uint8 style_nseg;
+ fixed28_4 width @zero;
+ fixed28_4 miter_limit @zero;
+ fixed28_4 *style[style_nseg];
+};
+
+struct RasterGlyphA1 {
+ Point render_pos;
+ Point glyph_origin;
+ uint16 width;
+ uint16 height;
+ uint8 data[image_size(1, width, height)] @end;
+} @ctype(SpiceRasterGlyph);
+
+struct RasterGlyphA4 {
+ Point render_pos;
+ Point glyph_origin;
+ uint16 width;
+ uint16 height;
+ uint8 data[image_size(4, width, height)] @end;
+} @ctype(SpiceRasterGlyph);
+
+struct RasterGlyphA8 {
+ Point render_pos;
+ Point glyph_origin;
+ uint16 width;
+ uint16 height;
+ uint8 data[image_size(8, width, height)] @end;
+} @ctype(SpiceRasterGlyph);
+
+struct String {
+ uint16 length;
+ string_flags flags; /* Special: Only one of a1/a4/a8 set */
+ switch (flags) {
+ case RASTER_A1:
+ RasterGlyphA1 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array;
+ case RASTER_A4:
+ RasterGlyphA4 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array;
+ case RASTER_A8:
+ RasterGlyphA8 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array;
+ } u @anon;
+};
+
+struct StreamDataHeader {
+ uint32 id;
+ uint32 multi_media_time;
+};
+
+channel DisplayChannel : BaseChannel {
+ server:
+ message {
+ uint32 x_res;
+ uint32 y_res;
+ uint32 bits;
+ } mode = 101;
+
+ Empty mark;
+ Empty reset;
+
+ message {
+ DisplayBase base;
+ Point src_pos;
+ } copy_bits;
+
+ message {
+ uint16 count;
+ ResourceID resources[count] @end;
+ } @ctype(SpiceResourceList) inval_list;
+
+ message {
+ uint8 wait_count;
+ WaitForChannel wait_list[wait_count] @end;
+ } @ctype(SpiceMsgWaitForChannels) inval_all_pixmaps;
+
+ message {
+ uint64 id;
+ } @ctype(SpiceMsgDisplayInvalOne) inval_palette;
+
+ Empty inval_all_palettes;
+
+ message {
+ uint32 surface_id @virtual(0);
+ uint32 id;
+ stream_flags flags;
+ video_codec_type codec_type;
+ uint64 stamp;
+ uint32 stream_width;
+ uint32 stream_height;
+ uint32 src_width;
+ uint32 src_height;
+ Rect dest;
+ Clip clip;
+ } stream_create = 122;
+
+ message {
+ StreamDataHeader base;
+ uint32 data_size;
+ uint32 pad_size @zero;
+ uint8 data[data_size] @end @nomarshal;
+ /* Ignore: uint8 padding[pad_size] */
+ } stream_data;
+
+ message {
+ uint32 id;
+ Clip clip;
+ } stream_clip;
+
+ message {
+ uint32 id;
+ } stream_destroy;
+
+ Empty stream_destroy_all;
+
+ message {
+ DisplayBase base;
+ struct Fill {
+ Brush brush @outvar(brush);
+ uint16 rop_descriptor;
+ QMask mask @outvar(mask);
+ } data;
+ } draw_fill = 302;
+
+ message {
+ DisplayBase base;
+ struct Opaque {
+ Image *src_bitmap;
+ Rect src_area;
+ Brush brush;
+ ropd rop_descriptor;
+ image_scale_mode scale_mode;
+ QMask mask @outvar(mask);
+ } data;
+ } draw_opaque;
+
+ message {
+ DisplayBase base;
+ struct Copy {
+ Image *src_bitmap;
+ Rect src_area;
+ ropd rop_descriptor;
+ image_scale_mode scale_mode;
+ QMask mask @outvar(mask);
+ } data;
+ } draw_copy;
+
+ message {
+ DisplayBase base;
+ struct Blend {
+ Image *src_bitmap;
+ Rect src_area;
+ ropd rop_descriptor;
+ image_scale_mode scale_mode;
+ QMask mask @outvar(mask);
+ } @ctype(SpiceCopy) data;
+ } draw_blend;
+
+ message {
+ DisplayBase base;
+ struct Blackness {
+ QMask mask @outvar(mask);
+ } data;
+ } draw_blackness;
+
+ message {
+ DisplayBase base;
+ struct Whiteness {
+ QMask mask @outvar(mask);
+ } data;
+ } draw_whiteness;
+
+ message {
+ DisplayBase base;
+ struct Invers {
+ QMask mask @outvar(mask);
+ } data;
+ } draw_invers;
+
+ message {
+ DisplayBase base;
+ struct Rop3 {
+ Image *src_bitmap;
+ Rect src_area;
+ Brush brush;
+ uint8 rop3;
+ image_scale_mode scale_mode;
+ QMask mask @outvar(mask);
+ } data;
+ } draw_rop3;
+
+ message {
+ DisplayBase base;
+ struct Stroke {
+ Path *path;
+ LineAttr attr;
+ Brush brush;
+ uint16 fore_mode;
+ uint16 back_mode;
+ } data;
+ } draw_stroke;
+
+ message {
+ DisplayBase base;
+ struct Text {
+ String *str;
+ Rect back_area;
+ Brush fore_brush @outvar(fore_brush);
+ Brush back_brush @outvar(back_brush);
+ uint16 fore_mode;
+ uint16 back_mode;
+ } data;
+ } draw_text;
+
+ message {
+ DisplayBase base;
+ struct Transparent {
+ Image *src_bitmap;
+ Rect src_area;
+ uint32 src_color;
+ uint32 true_color;
+ } data;
+ } draw_transparent;
+
+ message {
+ DisplayBase base;
+ struct AlphaBlend {
+ int8 alpha_flags @virtual(0);
+ uint8 alpha;
+ Image *src_bitmap;
+ Rect src_area;
+ } data;
+ } draw_alpha_blend;
+
+ client:
+ message {
+ uint8 pixmap_cache_id;
+ int64 pixmap_cache_size; //in pixels
+ uint8 glz_dictionary_id;
+ int32 glz_dictionary_window_size; // in pixels
+ } init = 101;
+};
+
+flags32 keyboard_modifier_flags {
+ SCROLL_LOCK,
+ NUM_LOCK,
+ CAPS_LOCK
+};
+
+enum32 mouse_button {
+ INVALID,
+ LEFT,
+ MIDDLE,
+ RIGHT,
+ UP,
+ DOWN,
+};
+
+flags32 mouse_button_mask {
+ LEFT,
+ MIDDLE,
+ RIGHT
+};
+
+channel InputsChannel : BaseChannel {
+ client:
+ message {
+ uint32 code;
+ } @ctype(SpiceMsgcKeyDown) key_down = 101;
+
+ message {
+ uint32 code;
+ } @ctype(SpiceMsgcKeyUp) key_up;
+
+ message {
+ keyboard_modifier_flags modifiers;
+ } @ctype(SpiceMsgcKeyModifiers) key_modifiers;
+
+ message {
+ int32 dx;
+ int32 dy;
+ mouse_button_mask buttons_state;
+ } @ctype(SpiceMsgcMouseMotion) mouse_motion = 111;
+
+ message {
+ uint32 x;
+ uint32 y;
+ mouse_button_mask buttons_state;
+ uint8 display_id;
+ } @ctype(SpiceMsgcMousePosition) mouse_position;
+
+ message {
+ mouse_button button;
+ mouse_button_mask buttons_state;
+ } @ctype(SpiceMsgcMousePress) mouse_press;
+
+ message {
+ mouse_button button;
+ mouse_button_mask buttons_state;
+ } @ctype(SpiceMsgcMouseRelease) mouse_release;
+
+ server:
+ message {
+ keyboard_modifier_flags keyboard_modifiers;
+ } init = 101;
+
+ message {
+ keyboard_modifier_flags modifiers;
+ } key_modifiers;
+
+ Empty mouse_motion_ack = 111;
+};
+
+enum16 cursor_type {
+ ALPHA,
+ MONO,
+ COLOR4,
+ COLOR8,
+ COLOR16,
+ COLOR24,
+ COLOR32,
+};
+
+flags32 cursor_flags {
+ NONE, /* Means no cursor */
+ CACHE_ME,
+ FROM_CACHE,
+};
+
+struct CursorHeader {
+ uint64 unique;
+ cursor_type type;
+ uint16 width;
+ uint16 height;
+ uint16 hot_spot_x;
+ uint16 hot_spot_y;
+};
+
+struct Cursor {
+ cursor_flags flags;
+ CursorHeader header;
+ uint8 data[] @as_ptr(data_size);
+};
+
+channel CursorChannel : BaseChannel {
+ server:
+ message {
+ Point16 position;
+ uint16 trail_length;
+ uint16 trail_frequency;
+ uint8 visible;
+ Cursor cursor;
+ } init = 101;
+
+ Empty reset;
+
+ message {
+ Point16 position;
+ uint8 visible;
+ Cursor cursor;
+ } set;
+
+ message {
+ Point16 position;
+ } move;
+
+ Empty hide;
+
+ message {
+ uint16 length;
+ uint16 frequency;
+ } trail;
+
+ message {
+ uint64 id;
+ } @ctype(SpiceMsgDisplayInvalOne) inval_one;
+
+ Empty inval_all;
+};
+
+enum32 audio_data_mode {
+ INVALID,
+ RAW,
+ CELT_0_5_1,
+ OPUS,
+};
+
+enum32 audio_fmt {
+ INVALID,
+ S16,
+};
+
+channel PlaybackChannel : BaseChannel {
+ server:
+ message {
+ uint32 time;
+ uint8 data[] @as_ptr(data_size);
+ } @ctype(SpiceMsgPlaybackPacket) data = 101;
+
+ message {
+ uint32 time;
+ audio_data_mode mode;
+ uint8 data[] @as_ptr(data_size);
+ } mode;
+
+ message {
+ uint32 channels;
+ audio_fmt format;
+ uint32 frequency;
+ uint32 time;
+ } start;
+
+ Empty stop;
+};
+
+channel RecordChannel : BaseChannel {
+ server:
+ message {
+ uint32 channels;
+ audio_fmt format;
+ uint32 frequency;
+ } start = 101;
+
+ Empty stop;
+ client:
+ message {
+ uint32 time;
+ uint8 data[] @nomarshal @as_ptr(data_size);
+ } @ctype(SpiceMsgcRecordPacket) data = 101;
+
+ message {
+ uint32 time;
+ audio_data_mode mode;
+ uint8 data[] @as_ptr(data_size);
+ } mode;
+
+ message {
+ uint32 time;
+ } start_mark;
+};
+
+protocol Spice {
+ MainChannel main = 1;
+ DisplayChannel display;
+ InputsChannel inputs;
+ CursorChannel cursor;
+ PlaybackChannel playback;
+ RecordChannel record;
+};
--- /dev/null
+#!/usr/bin/env python
+
+import os
+import sys
+from optparse import OptionParser
+import traceback
+from python_modules import spice_parser
+from python_modules import ptypes
+from python_modules import codegen
+from python_modules import demarshal
+from python_modules import marshal
+import six
+
+def write_channel_enums(writer, channel, client, describe):
+ messages = list(filter(lambda m : m.channel == channel, \
+ channel.client_messages if client else channel.server_messages))
+ if len(messages) == 0:
+ return
+ if client:
+ prefix = [ "MSGC" ]
+ else:
+ prefix = [ "MSG" ]
+ if channel.member_name:
+ prefix.append(channel.member_name.upper())
+ if not describe:
+ writer.begin_block("enum")
+ else:
+ writer.begin_block("static const value_string %s_vs[] = " % (codegen.prefix_underscore_lower(*[x.lower() for x in prefix])))
+ i = 0
+ prefix.append(None) # To be replaced with name
+ for m in messages:
+ prefix[-1] = m.name.upper()
+ enum = codegen.prefix_underscore_upper(*prefix)
+ if describe:
+ writer.writeln("{ %s, \"%s %s\" }," % (enum, "Client" if client else "Server", m.name.upper()))
+ else:
+ if m.value == i:
+ writer.writeln("%s," % enum)
+ i = i + 1
+ else:
+ writer.writeln("%s = %s," % (enum, m.value))
+ i = m.value + 1
+ if describe:
+ writer.writeln("{ 0, NULL }");
+ else:
+ if channel.member_name:
+ prefix[-1] = prefix[-2]
+ prefix[-2] = "END"
+ writer.newline()
+ writer.writeln("%s" % (codegen.prefix_underscore_upper(*prefix)))
+ writer.end_block(semicolon=True)
+ writer.newline()
+
+def write_channel_type_enum(writer, describe=False):
+ i = 0
+ if describe:
+ writer.begin_block("static const value_string channel_types_vs[] =")
+ else:
+ writer.begin_block("enum")
+ for c in proto.channels:
+ enum = codegen.prefix_underscore_upper("CHANNEL", c.name.upper())
+ if describe:
+ writer.writeln("{ %s, \"%s\" }," % (enum, c.name.upper()))
+ else:
+ if c.value == i:
+ writer.writeln("%s," % enum)
+ i = i + 1
+ else:
+ writer.writeln("%s = %s," % (enum, c.value))
+ i = c.value + 1
+ writer.newline()
+ if describe:
+ writer.writeln("{ 0, NULL }")
+ else:
+ writer.writeln("SPICE_END_CHANNEL")
+ writer.end_block(semicolon=True)
+ writer.newline()
+
+
+def write_enums(writer, describe=False):
+ writer.writeln("#ifndef _H_SPICE_ENUMS")
+ writer.writeln("#define _H_SPICE_ENUMS")
+ writer.newline()
+
+ # Define enums
+ for t in ptypes.get_named_types():
+ if isinstance(t, ptypes.EnumBaseType):
+ t.c_define(writer)
+ if describe:
+ t.c_describe(writer)
+
+ write_channel_type_enum(writer)
+ if (describe):
+ write_channel_type_enum(writer, True)
+
+ for c in ptypes.get_named_types():
+ if not isinstance(c, ptypes.ChannelType):
+ continue
+ write_channel_enums(writer, c, False, False)
+ if describe:
+ write_channel_enums(writer, c, False, describe)
+ write_channel_enums(writer, c, True, False)
+ if describe:
+ write_channel_enums(writer, c, True, describe)
+
+ writer.writeln("#endif /* _H_SPICE_ENUMS */")
+
+parser = OptionParser(usage="usage: %prog [options] <protocol_file> <destination file>")
+parser.add_option("-e", "--generate-enums",
+ action="store_true", dest="generate_enums", default=False,
+ help="Generate enums")
+parser.add_option("-w", "--generate-wireshark-dissector",
+ action="store_true", dest="generate_dissector", default=False,
+ help="Generate Wireshark dissector definitions")
+parser.add_option("-d", "--generate-demarshallers",
+ action="store_true", dest="generate_demarshallers", default=False,
+ help="Generate demarshallers")
+parser.add_option("-m", "--generate-marshallers",
+ action="store_true", dest="generate_marshallers", default=False,
+ help="Generate message marshallers")
+parser.add_option("-P", "--private-marshallers",
+ action="store_true", dest="private_marshallers", default=False,
+ help="Generate private message marshallers")
+parser.add_option("-M", "--generate-struct-marshaller",
+ action="append", dest="struct_marshallers",
+ help="Generate struct marshallers")
+parser.add_option("-a", "--assert-on-error",
+ action="store_true", dest="assert_on_error", default=False,
+ help="Assert on error")
+parser.add_option("-H", "--header",
+ action="store_true", dest="header", default=False,
+ help="Generate header")
+parser.add_option("-p", "--print-error",
+ action="store_true", dest="print_error", default=False,
+ help="Print errors")
+parser.add_option("-s", "--server",
+ action="store_true", dest="server", default=False,
+ help="Print errors")
+parser.add_option("-c", "--client",
+ action="store_true", dest="client", default=False,
+ help="Print errors")
+parser.add_option("-k", "--keep-identical-file",
+ action="store_true", dest="keep_identical_file", default=False,
+ help="Print errors")
+parser.add_option("-i", "--include",
+ action="append", dest="includes", metavar="FILE",
+ help="Include FILE in generated code")
+parser.add_option("--prefix", dest="prefix",
+ help="set public symbol prefix", default="")
+parser.add_option("--ptrsize", dest="ptrsize",
+ help="set default pointer size", default="4")
+
+(options, args) = parser.parse_args()
+
+if len(args) == 0:
+ parser.error("No protocol file specified")
+
+if len(args) == 1:
+ parser.error("No destination file specified")
+
+ptypes.default_pointer_size = int(options.ptrsize)
+
+proto_file = args[0]
+dest_file = args[1]
+proto = spice_parser.parse(proto_file)
+
+if proto == None:
+ exit(1)
+
+codegen.set_prefix(proto.name)
+writer = codegen.CodeWriter()
+writer.header = codegen.CodeWriter()
+writer.header.set_option("dest_file", dest_file)
+writer.set_option("source", os.path.basename(proto_file))
+
+license = """/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+"""
+
+writer.public_prefix = options.prefix
+
+writer.writeln("/* this is a file autogenerated by spice_codegen.py */")
+writer.write(license)
+writer.header.writeln("/* this is a file autogenerated by spice_codegen.py */")
+writer.header.write(license)
+if not options.header and not options.generate_enums:
+ writer.writeln("#ifdef HAVE_CONFIG_H")
+ writer.writeln("#include <config.h>")
+ writer.writeln("#endif")
+
+if options.assert_on_error:
+ writer.set_option("assert_on_error")
+
+if options.print_error:
+ writer.set_option("print_error")
+
+if options.includes:
+ for i in options.includes:
+ writer.header.writeln('#include "%s"' % i)
+ writer.writeln('#include "%s"' % i)
+
+if options.generate_enums or options.generate_dissector:
+ write_enums(writer, options.generate_dissector)
+
+if options.generate_demarshallers:
+ if not options.server and not options.client:
+ print >> sys.stderr, "Must specify client and/or server"
+ sys.exit(1)
+ demarshal.write_includes(writer)
+
+ if options.server:
+ demarshal.write_protocol_parser(writer, proto, False)
+ if options.client:
+ demarshal.write_protocol_parser(writer, proto, True)
+
+if options.generate_marshallers or (options.struct_marshallers and len(options.struct_marshallers) > 0):
+ marshal.write_includes(writer)
+
+if options.generate_marshallers:
+ if not options.server and not options.client:
+ print >> sys.stderr, "Must specify client and/or server"
+ sys.exit(1)
+ if options.server:
+ marshal.write_protocol_marshaller(writer, proto, False, options.private_marshallers)
+ if options.client:
+ marshal.write_protocol_marshaller(writer, proto, True, options.private_marshallers)
+
+if options.struct_marshallers:
+ for structname in options.struct_marshallers:
+ t = ptypes.lookup_type(structname)
+ marshal.write_marshal_ptr_function(writer, t, False)
+
+if options.generate_marshallers or (options.struct_marshallers and len(options.struct_marshallers) > 0):
+ marshal.write_trailer(writer)
+
+if options.header:
+ content = writer.header.getvalue()
+else:
+ content = writer.getvalue()
+if options.keep_identical_file:
+ try:
+ f = open(dest_file, 'rb')
+ old_content = f.read()
+ f.close()
+
+ if content == old_content:
+ six.print_("No changes to %s" % dest_file)
+ sys.exit(0)
+
+ except IOError:
+ pass
+
+f = open(dest_file, 'wb')
+if six.PY3:
+ f.write(bytes(content, 'UTF-8'))
+else:
+ f.write(content)
+f.close()
+
+six.print_("Wrote %s" % dest_file)
+sys.exit(0)
--- /dev/null
+NULL =
+
+TESTS = test_logging test_marshallers
+noinst_PROGRAMS = $(TESTS)
+
+test_logging_SOURCES = test-logging.c
+test_logging_CFLAGS = \
+ -I$(top_srcdir) \
+ $(GLIB2_CFLAGS) \
+ $(GIO_UNIX_CFLAGS) \
+ $(PROTOCOL_CFLAGS) \
+ $(NULL)
+test_logging_LDADD = \
+ $(top_builddir)/common/libspice-common.la \
+ $(GLIB2_LIBS) \
+ $(GIO_UNIX_LIBS) \
+ $(NULL)
+
+
+test_marshallers_SOURCES = \
+ generated_test_marshallers.c \
+ generated_test_marshallers.h \
+ test-marshallers.c \
+ test-marshallers.h \
+ $(NULL)
+test_marshallers_CFLAGS = \
+ -I$(top_srcdir) \
+ $(GLIB2_CFLAGS) \
+ $(PROTOCOL_CFLAGS) \
+ $(NULL)
+test_marshallers_LDADD = \
+ $(top_builddir)/common/libspice-common.la \
+ $(GLIB2_LIBS) \
+ $(NULL)
+
+# Avoid need for python(pyparsing) by end users
+TEST_MARSHALLERS = \
+ generated_test_marshallers.c \
+ generated_test_marshallers.h \
+ $(NULL)
+
+BUILT_SOURCES = $(TEST_MARSHALLERS)
+
+MARSHALLERS_DEPS = \
+ $(top_srcdir)/python_modules/__init__.py \
+ $(top_srcdir)/python_modules/codegen.py \
+ $(top_srcdir)/python_modules/demarshal.py \
+ $(top_srcdir)/python_modules/marshal.py \
+ $(top_srcdir)/python_modules/ptypes.py \
+ $(top_srcdir)/python_modules/spice_parser.py \
+ $(top_srcdir)/spice_codegen.py \
+ $(NULL)
+
+# Note despite being autogenerated these are not part of CLEANFILES, they are
+# actually a part of EXTRA_DIST, to avoid the need for pyparser by end users
+generated_test_marshallers.c: $(srcdir)/test-marshallers.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers --server --include test-marshallers.h $< $@ >/dev/null
+generated_test_marshallers.h: $(srcdir)/test-marshallers.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers --server --include test-marshallers.h -H $< $@ >/dev/null
+
+EXTRA_DIST = \
+ $(TEST_MARSHALLERS) \
+ test-marshallers.proto \
+ $(NULL)
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+TESTS = test_logging$(EXEEXT) test_marshallers$(EXEEXT)
+noinst_PROGRAMS = $(am__EXEEXT_1)
+subdir = tests
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_python_module.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__EXEEXT_1 = test_logging$(EXEEXT) test_marshallers$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+am_test_logging_OBJECTS = test_logging-test-logging.$(OBJEXT)
+test_logging_OBJECTS = $(am_test_logging_OBJECTS)
+am__DEPENDENCIES_1 =
+test_logging_DEPENDENCIES = $(top_builddir)/common/libspice-common.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+test_logging_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_logging_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am__objects_1 =
+am_test_marshallers_OBJECTS = \
+ test_marshallers-generated_test_marshallers.$(OBJEXT) \
+ test_marshallers-test-marshallers.$(OBJEXT) $(am__objects_1)
+test_marshallers_OBJECTS = $(am_test_marshallers_OBJECTS)
+test_marshallers_DEPENDENCIES = \
+ $(top_builddir)/common/libspice-common.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+test_marshallers_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(test_marshallers_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+ -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(test_logging_SOURCES) $(test_marshallers_SOURCES)
+DIST_SOURCES = $(test_logging_SOURCES) $(test_marshallers_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red='\e[0;31m'; \
+ grn='\e[0;32m'; \
+ lgn='\e[1;32m'; \
+ blu='\e[1;34m'; \
+ mgn='\e[0;35m'; \
+ brg='\e[1m'; \
+ std='\e[m'; \
+ fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CELT051_CFLAGS = @CELT051_CFLAGS@
+CELT051_LIBS = @CELT051_LIBS@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OPUS_CFLAGS = @OPUS_CFLAGS@
+OPUS_LIBS = @OPUS_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PROTOCOL_CFLAGS = @PROTOCOL_CFLAGS@
+PROTOCOL_LIBS = @PROTOCOL_LIBS@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_COMMON_CFLAGS = @SPICE_COMMON_CFLAGS@
+SPICE_COMMON_LIBS = @SPICE_COMMON_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+test_logging_SOURCES = test-logging.c
+test_logging_CFLAGS = \
+ -I$(top_srcdir) \
+ $(GLIB2_CFLAGS) \
+ $(GIO_UNIX_CFLAGS) \
+ $(PROTOCOL_CFLAGS) \
+ $(NULL)
+
+test_logging_LDADD = \
+ $(top_builddir)/common/libspice-common.la \
+ $(GLIB2_LIBS) \
+ $(GIO_UNIX_LIBS) \
+ $(NULL)
+
+test_marshallers_SOURCES = \
+ generated_test_marshallers.c \
+ generated_test_marshallers.h \
+ test-marshallers.c \
+ test-marshallers.h \
+ $(NULL)
+
+test_marshallers_CFLAGS = \
+ -I$(top_srcdir) \
+ $(GLIB2_CFLAGS) \
+ $(PROTOCOL_CFLAGS) \
+ $(NULL)
+
+test_marshallers_LDADD = \
+ $(top_builddir)/common/libspice-common.la \
+ $(GLIB2_LIBS) \
+ $(NULL)
+
+
+# Avoid need for python(pyparsing) by end users
+TEST_MARSHALLERS = \
+ generated_test_marshallers.c \
+ generated_test_marshallers.h \
+ $(NULL)
+
+BUILT_SOURCES = $(TEST_MARSHALLERS)
+MARSHALLERS_DEPS = \
+ $(top_srcdir)/python_modules/__init__.py \
+ $(top_srcdir)/python_modules/codegen.py \
+ $(top_srcdir)/python_modules/demarshal.py \
+ $(top_srcdir)/python_modules/marshal.py \
+ $(top_srcdir)/python_modules/ptypes.py \
+ $(top_srcdir)/python_modules/spice_parser.py \
+ $(top_srcdir)/spice_codegen.py \
+ $(NULL)
+
+EXTRA_DIST = \
+ $(TEST_MARSHALLERS) \
+ test-marshallers.proto \
+ $(NULL)
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+test_logging$(EXEEXT): $(test_logging_OBJECTS) $(test_logging_DEPENDENCIES) $(EXTRA_test_logging_DEPENDENCIES)
+ @rm -f test_logging$(EXEEXT)
+ $(AM_V_CCLD)$(test_logging_LINK) $(test_logging_OBJECTS) $(test_logging_LDADD) $(LIBS)
+
+test_marshallers$(EXEEXT): $(test_marshallers_OBJECTS) $(test_marshallers_DEPENDENCIES) $(EXTRA_test_marshallers_DEPENDENCIES)
+ @rm -f test_marshallers$(EXEEXT)
+ $(AM_V_CCLD)$(test_marshallers_LINK) $(test_marshallers_OBJECTS) $(test_marshallers_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_logging-test-logging.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_marshallers-generated_test_marshallers.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_marshallers-test-marshallers.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+test_logging-test-logging.o: test-logging.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_logging_CFLAGS) $(CFLAGS) -MT test_logging-test-logging.o -MD -MP -MF $(DEPDIR)/test_logging-test-logging.Tpo -c -o test_logging-test-logging.o `test -f 'test-logging.c' || echo '$(srcdir)/'`test-logging.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_logging-test-logging.Tpo $(DEPDIR)/test_logging-test-logging.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-logging.c' object='test_logging-test-logging.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_logging_CFLAGS) $(CFLAGS) -c -o test_logging-test-logging.o `test -f 'test-logging.c' || echo '$(srcdir)/'`test-logging.c
+
+test_logging-test-logging.obj: test-logging.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_logging_CFLAGS) $(CFLAGS) -MT test_logging-test-logging.obj -MD -MP -MF $(DEPDIR)/test_logging-test-logging.Tpo -c -o test_logging-test-logging.obj `if test -f 'test-logging.c'; then $(CYGPATH_W) 'test-logging.c'; else $(CYGPATH_W) '$(srcdir)/test-logging.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_logging-test-logging.Tpo $(DEPDIR)/test_logging-test-logging.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-logging.c' object='test_logging-test-logging.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_logging_CFLAGS) $(CFLAGS) -c -o test_logging-test-logging.obj `if test -f 'test-logging.c'; then $(CYGPATH_W) 'test-logging.c'; else $(CYGPATH_W) '$(srcdir)/test-logging.c'; fi`
+
+test_marshallers-generated_test_marshallers.o: generated_test_marshallers.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_marshallers_CFLAGS) $(CFLAGS) -MT test_marshallers-generated_test_marshallers.o -MD -MP -MF $(DEPDIR)/test_marshallers-generated_test_marshallers.Tpo -c -o test_marshallers-generated_test_marshallers.o `test -f 'generated_test_marshallers.c' || echo '$(srcdir)/'`generated_test_marshallers.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_marshallers-generated_test_marshallers.Tpo $(DEPDIR)/test_marshallers-generated_test_marshallers.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='generated_test_marshallers.c' object='test_marshallers-generated_test_marshallers.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_marshallers_CFLAGS) $(CFLAGS) -c -o test_marshallers-generated_test_marshallers.o `test -f 'generated_test_marshallers.c' || echo '$(srcdir)/'`generated_test_marshallers.c
+
+test_marshallers-generated_test_marshallers.obj: generated_test_marshallers.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_marshallers_CFLAGS) $(CFLAGS) -MT test_marshallers-generated_test_marshallers.obj -MD -MP -MF $(DEPDIR)/test_marshallers-generated_test_marshallers.Tpo -c -o test_marshallers-generated_test_marshallers.obj `if test -f 'generated_test_marshallers.c'; then $(CYGPATH_W) 'generated_test_marshallers.c'; else $(CYGPATH_W) '$(srcdir)/generated_test_marshallers.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_marshallers-generated_test_marshallers.Tpo $(DEPDIR)/test_marshallers-generated_test_marshallers.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='generated_test_marshallers.c' object='test_marshallers-generated_test_marshallers.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_marshallers_CFLAGS) $(CFLAGS) -c -o test_marshallers-generated_test_marshallers.obj `if test -f 'generated_test_marshallers.c'; then $(CYGPATH_W) 'generated_test_marshallers.c'; else $(CYGPATH_W) '$(srcdir)/generated_test_marshallers.c'; fi`
+
+test_marshallers-test-marshallers.o: test-marshallers.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_marshallers_CFLAGS) $(CFLAGS) -MT test_marshallers-test-marshallers.o -MD -MP -MF $(DEPDIR)/test_marshallers-test-marshallers.Tpo -c -o test_marshallers-test-marshallers.o `test -f 'test-marshallers.c' || echo '$(srcdir)/'`test-marshallers.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_marshallers-test-marshallers.Tpo $(DEPDIR)/test_marshallers-test-marshallers.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-marshallers.c' object='test_marshallers-test-marshallers.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_marshallers_CFLAGS) $(CFLAGS) -c -o test_marshallers-test-marshallers.o `test -f 'test-marshallers.c' || echo '$(srcdir)/'`test-marshallers.c
+
+test_marshallers-test-marshallers.obj: test-marshallers.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_marshallers_CFLAGS) $(CFLAGS) -MT test_marshallers-test-marshallers.obj -MD -MP -MF $(DEPDIR)/test_marshallers-test-marshallers.Tpo -c -o test_marshallers-test-marshallers.obj `if test -f 'test-marshallers.c'; then $(CYGPATH_W) 'test-marshallers.c'; else $(CYGPATH_W) '$(srcdir)/test-marshallers.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_marshallers-test-marshallers.Tpo $(DEPDIR)/test_marshallers-test-marshallers.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test-marshallers.c' object='test_marshallers-test-marshallers.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_marshallers_CFLAGS) $(CFLAGS) -c -o test_marshallers-test-marshallers.obj `if test -f 'test-marshallers.c'; then $(CYGPATH_W) 'test-marshallers.c'; else $(CYGPATH_W) '$(srcdir)/test-marshallers.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+test_logging.log: test_logging$(EXEEXT)
+ @p='test_logging$(EXEEXT)'; \
+ b='test_logging'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test_marshallers.log: test_marshallers$(EXEEXT)
+ @p='test_marshallers$(EXEEXT)'; \
+ b='test_marshallers'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: all check check-am install install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+ clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Note despite being autogenerated these are not part of CLEANFILES, they are
+# actually a part of EXTRA_DIST, to avoid the need for pyparser by end users
+generated_test_marshallers.c: $(srcdir)/test-marshallers.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers --server --include test-marshallers.h $< $@ >/dev/null
+generated_test_marshallers.h: $(srcdir)/test-marshallers.proto $(MARSHALLERS_DEPS)
+ $(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers --server --include test-marshallers.h -H $< $@ >/dev/null
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+/* this is a file autogenerated by spice_codegen.py */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "test-marshallers.h"
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <spice/protocol.h>
+#include <spice/macros.h>
+#include "common/marshaller.h"
+
+#ifdef _MSC_VER
+#pragma warning(disable:4101)
+#pragma warning(disable:4018)
+#endif
+
+SPICE_GNUC_UNUSED static void spice_marshall_array_uint64(SpiceMarshaller *m, uint64_t *ptr, unsigned count)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ uint32_t i;
+
+ for (i = 0; i < count; i++) {
+ spice_marshaller_add_uint64(m, *ptr++);
+ }
+}
+
+void spice_marshall_msg_main_ShortDataSubMarshall(SPICE_GNUC_UNUSED SpiceMarshaller *m, SPICE_GNUC_UNUSED SpiceMsgMainShortDataSubMarshall *msg)
+{
+ SPICE_GNUC_UNUSED SpiceMarshaller *m2;
+ SpiceMsgMainShortDataSubMarshall *src;
+ src = (SpiceMsgMainShortDataSubMarshall *)msg;
+
+ spice_marshaller_add_uint32(m, src->data_size);
+ m2 = spice_marshaller_get_ptr_submarshaller(m, 0);
+ if (src->data != NULL) {
+ spice_marshall_array_uint64(m2, src->data, src->data_size);
+ }
+}
+
--- /dev/null
+/* this is a file autogenerated by spice_codegen.py */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "test-marshallers.h"
+#include <spice/protocol.h>
+#include "common/marshaller.h"
+
+#ifndef _H_GENERATED_TEST_MARSHALLERS
+#define _H_GENERATED_TEST_MARSHALLERS
+
+SPICE_BEGIN_DECLS
+
+void spice_marshall_msg_main_ShortDataSubMarshall(SpiceMarshaller *m, SpiceMsgMainShortDataSubMarshall *msg);
+
+SPICE_END_DECLS
+
+#endif
--- /dev/null
+/*
+ Copyright (C) 2015 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define G_LOG_DOMAIN "Spice"
+#define SPICE_LOG_DOMAIN G_LOG_DOMAIN
+
+#include <glib.h>
+#include <stdlib.h>
+
+#include "common/log.h"
+
+#define OTHER_LOG_DOMAIN "Other"
+#define LOG_OTHER_HELPER(suffix, level) \
+ static void G_PASTE(other_, suffix)(const gchar *format, ...) \
+ { \
+ va_list args; \
+ \
+ va_start (args, format); \
+ g_logv(OTHER_LOG_DOMAIN, G_PASTE(G_LOG_LEVEL_, level), format, args); \
+ va_end (args); \
+ }
+
+/* Set of helpers to log in a different log domain than "Spice" */
+LOG_OTHER_HELPER(debug, DEBUG)
+LOG_OTHER_HELPER(info, INFO)
+LOG_OTHER_HELPER(message, MESSAGE)
+LOG_OTHER_HELPER(warning, WARNING)
+LOG_OTHER_HELPER(critical, CRITICAL)
+
+#if GLIB_CHECK_VERSION(2,38,0)
+/* Checks that spice_warning() aborts after changing SPICE_ABORT_LEVEL */
+static void test_spice_abort_level(void)
+{
+ if (g_test_subprocess()) {
+ spice_warning("spice_warning");
+ return;
+ }
+ /* 2 = SPICE_LOG_LEVEL_WARNING */
+ g_setenv("SPICE_ABORT_LEVEL", "2", TRUE);
+ g_test_trap_subprocess(NULL, 0, 0);
+ g_unsetenv("SPICE_ABORT_LEVEL");
+ g_test_trap_assert_failed();
+ g_test_trap_assert_stderr("*SPICE_ABORT_LEVEL*deprecated*");
+ g_test_trap_assert_stderr("*spice_warning*");
+}
+
+/* Checks that g_warning() aborts after changing SPICE_ABORT_LEVEL */
+static void test_spice_abort_level_g_warning(void)
+{
+ if (g_test_subprocess()) {
+ g_warning("g_warning");
+ return;
+ }
+ g_setenv("SPICE_ABORT_LEVEL", "2", TRUE);
+ g_test_trap_subprocess(NULL, 0, 0);
+ g_unsetenv("SPICE_ABORT_LEVEL");
+ g_test_trap_assert_failed();
+ g_test_trap_assert_stderr("*SPICE_ABORT_LEVEL*deprecated*");
+ g_test_trap_assert_stderr("*g_warning*");
+}
+
+/* Checks that spice_warning() aborts after setting G_DEBUG=fatal-warnings */
+static void test_spice_fatal_warning(void)
+{
+ g_setenv("G_DEBUG", "fatal-warnings", TRUE);
+ if (g_test_subprocess()) {
+ spice_warning("spice_warning");
+ return;
+ }
+ g_test_trap_subprocess(NULL, 0, 0);
+ g_test_trap_assert_failed();
+ g_test_trap_assert_stderr("*spice_warning*");
+ g_unsetenv("G_DEBUG");
+}
+
+/* Checks that spice_critical() aborts by default if SPICE_DISABLE_ABORT is not
+ * defined at compile-time */
+static void test_spice_fatal_critical(void)
+{
+ if (g_test_subprocess()) {
+ spice_critical("spice_critical");
+ return;
+ }
+ g_test_trap_subprocess(NULL, 0, 0);
+#ifdef SPICE_DISABLE_ABORT
+ g_test_trap_assert_passed();
+#else
+ g_test_trap_assert_failed();
+#endif
+ g_test_trap_assert_stderr("*spice_critical*");
+}
+
+/* Checks that g_critical() does not abort by default */
+static void test_spice_non_fatal_g_critical(void)
+{
+ if (g_test_subprocess()) {
+ g_critical("g_critical");
+ return;
+ }
+ g_test_trap_subprocess(NULL, 0, 0);
+ g_test_trap_assert_passed();
+ g_test_trap_assert_stderr("*g_critical*");
+}
+
+/* Checks that g_critical() aborts after setting G_DEBUG=fatal-criticals */
+static void test_spice_fatal_g_critical(void)
+{
+ g_setenv("G_DEBUG", "fatal-criticals", TRUE);
+ if (g_test_subprocess()) {
+ g_critical("g_critical");
+ return;
+ }
+ g_test_trap_subprocess(NULL, 0, 0);
+ g_test_trap_assert_failed();
+ g_test_trap_assert_stderr("*g_critical*");
+ g_unsetenv("G_DEBUG");
+}
+
+/* Checks that spice_return_if_fail() aborts by default unless
+ * SPICE_DISABLE_ABORT was defined at compile time*/
+static void test_spice_fatal_return_if_fail(void)
+{
+ if (g_test_subprocess()) {
+ spice_return_if_fail(FALSE);
+ return;
+ }
+ g_test_trap_subprocess(NULL, 0, 0);
+#ifdef SPICE_DISABLE_ABORT
+ g_test_trap_assert_passed();
+#else
+ g_test_trap_assert_failed();
+#endif
+ g_test_trap_assert_stderr("*test_spice_fatal_return_if_fail*");
+}
+
+/* Checks that g_return_if_fail() does not abort by default */
+static void test_spice_non_fatal_g_return_if_fail(void)
+{
+ if (g_test_subprocess()) {
+ g_return_if_fail(FALSE);
+ return;
+ }
+ g_test_trap_subprocess(NULL, 0, 0);
+ g_test_trap_assert_passed();
+}
+
+/* Checks that spice_*, g_* and other_* (different log domain as g_*) all
+ * go through g_log() with the correct domain/log level. This then checks
+ * that only logs with level 'message' or higher are shown by default.
+ */
+static void test_log_levels(void)
+{
+ if (g_test_subprocess()) {
+ g_test_expect_message(SPICE_LOG_DOMAIN,
+ G_LOG_LEVEL_WARNING,
+ "*spice_warning");
+ spice_warning("spice_warning");
+ g_test_expect_message(SPICE_LOG_DOMAIN,
+ G_LOG_LEVEL_INFO,
+ "*spice_info");
+ spice_info("spice_info");
+ g_test_expect_message(SPICE_LOG_DOMAIN,
+ G_LOG_LEVEL_DEBUG,
+ "*spice_debug");
+ spice_debug("spice_debug");
+
+ g_test_expect_message(G_LOG_DOMAIN,
+ G_LOG_LEVEL_CRITICAL,
+ "*g_critical");
+ g_critical("g_critical");
+ g_test_expect_message(G_LOG_DOMAIN,
+ G_LOG_LEVEL_WARNING,
+ "*g_warning");
+ g_warning("g_warning");
+ g_test_expect_message(G_LOG_DOMAIN,
+ G_LOG_LEVEL_MESSAGE,
+ "*g_message");
+ g_message("g_message");
+ g_test_expect_message(G_LOG_DOMAIN,
+ G_LOG_LEVEL_INFO,
+ "*g_info");
+ g_info("g_info");
+ g_test_expect_message(G_LOG_DOMAIN,
+ G_LOG_LEVEL_DEBUG,
+ "*g_debug");
+ g_debug("g_debug");
+
+ g_test_expect_message(OTHER_LOG_DOMAIN,
+ G_LOG_LEVEL_CRITICAL,
+ "*other_critical");
+ other_critical("other_critical");
+ g_test_expect_message(OTHER_LOG_DOMAIN,
+ G_LOG_LEVEL_WARNING,
+ "*other_warning");
+ other_warning("other_warning");
+ g_test_expect_message(OTHER_LOG_DOMAIN,
+ G_LOG_LEVEL_MESSAGE,
+ "*other_message");
+ other_message("other_message");
+ g_test_expect_message(OTHER_LOG_DOMAIN,
+ G_LOG_LEVEL_INFO,
+ "*other_info");
+ other_info("other_info");
+ g_test_expect_message(OTHER_LOG_DOMAIN,
+ G_LOG_LEVEL_DEBUG,
+ "*other_debug");
+ other_debug("other_debug");
+
+ g_test_assert_expected_messages();
+
+
+ /* g_test_expected_message only checks whether the appropriate messages got up to g_log()
+ * The following calls will be caught by the parent process to check what was (not) printed
+ * to stdout/stderr
+ */
+ spice_warning("spice_warning");
+ spice_info("spice_info");
+ spice_debug("spice_debug");
+
+ g_critical("g_critical");
+ g_warning("g_warning");
+ g_message("g_message");
+ g_info("g_info");
+ g_debug("g_debug");
+
+ other_critical("other_critical");
+ other_warning("other_warning");
+ other_message("other_message");
+ other_info("other_info");
+ other_debug("other_debug");
+
+ return;
+ }
+ g_test_trap_subprocess(NULL, 0, 0);
+ g_test_trap_assert_passed();
+ g_test_trap_assert_stderr("*spice_warning\n*g_critical\n*g_warning\n*g_message\n*other_critical\n*other_warning\n*other_message\n");
+}
+
+/* Checks that SPICE_DEBUG_LEVEL impacts spice_debug(), g_debug() but not other_debug() */
+static void test_spice_debug_level(void)
+{
+ if (g_test_subprocess()) {
+ /* g_test_expected_message only checks whether the appropriate messages got up to g_log()
+ * The following calls will be caught by the parent process to check what was (not) printed
+ * to stdout/stderr
+ */
+ spice_info("spice_info");
+ g_debug("g_debug");
+ spice_debug("spice_debug");
+ other_debug("other_debug");
+
+ return;
+ }
+
+ g_unsetenv("G_MESSAGES_DEBUG");
+ g_setenv("SPICE_DEBUG_LEVEL", "5", TRUE);
+ g_test_trap_subprocess(NULL, 0, 0);
+ g_unsetenv("SPICE_DEBUG_LEVEL");
+ g_test_trap_assert_passed();
+ g_test_trap_assert_stderr("*SPICE_DEBUG_LEVEL*deprecated*");
+ g_test_trap_assert_stdout("*spice_info\n*g_debug\n*spice_debug\n");
+}
+
+/* Checks that raising SPICE_DEBUG_LEVEL allows to only show spice_warning() and spice_critical()
+ * messages, as well as g_warning() and g_critical(), but does not impact other_message()
+ */
+static void test_spice_debug_level_warning(void)
+{
+ if (g_test_subprocess()) {
+ spice_info("spice_info");
+ spice_debug("spice_debug");
+ spice_warning("spice_warning");
+ spice_critical("spice_critical");
+ g_debug("g_debug");
+ g_info("g_info");
+ g_message("g_message");
+ g_warning("g_warning");
+ g_critical("g_critical");
+ other_debug("other_debug");
+ other_info("other_info");
+ other_message("other_message");
+ other_warning("other_warning");
+ other_critical("other_critical");
+
+ return;
+ }
+
+ g_setenv("SPICE_ABORT_LEVEL", "0", TRUE);
+ g_setenv("SPICE_DEBUG_LEVEL", "1", TRUE);
+ g_test_trap_subprocess(NULL, 0, 0);
+ g_unsetenv("SPICE_ABORT_LEVEL");
+ g_unsetenv("SPICE_DEBUG_LEVEL");
+ g_test_trap_assert_passed();
+ g_test_trap_assert_stderr("*SPICE_DEBUG_LEVEL*deprecated*");
+ g_test_trap_assert_stderr("*SPICE_ABORT_LEVEL*deprecated*");
+ g_test_trap_assert_stderr("*spice_critical\n*g_critical\n*other_message\n*other_warning\n*other_critical\n");
+}
+
+/* Checks that setting G_MESSAGES_DEBUG to 'Spice' impacts spice_debug() and
+ * g_debug() but not other_debug() */
+static void test_spice_g_messages_debug(void)
+{
+ if (g_test_subprocess()) {
+ g_setenv("G_MESSAGES_DEBUG", "Spice", TRUE);
+
+ spice_debug("spice_debug");
+ spice_info("spice_info");
+ g_debug("g_debug");
+ g_info("g_info");
+ g_message("g_message");
+ other_debug("other_debug");
+ other_info("other_info");
+ other_message("other_message");
+
+ return;
+ }
+
+ g_test_trap_subprocess(NULL, 0, 0);
+ g_test_trap_assert_passed();
+ g_test_trap_assert_stdout("*spice_debug\n*spice_info\n*g_debug\n*g_info\n");
+ g_test_trap_assert_stderr("*g_message\n*other_message\n");
+}
+
+/* Checks that setting G_MESSAGES_DEBUG to 'all' impacts spice_debug(),
+ * g_debug() and other_debug() */
+static void test_spice_g_messages_debug_all(void)
+{
+ if (g_test_subprocess()) {
+ g_setenv("G_MESSAGES_DEBUG", "all", TRUE);
+
+ spice_debug("spice_debug");
+ spice_info("spice_info");
+ g_debug("g_debug");
+ g_info("g_info");
+ g_message("g_message");
+ other_debug("other_debug");
+ other_info("other_info");
+ other_message("other_message");
+
+ return;
+ }
+
+ g_test_trap_subprocess(NULL, 0, 0);
+ g_test_trap_assert_passed();
+ g_test_trap_assert_stdout("*spice_debug\n*spice_info\n*g_debug\n*g_info\n*other_debug\n*other_info\n");
+ g_test_trap_assert_stderr("*g_message\n*other_message\n");
+}
+#endif /* GLIB_CHECK_VERSION(2,38,0) */
+
+static void handle_sigabrt(int sig)
+{
+ _Exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ GLogLevelFlags fatal_mask;
+
+ /* prevents core generations as this could cause some issues/timeout
+ * depending on system configuration */
+ signal(SIGABRT, handle_sigabrt);
+
+ fatal_mask = (GLogLevelFlags)g_log_set_always_fatal((GLogLevelFlags) G_LOG_FATAL_MASK);
+
+ g_test_init(&argc, &argv, NULL);
+
+ /* Reset fatal mask set by g_test_init() as we don't want
+ * warnings/criticals to be fatal by default since this is what some of the
+ * test cases are going to test */
+ g_log_set_always_fatal(fatal_mask & G_LOG_LEVEL_MASK);
+
+#if GLIB_CHECK_VERSION(2,38,0)
+ g_test_add_func("/spice-common/spice-abort-level", test_spice_abort_level);
+ g_test_add_func("/spice-common/spice-abort-level-gwarning", test_spice_abort_level_g_warning);
+ g_test_add_func("/spice-common/spice-debug-level", test_spice_debug_level);
+ g_test_add_func("/spice-common/spice-debug-level-warning", test_spice_debug_level_warning);
+ g_test_add_func("/spice-common/spice-g-messages-debug", test_spice_g_messages_debug);
+ g_test_add_func("/spice-common/spice-g-messages-debug-all", test_spice_g_messages_debug_all);
+ g_test_add_func("/spice-common/spice-log-levels", test_log_levels);
+ g_test_add_func("/spice-common/spice-fatal-critical", test_spice_fatal_critical);
+ g_test_add_func("/spice-common/spice-non-fatal-gcritical", test_spice_non_fatal_g_critical);
+ g_test_add_func("/spice-common/spice-fatal-gcritical", test_spice_fatal_g_critical);
+ g_test_add_func("/spice-common/spice-fatal-return-if-fail", test_spice_fatal_return_if_fail);
+ g_test_add_func("/spice-common/spice-non-fatal-greturn-if-fail", test_spice_non_fatal_g_return_if_fail);
+ g_test_add_func("/spice-common/spice-fatal-warning", test_spice_fatal_warning);
+#endif /* GLIB_CHECK_VERSION(2,38,0) */
+
+ return g_test_run();
+}
--- /dev/null
+#include <glib.h>
+#include <string.h>
+
+#include "common/marshaller.h"
+#include "generated_test_marshallers.h"
+
+#ifndef g_assert_true
+#define g_assert_true g_assert
+#endif
+
+static uint8_t expected_data[] = { 0x02, 0x00, 0x00, 0x00, /* data_size */
+ 0x08, 0x00, 0x00, 0x00, /* data offset */
+ 0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12, /* data */
+ 0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12, /* data */
+};
+
+int main(int argc, char **argv)
+{
+ SpiceMarshaller *marshaller;
+ SpiceMsgMainShortDataSubMarshall *msg;
+ size_t len;
+ int free_res;
+ uint8_t *data;
+
+ msg = spice_malloc0(sizeof(SpiceMsgMainShortDataSubMarshall) + 2 * sizeof(uint64_t));
+ msg->data_size = 2;
+ msg->data[0] = 0x1234567890abcdef;
+ msg->data[1] = 0x1234567890abcdef;
+
+ marshaller = spice_marshaller_new();
+ spice_marshall_msg_main_ShortDataSubMarshall(marshaller, msg);
+ spice_marshaller_flush(marshaller);
+ data = spice_marshaller_linearize(marshaller, 0, &len, &free_res);
+ g_assert_cmpint(len, ==, G_N_ELEMENTS(expected_data));
+ g_assert_true(memcmp(data, expected_data, len) == 0);
+ if (free_res) {
+ free(data);
+ }
+ spice_marshaller_destroy(marshaller);
+ free(msg);
+
+ return 0;
+}
--- /dev/null
+#include <stdint.h>
+
+#ifndef _H_TEST_MARSHALLERS
+
+typedef struct {
+ uint32_t data_size;
+ uint64_t data[];
+} SpiceMsgMainShortDataSubMarshall;
+
+#endif /* _H_TEST_MARSHALLERS */
+
--- /dev/null
+channel TestChannel {
+ message {
+ uint32 data_size;
+ uint64 *data[data_size] @marshall;
+ } ShortDataSubMarshall;
+};
+
+protocol Spice {
+ TestChannel main = 1;
+};
--- /dev/null
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: spice-controller
+Description: SPICE Client controller library
+Version: @VERSION@
+
+Requires: glib-2.0
+Libs: -L${libdir} -lspice-controller
+Cflags: -I${includedir}/spice-controller
--- /dev/null
+NULL =
+SUBDIRS =
+
+if WITH_CONTROLLER
+SUBDIRS += controller
+endif
+
+# Avoid need for perl(Text::CSV) by end users
+KEYMAPS = \
+ vncdisplaykeymap_xorgevdev2xtkbd.c \
+ vncdisplaykeymap_xorgkbd2xtkbd.c \
+ vncdisplaykeymap_xorgxquartz2xtkbd.c \
+ vncdisplaykeymap_xorgxwin2xtkbd.c \
+ vncdisplaykeymap_osx2xtkbd.c \
+ vncdisplaykeymap_win322xtkbd.c \
+ vncdisplaykeymap_x112xtkbd.c \
+ $(NULL)
+
+# End users build dependencies can be cleaned
+GLIBGENS = \
+ spice-glib-enums.c \
+ spice-glib-enums.h \
+ spice-marshal.c \
+ spice-marshal.h \
+ spice-widget-enums.c \
+ spice-widget-enums.h \
+ $(NULL)
+
+CLEANFILES = $(GLIBGENS)
+BUILT_SOURCES = $(GLIBGENS) $(KEYMAPS)
+
+EXTRA_DIST = \
+ $(KEYMAPS) \
+ decode-glz-tmpl.c \
+ keymap-gen.pl \
+ keymaps.csv \
+ map-file \
+ spice-glib-sym-file \
+ spice-gtk-sym-file \
+ spice-client-gtk-manual.defs \
+ spice-client-gtk.override \
+ spice-marshal.txt \
+ spice-version.h.in \
+ $(NULL)
+
+DISTCLEANFILES = spice-version.h
+
+bin_PROGRAMS = spicy-stats spicy-screenshot
+if WITH_GTK
+bin_PROGRAMS += spicy
+endif
+if WITH_POLKIT
+acldir = $(ACL_HELPER_DIR)
+acl_PROGRAMS = spice-client-glib-usb-acl-helper
+endif
+
+lib_LTLIBRARIES = libspice-client-glib-2.0.la
+
+if WITH_GTK
+lib_LTLIBRARIES += libspice-client-gtk-3.0.la
+endif
+
+if HAVE_LD_VERSION_SCRIPT
+GLIB_SYMBOLS_LDFLAGS = -Wl,--version-script=${srcdir}/map-file
+GLIB_SYMBOLS_FILE = map-file
+GTK_SYMBOLS_LDFLAGS = $(GLIB_SYMBOLS_LDFLAGS)
+GTK_SYMBOLS_FILE = $(GLIB_SYMBOLS_FILE)
+else
+GLIB_SYMBOLS_LDFLAGS = -export-symbols ${srcdir}/spice-glib-sym-file
+GLIB_SYMBOLS_FILE = spice-glib-sym-file
+GTK_SYMBOLS_LDFLAGS = -export-symbols ${srcdir}/spice-gtk-sym-file
+GTK_SYMBOLS_FILE = spice-gtk-sym-file
+endif
+
+KEYMAP_GEN = $(srcdir)/keymap-gen.pl
+
+SPICE_COMMON_CPPFLAGS = \
+ -DSPICE_COMPILATION \
+ -DG_LOG_DOMAIN=\"GSpice\" \
+ -DSPICE_NO_DEPRECATED \
+ -DSPICE_GTK_LOCALEDIR=\"${SPICE_GTK_LOCALEDIR}\" \
+ -DPNP_IDS=\""$(PNP_IDS)"\" \
+ -DUSB_IDS=\""$(USB_IDS)"\" \
+ -DSPICE_DISABLE_ABORT \
+ -I$(top_srcdir) \
+ $(COMMON_CFLAGS) \
+ $(PIXMAN_CFLAGS) \
+ $(PULSE_CFLAGS) \
+ $(GTK_CFLAGS) \
+ $(CAIRO_CFLAGS) \
+ $(GLIB2_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(GOBJECT2_CFLAGS) \
+ $(SSL_CFLAGS) \
+ $(SASL_CFLAGS) \
+ $(GSTAUDIO_CFLAGS) \
+ $(GSTVIDEO_CFLAGS) \
+ $(SMARTCARD_CFLAGS) \
+ $(USBREDIR_CFLAGS) \
+ $(GUDEV_CFLAGS) \
+ $(SOUP_CFLAGS) \
+ $(PHODAV_CFLAGS) \
+ $(X11_CFLAGS) \
+ $(LZ4_CFLAGS) \
+ $(NULL)
+
+AM_CPPFLAGS = \
+ -DLOCALE_DIR=\""$(datadir)/locale"\" \
+ $(SPICE_COMMON_CPPFLAGS) \
+ $(SPICE_CFLAGS) \
+ $(NULL)
+
+# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+SPICE_GTK_LDFLAGS_COMMON = \
+ -version-info 5:0:0 \
+ -no-undefined \
+ $(GTK_SYMBOLS_LDFLAGS) \
+ $(NULL)
+
+SPICE_GTK_LIBADD_COMMON = \
+ libspice-client-glib-2.0.la \
+ $(GTK_LIBS) \
+ $(CAIRO_LIBS) \
+ $(X11_LIBS) \
+ $(LIBM) \
+ $(NULL)
+
+SPICE_GTK_SOURCES_COMMON = \
+ spice-util.c \
+ spice-util-priv.h \
+ spice-gtk-session.c \
+ spice-gtk-session-priv.h \
+ spice-widget.c \
+ spice-widget-priv.h \
+ spice-file-transfer-task.h \
+ vncdisplaykeymap.c \
+ vncdisplaykeymap.h \
+ spice-grabsequence.c \
+ spice-grabsequence.h \
+ spice-grabsequence-priv.h \
+ desktop-integration.c \
+ desktop-integration.h \
+ usb-device-widget.c \
+ $(NULL)
+
+nodist_SPICE_GTK_SOURCES_COMMON = \
+ spice-widget-enums.c \
+ spice-marshal.c \
+ $(NULL)
+
+SPICE_GTK_SOURCES_COMMON += \
+ spice-widget-cairo.c \
+ $(NULL)
+
+if !OS_WIN32
+SPICE_GTK_SOURCES_COMMON += \
+ spice-widget-egl.c \
+ $(NULL)
+endif
+
+if WITH_GTK
+EXTRA_libspice_client_gtk_3_0_la_DEPENDENCIES = $(GTK_SYMBOLS_FILE)
+libspice_client_gtk_3_0_la_LDFLAGS = $(SPICE_GTK_LDFLAGS_COMMON)
+libspice_client_gtk_3_0_la_LIBADD = $(SPICE_GTK_LIBADD_COMMON)
+libspice_client_gtk_3_0_la_SOURCES = $(SPICE_GTK_SOURCES_COMMON)
+nodist_libspice_client_gtk_3_0_la_SOURCES = $(nodist_SPICE_GTK_SOURCES_COMMON)
+
+libspice_client_gtkincludedir = $(includedir)/spice-client-gtk-3.0
+libspice_client_gtkinclude_HEADERS = \
+ spice-client-gtk.h \
+ spice-gtk-session.h \
+ spice-widget.h \
+ spice-grabsequence.h \
+ usb-device-widget.h \
+ $(NULL)
+
+nodist_libspice_client_gtkinclude_HEADERS = \
+ spice-widget-enums.h \
+ $(NULL)
+endif
+
+EXTRA_libspice_client_glib_2_0_la_DEPENDENCIES = $(GLIB_SYMBOLS_FILE)
+
+libspice_client_glib_2_0_la_LDFLAGS = \
+ -version-info 14:0:6 \
+ -no-undefined \
+ $(GLIB_SYMBOLS_LDFLAGS) \
+ $(NULL)
+
+libspice_client_glib_2_0_la_LIBADD = \
+ $(top_builddir)/spice-common/common/libspice-common.la \
+ $(top_builddir)/spice-common/common/libspice-common-client.la \
+ $(GLIB2_LIBS) \
+ $(SOUP_LIBS) \
+ $(GIO_LIBS) \
+ $(GOBJECT2_LIBS) \
+ $(JPEG_LIBS) \
+ $(Z_LIBS) \
+ $(LZ4_LIBS) \
+ $(PIXMAN_LIBS) \
+ $(SSL_LIBS) \
+ $(PULSE_LIBS) \
+ $(GSTAUDIO_LIBS) \
+ $(GSTVIDEO_LIBS) \
+ $(SASL_LIBS) \
+ $(SMARTCARD_LIBS) \
+ $(USBREDIR_LIBS) \
+ $(GUDEV_LIBS) \
+ $(PHODAV_LIBS) \
+ $(NULL)
+
+if WITH_POLKIT
+USB_ACL_HELPER_SRCS = \
+ usb-acl-helper.c \
+ usb-acl-helper.h \
+ $(NULL)
+AM_CPPFLAGS += -DACL_HELPER_PATH="\"$(ACL_HELPER_DIR)\""
+else
+USB_ACL_HELPER_SRCS =
+endif
+
+libspice_client_glib_2_0_la_SOURCES = \
+ bio-gio.c \
+ bio-gio.h \
+ spice-audio.c \
+ spice-audio-priv.h \
+ spice-common.h \
+ spice-util.c \
+ spice-util-priv.h \
+ spice-option.h \
+ spice-option.c \
+ \
+ spice-client.c \
+ spice-session.c \
+ spice-session-priv.h \
+ spice-channel.c \
+ spice-channel-cache.h \
+ spice-channel-priv.h \
+ spice-file-transfer-task.c \
+ spice-file-transfer-task-priv.h \
+ coroutine.h \
+ gio-coroutine.c \
+ gio-coroutine.h \
+ \
+ channel-base.c \
+ channel-webdav.c \
+ channel-cursor.c \
+ channel-display.c \
+ channel-display-priv.h \
+ channel-inputs.c \
+ channel-main.c \
+ channel-playback.c \
+ channel-playback-priv.h \
+ channel-port.c \
+ channel-record.c \
+ channel-smartcard.c \
+ channel-usbredir.c \
+ channel-usbredir-priv.h \
+ smartcard-manager.c \
+ smartcard-manager-priv.h \
+ spice-uri.c \
+ spice-uri-priv.h \
+ usb-device-manager.c \
+ usb-device-manager-priv.h \
+ usbutil.c \
+ usbutil.h \
+ $(USB_ACL_HELPER_SRCS) \
+ vmcstream.c \
+ vmcstream.h \
+ wocky-http-proxy.c \
+ wocky-http-proxy.h \
+ \
+ decode.h \
+ decode-glz.c \
+ decode-jpeg.c \
+ decode-zlib.c \
+ \
+ client_sw_canvas.c \
+ client_sw_canvas.h \
+ \
+ spice-glib-main.c \
+ $(NULL)
+
+nodist_libspice_client_glib_2_0_la_SOURCES = \
+ spice-glib-enums.c \
+ spice-marshal.c \
+ spice-marshal.h \
+ $(NULL)
+
+libspice_client_glibincludedir = $(includedir)/spice-client-glib-2.0
+libspice_client_glibinclude_HEADERS = \
+ spice-audio.h \
+ spice-client.h \
+ spice-uri.h \
+ spice-types.h \
+ spice-session.h \
+ spice-channel.h \
+ spice-util.h \
+ spice-option.h \
+ spice-version.h \
+ channel-cursor.h \
+ channel-display.h \
+ channel-inputs.h \
+ channel-main.h \
+ channel-playback.h \
+ channel-port.h \
+ channel-record.h \
+ channel-smartcard.h \
+ channel-usbredir.h \
+ channel-webdav.h \
+ usb-device-manager.h \
+ smartcard-manager.h \
+ spice-file-transfer-task.h \
+ $(NULL)
+
+nodist_libspice_client_glibinclude_HEADERS = \
+ spice-glib-enums.h \
+ $(NULL)
+
+# file for API compatibility, but we don't want warning during our compilation
+dist_libspice_client_glibinclude_DATA = \
+ spice-channel-enums.h \
+ $(NULL)
+
+if HAVE_PULSE
+libspice_client_glib_2_0_la_SOURCES += \
+ spice-pulse.c \
+ spice-pulse.h \
+ $(NULL)
+endif
+
+if HAVE_GSTAUDIO
+libspice_client_glib_2_0_la_SOURCES += \
+ spice-gstaudio.c \
+ spice-gstaudio.h \
+ $(NULL)
+endif
+
+if HAVE_BUILTIN_MJPEG
+libspice_client_glib_2_0_la_SOURCES += \
+ channel-display-mjpeg.c \
+ $(NULL)
+endif
+
+if HAVE_GSTVIDEO
+libspice_client_glib_2_0_la_SOURCES += \
+ channel-display-gst.c \
+ $(NULL)
+endif
+
+if WITH_PHODAV
+libspice_client_glib_2_0_la_SOURCES += \
+ giopipe.c \
+ giopipe.h \
+ $(NULL)
+endif
+
+if WITH_UCONTEXT
+libspice_client_glib_2_0_la_SOURCES += continuation.h continuation.c coroutine_ucontext.c
+endif
+
+if WITH_WINFIBER
+libspice_client_glib_2_0_la_SOURCES += coroutine_winfibers.c
+endif
+
+if WITH_GTHREAD
+libspice_client_glib_2_0_la_SOURCES += coroutine_gthread.c
+libspice_client_glib_2_0_la_LIBADD += $(GTHREAD_LIBS)
+endif
+
+
+WIN_USB_FILES= \
+ win-usb-dev.h \
+ win-usb-dev.c \
+ win-usb-clerk.h \
+ win-usb-driver-install.h \
+ win-usb-driver-install.c \
+ usbdk_api.h \
+ usbdk_api.c \
+ $(NULL)
+
+if OS_WIN32
+if WITH_USBREDIR
+libspice_client_glib_2_0_la_SOURCES += \
+ $(WIN_USB_FILES)
+endif
+libspice_client_glib_2_0_la_LIBADD += -lws2_32 -lgdi32
+endif
+
+spicy_SOURCES = \
+ spicy.c \
+ spicy-connect.h \
+ spicy-connect.c \
+ spice-cmdline.h \
+ spice-cmdline.c \
+ $(NULL)
+
+spicy_LDADD = \
+ libspice-client-gtk-3.0.la \
+ libspice-client-glib-2.0.la \
+ $(GTHREAD_LIBS) \
+ $(GTK_LIBS) \
+ $(LIBM) \
+ $(NULL)
+
+spicy_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ $(GTHREAD_CFLAGS) \
+ -DSPICE_DISABLE_DEPRECATED \
+ $(NULL)
+
+
+if WITH_POLKIT
+spice_client_glib_usb_acl_helper_SOURCES = \
+ spice-client-glib-usb-acl-helper.c \
+ $(NULL)
+
+spice_client_glib_usb_acl_helper_LDADD = \
+ $(GLIB2_LIBS) \
+ $(GIO_LIBS) \
+ $(POLKIT_LIBS) \
+ $(ACL_LIBS) \
+ $(PIE_LDFLAGS) \
+ $(NULL)
+
+spice_client_glib_usb_acl_helper_CPPFLAGS = \
+ $(SPICE_CFLAGS) \
+ $(GLIB2_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(POLKIT_CFLAGS) \
+ $(PIE_CFLAGS) \
+ $(NULL)
+
+install-data-hook:
+ -chown root $(DESTDIR)$(acldir)/spice-client-glib-usb-acl-helper
+ -chmod u+s $(DESTDIR)$(acldir)/spice-client-glib-usb-acl-helper
+
+endif
+
+
+spicy_screenshot_SOURCES = \
+ spicy-screenshot.c \
+ spice-cmdline.h \
+ spice-cmdline.c \
+ $(NULL)
+
+spicy_screenshot_LDADD = \
+ libspice-client-glib-2.0.la \
+ $(GOBJECT2_LIBS) \
+ $(NULL)
+
+spicy_stats_SOURCES = \
+ spicy-stats.c \
+ spice-cmdline.h \
+ spice-cmdline.c \
+ $(NULL)
+
+spicy_stats_LDADD = \
+ libspice-client-glib-2.0.la \
+ $(GOBJECT2_LIBS) \
+ $(NULL)
+
+
+
+$(libspice_client_glib_2_0_la_SOURCES): spice-glib-enums.h spice-marshal.h
+
+if WITH_GTK
+$(libspice_client_gtk_3_0_la_SOURCES): spice-glib-enums.h spice-widget-enums.h
+endif
+
+spice-marshal.c: spice-marshal.h
+spice-glib-enums.c: spice-glib-enums.h
+spice-widget-enums.c: spice-widget-enums.h
+
+spice-marshal.c: spice-marshal.txt
+ $(AM_V_GEN)echo "#include \"config.h\"" > $@ && \
+ echo "#include \"spice-marshal.h\"" > $@ && \
+ glib-genmarshal --body $< >> $@ || (rm -f $@ && exit 1)
+
+spice-marshal.h: spice-marshal.txt
+ $(AM_V_GEN)glib-genmarshal --header $< > $@ || (rm -f $@ && exit 1)
+
+spice-glib-enums.c: spice-channel.h channel-inputs.h spice-session.h
+ $(AM_V_GEN)glib-mkenums --fhead "#include \"config.h\"\n\n" \
+ --fhead "#include <glib-object.h>\n" \
+ --fhead "#include \"spice-glib-enums.h\"\n\n" \
+ --fprod "\n#include \"spice-session.h\"\n" \
+ --fprod "\n#include \"spice-channel.h\"\n" \
+ --fprod "\n#include \"channel-inputs.h\"\n" \
+ --vhead "static const G@Type@Value _@enum_name@_values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n};\n\n" \
+ --vtail "GType\n@enum_name@_get_type (void)\n{\n" \
+ --vtail " static GType type = 0;\n" \
+ --vtail " static volatile gsize type_volatile = 0;\n\n" \
+ --vtail " if (g_once_init_enter(&type_volatile)) {\n" \
+ --vtail " type = g_@type@_register_static (\"@EnumName@\", _@enum_name@_values);\n" \
+ --vtail " g_once_init_leave(&type_volatile, type);\n" \
+ --vtail " }\n\n" \
+ --vtail " return type;\n}\n\n" \
+ $^ > $@
+
+spice-glib-enums.h: spice-channel.h channel-inputs.h spice-session.h
+ $(AM_V_GEN)glib-mkenums --fhead "#ifndef SPICE_GLIB_ENUMS_H\n" \
+ --fhead "#define SPICE_GLIB_ENUMS_H\n\n" \
+ --fhead "G_BEGIN_DECLS\n\n" \
+ --ftail "G_END_DECLS\n\n" \
+ --ftail "#endif /* SPICE_CHANNEL_ENUMS_H */\n" \
+ --eprod "#define SPICE_TYPE_@ENUMSHORT@ @enum_name@_get_type()\n" \
+ --eprod "GType @enum_name@_get_type (void);\n" \
+ $^ > $@
+
+spice-widget-enums.c: spice-widget.h
+ $(AM_V_GEN)glib-mkenums --fhead "#include \"config.h\"\n\n" \
+ --fhead "#include <glib-object.h>\n" \
+ --fhead "#include \"spice-widget-enums.h\"\n\n" \
+ --fprod "\n#include \"spice-widget.h\"\n" \
+ --vhead "static const G@Type@Value _@enum_name@_values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n};\n\n" \
+ --vtail "GType\n@enum_name@_get_type (void)\n{\n" \
+ --vtail " static GType type = 0;\n" \
+ --vtail " static volatile gsize type_volatile = 0;\n\n" \
+ --vtail " if (g_once_init_enter(&type_volatile)) {\n" \
+ --vtail " type = g_@type@_register_static (\"@EnumName@\", _@enum_name@_values);\n" \
+ --vtail " g_once_init_leave(&type_volatile, type);\n" \
+ --vtail " }\n\n" \
+ --vtail " return type;\n}\n\n" \
+ $< > $@
+
+spice-widget-enums.h: spice-widget.h
+ $(AM_V_GEN)glib-mkenums --fhead "#ifndef SPICE_WIDGET_ENUMS_H\n" \
+ --fhead "#define SPICE_WIDGET_ENUMS_H\n\n" \
+ --fhead "G_BEGIN_DECLS\n\n" \
+ --ftail "G_END_DECLS\n\n" \
+ --ftail "#endif /* SPICE_WIDGET_ENUMS_H */\n" \
+ --eprod "#define SPICE_TYPE_@ENUMSHORT@ @enum_name@_get_type()\n" \
+ --eprod "GType @enum_name@_get_type (void);\n" \
+ $< > $@
+
+
+vncdisplaykeymap.c: $(KEYMAPS)
+
+$(KEYMAPS): $(KEYMAP_GEN) keymaps.csv
+
+# Note despite being autogenerated these are not part of CLEANFILES, they
+# are actually a part of EXTRA_DIST to avoid the need for perl(Text::CSV) by
+# end users
+vncdisplaykeymap_xorgevdev2xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgevdev xtkbd > $@ || rm $@
+
+vncdisplaykeymap_xorgkbd2xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgkbd xtkbd > $@ || rm $@
+
+vncdisplaykeymap_xorgxquartz2xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgxquartz xtkbd > $@ || rm $@
+
+vncdisplaykeymap_xorgxwin2xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgxwin xtkbd > $@ || rm $@
+
+vncdisplaykeymap_osx2xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv osx xtkbd > $@ || rm $@
+
+vncdisplaykeymap_win322xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv win32 xtkbd > $@ || rm $@
+
+vncdisplaykeymap_x112xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv x11 xtkbd > $@ || rm $@
+
+-include $(INTROSPECTION_MAKEFILE)
+
+if G_IR_SCANNER_SYMBOL_PREFIX
+PREFIX_ARGS = --symbol-prefix=spice --identifier-prefix=Spice
+else
+PREFIX_ARGS = --strip-prefix=Spice
+endif
+
+INTROSPECTION_GIRS =
+INTROSPECTION_SCANNER_ARGS = --warn-all --accept-unprefixed --add-include-path=$(builddir) $(PREFIX_ARGS)
+INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir)
+
+if HAVE_INTROSPECTION
+glib_introspection_files = \
+ $(libspice_client_glibinclude_HEADERS) \
+ $(nodist_libspice_client_glibinclude_HEADERS) \
+ spice-audio.c \
+ spice-client.c \
+ spice-session.c \
+ spice-channel.c \
+ spice-glib-enums.c \
+ spice-option.c \
+ spice-util.c \
+ channel-webdav.c \
+ channel-cursor.c \
+ channel-display.c \
+ channel-inputs.c \
+ channel-main.c \
+ channel-playback.c \
+ channel-port.c \
+ channel-record.c \
+ channel-smartcard.c \
+ channel-usbredir.c \
+ smartcard-manager.c \
+ usb-device-manager.c \
+ $(NULL)
+
+gtk_introspection_files = \
+ $(libspice_client_gtkinclude_HEADERS) \
+ $(nodist_libspice_client_gtkinclude_HEADERS) \
+ spice-gtk-session.c \
+ spice-widget.c \
+ spice-grabsequence.c \
+ usb-device-widget.c \
+ $(NULL)
+
+SpiceClientGLib-2.0.gir: libspice-client-glib-2.0.la
+SpiceClientGLib_2_0_gir_INCLUDES = GObject-2.0 Gio-2.0
+SpiceClientGLib_2_0_gir_CFLAGS = $(SPICE_COMMON_CPPFLAGS)
+SpiceClientGLib_2_0_gir_LIBS = libspice-client-glib-2.0.la
+SpiceClientGLib_2_0_gir_FILES = $(glib_introspection_files)
+SpiceClientGLib_2_0_gir_EXPORT_PACKAGES = spice-client-glib-2.0
+SpiceClientGLib_2_0_gir_SCANNERFLAGS = --c-include="spice-client.h"
+INTROSPECTION_GIRS += SpiceClientGLib-2.0.gir
+
+if WITH_GTK
+SpiceClientGtk-3.0.gir: libspice-client-gtk-3.0.la SpiceClientGLib-2.0.gir
+SpiceClientGtk_3_0_gir_INCLUDES = GObject-2.0 Gtk-3.0 SpiceClientGLib-2.0
+SpiceClientGtk_3_0_gir_CFLAGS = $(SPICE_COMMON_CPPFLAGS)
+SpiceClientGtk_3_0_gir_LIBS = libspice-client-gtk-3.0.la libspice-client-glib-2.0.la
+SpiceClientGtk_3_0_gir_FILES = $(gtk_introspection_files)
+SpiceClientGtk_3_0_gir_EXPORT_PACKAGES = spice-client-gtk-3.0
+SpiceClientGtk_3_0_gir_SCANNERFLAGS = --c-include="spice-widget.h"
+INTROSPECTION_GIRS += SpiceClientGtk-3.0.gir
+endif
+
+girdir = $(datadir)/gir-1.0
+gir_DATA = $(INTROSPECTION_GIRS)
+
+typelibsdir = $(libdir)/girepository-1.0
+typelibs_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+
+CLEANFILES += $(gir_DATA) $(typelibs_DATA)
+endif
+
+update-map-file: $(libspice_client_gtkinclude_HEADERS) $(nodist_libspice_client_gtkinclude_HEADERS) $(libspice_client_glibinclude_HEADERS) $(nodist_libspice_client_glibinclude_HEADERS)
+ ( echo "SPICEGTK_1 {" ; \
+ echo "global:" ; \
+ ctags -f - -I G_GNUC_CONST --c-kinds=p $^ | awk '/^spice_/ { print $$1 ";" }' | sort ; \
+ echo "local:" ; \
+ echo "*;" ; \
+ echo "};" ) > $(srcdir)/map-file
+
+update-glib-sym-file: $(libspice_client_glibinclude_HEADERS) $(nodist_libspice_client_glibinclude_HEADERS)
+ ( ctags -f - -I G_GNUC_CONST --c-kinds=p $^ | awk '/^spice_/ { print $$1 }' | sort ; \
+ ) > $(srcdir)/spice-glib-sym-file
+
+update-gtk-sym-file: $(libspice_client_gtkinclude_HEADERS) $(nodist_libspice_client_gtkinclude_HEADERS)
+ ( ctags -f - -I G_GNUC_CONST --c-kinds=p $^ | awk '/^spice_/ { print $$1 }' | sort ; \
+ ) > $(srcdir)/spice-gtk-sym-file
+
+update-symbol-files: update-map-file update-glib-sym-file update-gtk-sym-file
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@WITH_CONTROLLER_TRUE@am__append_1 = controller
+bin_PROGRAMS = spicy-stats$(EXEEXT) spicy-screenshot$(EXEEXT) \
+ $(am__EXEEXT_1)
+@WITH_GTK_TRUE@am__append_2 = spicy
+@WITH_POLKIT_TRUE@acl_PROGRAMS = \
+@WITH_POLKIT_TRUE@ spice-client-glib-usb-acl-helper$(EXEEXT)
+@WITH_GTK_TRUE@am__append_3 = libspice-client-gtk-3.0.la
+@OS_WIN32_FALSE@am__append_4 = \
+@OS_WIN32_FALSE@ spice-widget-egl.c \
+@OS_WIN32_FALSE@ $(NULL)
+
+@WITH_POLKIT_TRUE@am__append_5 = -DACL_HELPER_PATH="\"$(ACL_HELPER_DIR)\""
+@HAVE_PULSE_TRUE@am__append_6 = \
+@HAVE_PULSE_TRUE@ spice-pulse.c \
+@HAVE_PULSE_TRUE@ spice-pulse.h \
+@HAVE_PULSE_TRUE@ $(NULL)
+
+@HAVE_GSTAUDIO_TRUE@am__append_7 = \
+@HAVE_GSTAUDIO_TRUE@ spice-gstaudio.c \
+@HAVE_GSTAUDIO_TRUE@ spice-gstaudio.h \
+@HAVE_GSTAUDIO_TRUE@ $(NULL)
+
+@HAVE_BUILTIN_MJPEG_TRUE@am__append_8 = \
+@HAVE_BUILTIN_MJPEG_TRUE@ channel-display-mjpeg.c \
+@HAVE_BUILTIN_MJPEG_TRUE@ $(NULL)
+
+@HAVE_GSTVIDEO_TRUE@am__append_9 = \
+@HAVE_GSTVIDEO_TRUE@ channel-display-gst.c \
+@HAVE_GSTVIDEO_TRUE@ $(NULL)
+
+@WITH_PHODAV_TRUE@am__append_10 = \
+@WITH_PHODAV_TRUE@ giopipe.c \
+@WITH_PHODAV_TRUE@ giopipe.h \
+@WITH_PHODAV_TRUE@ $(NULL)
+
+@WITH_UCONTEXT_TRUE@am__append_11 = continuation.h continuation.c coroutine_ucontext.c
+@WITH_WINFIBER_TRUE@am__append_12 = coroutine_winfibers.c
+@WITH_GTHREAD_TRUE@am__append_13 = coroutine_gthread.c
+@WITH_GTHREAD_TRUE@am__append_14 = $(GTHREAD_LIBS)
+@OS_WIN32_TRUE@@WITH_USBREDIR_TRUE@am__append_15 = \
+@OS_WIN32_TRUE@@WITH_USBREDIR_TRUE@ $(WIN_USB_FILES)
+
+@OS_WIN32_TRUE@am__append_16 = -lws2_32 -lgdi32
+@HAVE_INTROSPECTION_TRUE@am__append_17 = SpiceClientGLib-2.0.gir
+@HAVE_INTROSPECTION_TRUE@@WITH_GTK_TRUE@am__append_18 = SpiceClientGtk-3.0.gir
+@HAVE_INTROSPECTION_TRUE@am__append_19 = $(gir_DATA) $(typelibs_DATA)
+subdir = src
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/ld-version.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/manywarnings.m4 \
+ $(top_srcdir)/m4/spice-compile-warnings.m4 \
+ $(top_srcdir)/m4/warnings.m4 \
+ $(top_srcdir)/spice-common/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am \
+ $(dist_libspice_client_glibinclude_DATA) \
+ $(libspice_client_glibinclude_HEADERS) \
+ $(am__libspice_client_gtkinclude_HEADERS_DIST) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = spice-version.h
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(acldir)" \
+ "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(libspice_client_glibincludedir)" \
+ "$(DESTDIR)$(girdir)" "$(DESTDIR)$(typelibsdir)" \
+ "$(DESTDIR)$(libspice_client_glibincludedir)" \
+ "$(DESTDIR)$(libspice_client_gtkincludedir)" \
+ "$(DESTDIR)$(libspice_client_glibincludedir)" \
+ "$(DESTDIR)$(libspice_client_gtkincludedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+@WITH_GTHREAD_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
+libspice_client_glib_2_0_la_DEPENDENCIES = \
+ $(top_builddir)/spice-common/common/libspice-common.la \
+ $(top_builddir)/spice-common/common/libspice-common-client.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
+ $(am__DEPENDENCIES_1)
+am__libspice_client_glib_2_0_la_SOURCES_DIST = bio-gio.c bio-gio.h \
+ spice-audio.c spice-audio-priv.h spice-common.h spice-util.c \
+ spice-util-priv.h spice-option.h spice-option.c spice-client.c \
+ spice-session.c spice-session-priv.h spice-channel.c \
+ spice-channel-cache.h spice-channel-priv.h \
+ spice-file-transfer-task.c spice-file-transfer-task-priv.h \
+ coroutine.h gio-coroutine.c gio-coroutine.h channel-base.c \
+ channel-webdav.c channel-cursor.c channel-display.c \
+ channel-display-priv.h channel-inputs.c channel-main.c \
+ channel-playback.c channel-playback-priv.h channel-port.c \
+ channel-record.c channel-smartcard.c channel-usbredir.c \
+ channel-usbredir-priv.h smartcard-manager.c \
+ smartcard-manager-priv.h spice-uri.c spice-uri-priv.h \
+ usb-device-manager.c usb-device-manager-priv.h usbutil.c \
+ usbutil.h usb-acl-helper.c usb-acl-helper.h vmcstream.c \
+ vmcstream.h wocky-http-proxy.c wocky-http-proxy.h decode.h \
+ decode-glz.c decode-jpeg.c decode-zlib.c client_sw_canvas.c \
+ client_sw_canvas.h spice-glib-main.c spice-pulse.c \
+ spice-pulse.h spice-gstaudio.c spice-gstaudio.h \
+ channel-display-mjpeg.c channel-display-gst.c giopipe.c \
+ giopipe.h continuation.h continuation.c coroutine_ucontext.c \
+ coroutine_winfibers.c coroutine_gthread.c win-usb-dev.h \
+ win-usb-dev.c win-usb-clerk.h win-usb-driver-install.h \
+ win-usb-driver-install.c usbdk_api.h usbdk_api.c
+am__objects_1 =
+@WITH_POLKIT_TRUE@am__objects_2 = usb-acl-helper.lo $(am__objects_1)
+@HAVE_PULSE_TRUE@am__objects_3 = spice-pulse.lo $(am__objects_1)
+@HAVE_GSTAUDIO_TRUE@am__objects_4 = spice-gstaudio.lo $(am__objects_1)
+@HAVE_BUILTIN_MJPEG_TRUE@am__objects_5 = channel-display-mjpeg.lo \
+@HAVE_BUILTIN_MJPEG_TRUE@ $(am__objects_1)
+@HAVE_GSTVIDEO_TRUE@am__objects_6 = channel-display-gst.lo \
+@HAVE_GSTVIDEO_TRUE@ $(am__objects_1)
+@WITH_PHODAV_TRUE@am__objects_7 = giopipe.lo $(am__objects_1)
+@WITH_UCONTEXT_TRUE@am__objects_8 = continuation.lo \
+@WITH_UCONTEXT_TRUE@ coroutine_ucontext.lo
+@WITH_WINFIBER_TRUE@am__objects_9 = coroutine_winfibers.lo
+@WITH_GTHREAD_TRUE@am__objects_10 = coroutine_gthread.lo
+am__objects_11 = win-usb-dev.lo win-usb-driver-install.lo usbdk_api.lo \
+ $(am__objects_1)
+@OS_WIN32_TRUE@@WITH_USBREDIR_TRUE@am__objects_12 = $(am__objects_11)
+am_libspice_client_glib_2_0_la_OBJECTS = bio-gio.lo spice-audio.lo \
+ spice-util.lo spice-option.lo spice-client.lo spice-session.lo \
+ spice-channel.lo spice-file-transfer-task.lo gio-coroutine.lo \
+ channel-base.lo channel-webdav.lo channel-cursor.lo \
+ channel-display.lo channel-inputs.lo channel-main.lo \
+ channel-playback.lo channel-port.lo channel-record.lo \
+ channel-smartcard.lo channel-usbredir.lo smartcard-manager.lo \
+ spice-uri.lo usb-device-manager.lo usbutil.lo $(am__objects_2) \
+ vmcstream.lo wocky-http-proxy.lo decode-glz.lo decode-jpeg.lo \
+ decode-zlib.lo client_sw_canvas.lo spice-glib-main.lo \
+ $(am__objects_1) $(am__objects_3) $(am__objects_4) \
+ $(am__objects_5) $(am__objects_6) $(am__objects_7) \
+ $(am__objects_8) $(am__objects_9) $(am__objects_10) \
+ $(am__objects_12)
+nodist_libspice_client_glib_2_0_la_OBJECTS = spice-glib-enums.lo \
+ spice-marshal.lo $(am__objects_1)
+libspice_client_glib_2_0_la_OBJECTS = \
+ $(am_libspice_client_glib_2_0_la_OBJECTS) \
+ $(nodist_libspice_client_glib_2_0_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libspice_client_glib_2_0_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libspice_client_glib_2_0_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am__DEPENDENCIES_3 = libspice-client-glib-2.0.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+@WITH_GTK_TRUE@libspice_client_gtk_3_0_la_DEPENDENCIES = \
+@WITH_GTK_TRUE@ $(am__DEPENDENCIES_3)
+am__libspice_client_gtk_3_0_la_SOURCES_DIST = spice-util.c \
+ spice-util-priv.h spice-gtk-session.c spice-gtk-session-priv.h \
+ spice-widget.c spice-widget-priv.h spice-file-transfer-task.h \
+ vncdisplaykeymap.c vncdisplaykeymap.h spice-grabsequence.c \
+ spice-grabsequence.h spice-grabsequence-priv.h \
+ desktop-integration.c desktop-integration.h \
+ usb-device-widget.c spice-widget-cairo.c spice-widget-egl.c
+@OS_WIN32_FALSE@am__objects_13 = spice-widget-egl.lo $(am__objects_1)
+am__objects_14 = spice-util.lo spice-gtk-session.lo spice-widget.lo \
+ vncdisplaykeymap.lo spice-grabsequence.lo \
+ desktop-integration.lo usb-device-widget.lo $(am__objects_1) \
+ spice-widget-cairo.lo $(am__objects_1) $(am__objects_13)
+@WITH_GTK_TRUE@am_libspice_client_gtk_3_0_la_OBJECTS = \
+@WITH_GTK_TRUE@ $(am__objects_14)
+am__objects_15 = spice-widget-enums.lo spice-marshal.lo \
+ $(am__objects_1)
+@WITH_GTK_TRUE@nodist_libspice_client_gtk_3_0_la_OBJECTS = \
+@WITH_GTK_TRUE@ $(am__objects_15)
+libspice_client_gtk_3_0_la_OBJECTS = \
+ $(am_libspice_client_gtk_3_0_la_OBJECTS) \
+ $(nodist_libspice_client_gtk_3_0_la_OBJECTS)
+libspice_client_gtk_3_0_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libspice_client_gtk_3_0_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@WITH_GTK_TRUE@am_libspice_client_gtk_3_0_la_rpath = -rpath $(libdir)
+@WITH_GTK_TRUE@am__EXEEXT_1 = spicy$(EXEEXT)
+PROGRAMS = $(acl_PROGRAMS) $(bin_PROGRAMS)
+am__spice_client_glib_usb_acl_helper_SOURCES_DIST = \
+ spice-client-glib-usb-acl-helper.c
+@WITH_POLKIT_TRUE@am_spice_client_glib_usb_acl_helper_OBJECTS = spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.$(OBJEXT) \
+@WITH_POLKIT_TRUE@ $(am__objects_1)
+spice_client_glib_usb_acl_helper_OBJECTS = \
+ $(am_spice_client_glib_usb_acl_helper_OBJECTS)
+@WITH_POLKIT_TRUE@spice_client_glib_usb_acl_helper_DEPENDENCIES = \
+@WITH_POLKIT_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@WITH_POLKIT_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+@WITH_POLKIT_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_spicy_OBJECTS = spicy-spicy.$(OBJEXT) spicy-spicy-connect.$(OBJEXT) \
+ spicy-spice-cmdline.$(OBJEXT) $(am__objects_1)
+spicy_OBJECTS = $(am_spicy_OBJECTS)
+spicy_DEPENDENCIES = libspice-client-gtk-3.0.la \
+ libspice-client-glib-2.0.la $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_spicy_screenshot_OBJECTS = spicy-screenshot.$(OBJEXT) \
+ spice-cmdline.$(OBJEXT) $(am__objects_1)
+spicy_screenshot_OBJECTS = $(am_spicy_screenshot_OBJECTS)
+spicy_screenshot_DEPENDENCIES = libspice-client-glib-2.0.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_spicy_stats_OBJECTS = spicy-stats.$(OBJEXT) spice-cmdline.$(OBJEXT) \
+ $(am__objects_1)
+spicy_stats_OBJECTS = $(am_spicy_stats_OBJECTS)
+spicy_stats_DEPENDENCIES = libspice-client-glib-2.0.la \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libspice_client_glib_2_0_la_SOURCES) \
+ $(nodist_libspice_client_glib_2_0_la_SOURCES) \
+ $(libspice_client_gtk_3_0_la_SOURCES) \
+ $(nodist_libspice_client_gtk_3_0_la_SOURCES) \
+ $(spice_client_glib_usb_acl_helper_SOURCES) $(spicy_SOURCES) \
+ $(spicy_screenshot_SOURCES) $(spicy_stats_SOURCES)
+DIST_SOURCES = $(am__libspice_client_glib_2_0_la_SOURCES_DIST) \
+ $(am__libspice_client_gtk_3_0_la_SOURCES_DIST) \
+ $(am__spice_client_glib_usb_acl_helper_SOURCES_DIST) \
+ $(spicy_SOURCES) $(spicy_screenshot_SOURCES) \
+ $(spicy_stats_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+DATA = $(dist_libspice_client_glibinclude_DATA) $(gir_DATA) \
+ $(typelibs_DATA)
+am__libspice_client_gtkinclude_HEADERS_DIST = spice-client-gtk.h \
+ spice-gtk-session.h spice-widget.h spice-grabsequence.h \
+ usb-device-widget.h
+HEADERS = $(libspice_client_glibinclude_HEADERS) \
+ $(libspice_client_gtkinclude_HEADERS) \
+ $(nodist_libspice_client_glibinclude_HEADERS) \
+ $(nodist_libspice_client_gtkinclude_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = controller
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/spice-version.h.in \
+ $(top_srcdir)/build-aux/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ACL_HELPER_DIR = @ACL_HELPER_DIR@
+ACL_LIBS = @ACL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMMON_CFLAGS = @COMMON_CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GOBJECT2_CFLAGS = @GOBJECT2_CFLAGS@
+GOBJECT2_LIBS = @GOBJECT2_LIBS@
+GREP = @GREP@
+GSTAUDIO_CFLAGS = @GSTAUDIO_CFLAGS@
+GSTAUDIO_LIBS = @GSTAUDIO_LIBS@
+GSTVIDEO_CFLAGS = @GSTVIDEO_CFLAGS@
+GSTVIDEO_LIBS = @GSTVIDEO_LIBS@
+GST_INSPECT_1_0 = @GST_INSPECT_1_0@
+GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
+GTHREAD_LIBS = @GTHREAD_LIBS@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_REQUIRED = @GTK_REQUIRED@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+JPEG_LIBS = @JPEG_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUSB_HOTPLUG_CFLAGS = @LIBUSB_HOTPLUG_CFLAGS@
+LIBUSB_HOTPLUG_LIBS = @LIBUSB_HOTPLUG_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PHODAV_CFLAGS = @PHODAV_CFLAGS@
+PHODAV_LIBS = @PHODAV_LIBS@
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PNP_IDS = @PNP_IDS@
+POFILES = @POFILES@
+POLICYDIR = @POLICYDIR@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PULSE_CFLAGS = @PULSE_CFLAGS@
+PULSE_LIBS = @PULSE_LIBS@
+PYTHON = @PYTHON@
+RANLIB = @RANLIB@
+SASL_CFLAGS = @SASL_CFLAGS@
+SASL_LIBS = @SASL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_CFLAGS = @SPICE_CFLAGS@
+SPICE_GLIB_CFLAGS = @SPICE_GLIB_CFLAGS@
+SPICE_GLIB_REQUIRES = @SPICE_GLIB_REQUIRES@
+SPICE_GTK_CFLAGS = @SPICE_GTK_CFLAGS@
+SPICE_GTK_LOCALEDIR = @SPICE_GTK_LOCALEDIR@
+SPICE_GTK_MAJOR_VERSION = @SPICE_GTK_MAJOR_VERSION@
+SPICE_GTK_MICRO_VERSION = @SPICE_GTK_MICRO_VERSION@
+SPICE_GTK_MINOR_VERSION = @SPICE_GTK_MINOR_VERSION@
+SPICE_GTK_REQUIRES = @SPICE_GTK_REQUIRES@
+SPICE_PROTOCOL_CFLAGS = @SPICE_PROTOCOL_CFLAGS@
+SPICE_PROTOCOL_LIBS = @SPICE_PROTOCOL_LIBS@
+SSL_CFLAGS = @SSL_CFLAGS@
+SSL_LIBS = @SSL_LIBS@
+STOW = @STOW@
+STRIP = @STRIP@
+USBREDIR_CFLAGS = @USBREDIR_CFLAGS@
+USBREDIR_LIBS = @USBREDIR_LIBS@
+USB_IDS = @USB_IDS@
+USE_NLS = @USE_NLS@
+VALAC = @VALAC@
+VAPIDIR = @VAPIDIR@
+VAPIGEN = @VAPIGEN@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_LDFLAGS = @WARN_LDFLAGS@
+WARN_PYFLAGS = @WARN_PYFLAGS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+XGETTEXT = @XGETTEXT@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+SUBDIRS = $(am__append_1)
+
+# Avoid need for perl(Text::CSV) by end users
+KEYMAPS = \
+ vncdisplaykeymap_xorgevdev2xtkbd.c \
+ vncdisplaykeymap_xorgkbd2xtkbd.c \
+ vncdisplaykeymap_xorgxquartz2xtkbd.c \
+ vncdisplaykeymap_xorgxwin2xtkbd.c \
+ vncdisplaykeymap_osx2xtkbd.c \
+ vncdisplaykeymap_win322xtkbd.c \
+ vncdisplaykeymap_x112xtkbd.c \
+ $(NULL)
+
+
+# End users build dependencies can be cleaned
+GLIBGENS = \
+ spice-glib-enums.c \
+ spice-glib-enums.h \
+ spice-marshal.c \
+ spice-marshal.h \
+ spice-widget-enums.c \
+ spice-widget-enums.h \
+ $(NULL)
+
+CLEANFILES = $(GLIBGENS) $(am__append_19)
+BUILT_SOURCES = $(GLIBGENS) $(KEYMAPS)
+EXTRA_DIST = \
+ $(KEYMAPS) \
+ decode-glz-tmpl.c \
+ keymap-gen.pl \
+ keymaps.csv \
+ map-file \
+ spice-glib-sym-file \
+ spice-gtk-sym-file \
+ spice-client-gtk-manual.defs \
+ spice-client-gtk.override \
+ spice-marshal.txt \
+ spice-version.h.in \
+ $(NULL)
+
+DISTCLEANFILES = spice-version.h
+@WITH_POLKIT_TRUE@acldir = $(ACL_HELPER_DIR)
+lib_LTLIBRARIES = libspice-client-glib-2.0.la $(am__append_3)
+@HAVE_LD_VERSION_SCRIPT_FALSE@GLIB_SYMBOLS_LDFLAGS = -export-symbols ${srcdir}/spice-glib-sym-file
+@HAVE_LD_VERSION_SCRIPT_TRUE@GLIB_SYMBOLS_LDFLAGS = -Wl,--version-script=${srcdir}/map-file
+@HAVE_LD_VERSION_SCRIPT_FALSE@GLIB_SYMBOLS_FILE = spice-glib-sym-file
+@HAVE_LD_VERSION_SCRIPT_TRUE@GLIB_SYMBOLS_FILE = map-file
+@HAVE_LD_VERSION_SCRIPT_FALSE@GTK_SYMBOLS_LDFLAGS = -export-symbols ${srcdir}/spice-gtk-sym-file
+@HAVE_LD_VERSION_SCRIPT_TRUE@GTK_SYMBOLS_LDFLAGS = $(GLIB_SYMBOLS_LDFLAGS)
+@HAVE_LD_VERSION_SCRIPT_FALSE@GTK_SYMBOLS_FILE = spice-gtk-sym-file
+@HAVE_LD_VERSION_SCRIPT_TRUE@GTK_SYMBOLS_FILE = $(GLIB_SYMBOLS_FILE)
+KEYMAP_GEN = $(srcdir)/keymap-gen.pl
+SPICE_COMMON_CPPFLAGS = \
+ -DSPICE_COMPILATION \
+ -DG_LOG_DOMAIN=\"GSpice\" \
+ -DSPICE_NO_DEPRECATED \
+ -DSPICE_GTK_LOCALEDIR=\"${SPICE_GTK_LOCALEDIR}\" \
+ -DPNP_IDS=\""$(PNP_IDS)"\" \
+ -DUSB_IDS=\""$(USB_IDS)"\" \
+ -DSPICE_DISABLE_ABORT \
+ -I$(top_srcdir) \
+ $(COMMON_CFLAGS) \
+ $(PIXMAN_CFLAGS) \
+ $(PULSE_CFLAGS) \
+ $(GTK_CFLAGS) \
+ $(CAIRO_CFLAGS) \
+ $(GLIB2_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(GOBJECT2_CFLAGS) \
+ $(SSL_CFLAGS) \
+ $(SASL_CFLAGS) \
+ $(GSTAUDIO_CFLAGS) \
+ $(GSTVIDEO_CFLAGS) \
+ $(SMARTCARD_CFLAGS) \
+ $(USBREDIR_CFLAGS) \
+ $(GUDEV_CFLAGS) \
+ $(SOUP_CFLAGS) \
+ $(PHODAV_CFLAGS) \
+ $(X11_CFLAGS) \
+ $(LZ4_CFLAGS) \
+ $(NULL)
+
+AM_CPPFLAGS = -DLOCALE_DIR=\""$(datadir)/locale"\" \
+ $(SPICE_COMMON_CPPFLAGS) $(SPICE_CFLAGS) $(NULL) \
+ $(am__append_5)
+
+# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+SPICE_GTK_LDFLAGS_COMMON = \
+ -version-info 5:0:0 \
+ -no-undefined \
+ $(GTK_SYMBOLS_LDFLAGS) \
+ $(NULL)
+
+SPICE_GTK_LIBADD_COMMON = \
+ libspice-client-glib-2.0.la \
+ $(GTK_LIBS) \
+ $(CAIRO_LIBS) \
+ $(X11_LIBS) \
+ $(LIBM) \
+ $(NULL)
+
+SPICE_GTK_SOURCES_COMMON = spice-util.c spice-util-priv.h \
+ spice-gtk-session.c spice-gtk-session-priv.h spice-widget.c \
+ spice-widget-priv.h spice-file-transfer-task.h \
+ vncdisplaykeymap.c vncdisplaykeymap.h spice-grabsequence.c \
+ spice-grabsequence.h spice-grabsequence-priv.h \
+ desktop-integration.c desktop-integration.h \
+ usb-device-widget.c $(NULL) spice-widget-cairo.c $(NULL) \
+ $(am__append_4)
+nodist_SPICE_GTK_SOURCES_COMMON = \
+ spice-widget-enums.c \
+ spice-marshal.c \
+ $(NULL)
+
+@WITH_GTK_TRUE@EXTRA_libspice_client_gtk_3_0_la_DEPENDENCIES = $(GTK_SYMBOLS_FILE)
+@WITH_GTK_TRUE@libspice_client_gtk_3_0_la_LDFLAGS = $(SPICE_GTK_LDFLAGS_COMMON)
+@WITH_GTK_TRUE@libspice_client_gtk_3_0_la_LIBADD = $(SPICE_GTK_LIBADD_COMMON)
+@WITH_GTK_TRUE@libspice_client_gtk_3_0_la_SOURCES = $(SPICE_GTK_SOURCES_COMMON)
+@WITH_GTK_TRUE@nodist_libspice_client_gtk_3_0_la_SOURCES = $(nodist_SPICE_GTK_SOURCES_COMMON)
+@WITH_GTK_TRUE@libspice_client_gtkincludedir = $(includedir)/spice-client-gtk-3.0
+@WITH_GTK_TRUE@libspice_client_gtkinclude_HEADERS = \
+@WITH_GTK_TRUE@ spice-client-gtk.h \
+@WITH_GTK_TRUE@ spice-gtk-session.h \
+@WITH_GTK_TRUE@ spice-widget.h \
+@WITH_GTK_TRUE@ spice-grabsequence.h \
+@WITH_GTK_TRUE@ usb-device-widget.h \
+@WITH_GTK_TRUE@ $(NULL)
+
+@WITH_GTK_TRUE@nodist_libspice_client_gtkinclude_HEADERS = \
+@WITH_GTK_TRUE@ spice-widget-enums.h \
+@WITH_GTK_TRUE@ $(NULL)
+
+EXTRA_libspice_client_glib_2_0_la_DEPENDENCIES = $(GLIB_SYMBOLS_FILE)
+libspice_client_glib_2_0_la_LDFLAGS = \
+ -version-info 14:0:6 \
+ -no-undefined \
+ $(GLIB_SYMBOLS_LDFLAGS) \
+ $(NULL)
+
+libspice_client_glib_2_0_la_LIBADD = \
+ $(top_builddir)/spice-common/common/libspice-common.la \
+ $(top_builddir)/spice-common/common/libspice-common-client.la \
+ $(GLIB2_LIBS) $(SOUP_LIBS) $(GIO_LIBS) $(GOBJECT2_LIBS) \
+ $(JPEG_LIBS) $(Z_LIBS) $(LZ4_LIBS) $(PIXMAN_LIBS) $(SSL_LIBS) \
+ $(PULSE_LIBS) $(GSTAUDIO_LIBS) $(GSTVIDEO_LIBS) $(SASL_LIBS) \
+ $(SMARTCARD_LIBS) $(USBREDIR_LIBS) $(GUDEV_LIBS) \
+ $(PHODAV_LIBS) $(NULL) $(am__append_14) $(am__append_16)
+@WITH_POLKIT_FALSE@USB_ACL_HELPER_SRCS =
+@WITH_POLKIT_TRUE@USB_ACL_HELPER_SRCS = \
+@WITH_POLKIT_TRUE@ usb-acl-helper.c \
+@WITH_POLKIT_TRUE@ usb-acl-helper.h \
+@WITH_POLKIT_TRUE@ $(NULL)
+
+libspice_client_glib_2_0_la_SOURCES = bio-gio.c bio-gio.h \
+ spice-audio.c spice-audio-priv.h spice-common.h spice-util.c \
+ spice-util-priv.h spice-option.h spice-option.c spice-client.c \
+ spice-session.c spice-session-priv.h spice-channel.c \
+ spice-channel-cache.h spice-channel-priv.h \
+ spice-file-transfer-task.c spice-file-transfer-task-priv.h \
+ coroutine.h gio-coroutine.c gio-coroutine.h channel-base.c \
+ channel-webdav.c channel-cursor.c channel-display.c \
+ channel-display-priv.h channel-inputs.c channel-main.c \
+ channel-playback.c channel-playback-priv.h channel-port.c \
+ channel-record.c channel-smartcard.c channel-usbredir.c \
+ channel-usbredir-priv.h smartcard-manager.c \
+ smartcard-manager-priv.h spice-uri.c spice-uri-priv.h \
+ usb-device-manager.c usb-device-manager-priv.h usbutil.c \
+ usbutil.h $(USB_ACL_HELPER_SRCS) vmcstream.c vmcstream.h \
+ wocky-http-proxy.c wocky-http-proxy.h decode.h decode-glz.c \
+ decode-jpeg.c decode-zlib.c client_sw_canvas.c \
+ client_sw_canvas.h spice-glib-main.c $(NULL) $(am__append_6) \
+ $(am__append_7) $(am__append_8) $(am__append_9) \
+ $(am__append_10) $(am__append_11) $(am__append_12) \
+ $(am__append_13) $(am__append_15)
+nodist_libspice_client_glib_2_0_la_SOURCES = \
+ spice-glib-enums.c \
+ spice-marshal.c \
+ spice-marshal.h \
+ $(NULL)
+
+libspice_client_glibincludedir = $(includedir)/spice-client-glib-2.0
+libspice_client_glibinclude_HEADERS = \
+ spice-audio.h \
+ spice-client.h \
+ spice-uri.h \
+ spice-types.h \
+ spice-session.h \
+ spice-channel.h \
+ spice-util.h \
+ spice-option.h \
+ spice-version.h \
+ channel-cursor.h \
+ channel-display.h \
+ channel-inputs.h \
+ channel-main.h \
+ channel-playback.h \
+ channel-port.h \
+ channel-record.h \
+ channel-smartcard.h \
+ channel-usbredir.h \
+ channel-webdav.h \
+ usb-device-manager.h \
+ smartcard-manager.h \
+ spice-file-transfer-task.h \
+ $(NULL)
+
+nodist_libspice_client_glibinclude_HEADERS = \
+ spice-glib-enums.h \
+ $(NULL)
+
+
+# file for API compatibility, but we don't want warning during our compilation
+dist_libspice_client_glibinclude_DATA = \
+ spice-channel-enums.h \
+ $(NULL)
+
+WIN_USB_FILES = \
+ win-usb-dev.h \
+ win-usb-dev.c \
+ win-usb-clerk.h \
+ win-usb-driver-install.h \
+ win-usb-driver-install.c \
+ usbdk_api.h \
+ usbdk_api.c \
+ $(NULL)
+
+spicy_SOURCES = \
+ spicy.c \
+ spicy-connect.h \
+ spicy-connect.c \
+ spice-cmdline.h \
+ spice-cmdline.c \
+ $(NULL)
+
+spicy_LDADD = \
+ libspice-client-gtk-3.0.la \
+ libspice-client-glib-2.0.la \
+ $(GTHREAD_LIBS) \
+ $(GTK_LIBS) \
+ $(LIBM) \
+ $(NULL)
+
+spicy_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ $(GTHREAD_CFLAGS) \
+ -DSPICE_DISABLE_DEPRECATED \
+ $(NULL)
+
+@WITH_POLKIT_TRUE@spice_client_glib_usb_acl_helper_SOURCES = \
+@WITH_POLKIT_TRUE@ spice-client-glib-usb-acl-helper.c \
+@WITH_POLKIT_TRUE@ $(NULL)
+
+@WITH_POLKIT_TRUE@spice_client_glib_usb_acl_helper_LDADD = \
+@WITH_POLKIT_TRUE@ $(GLIB2_LIBS) \
+@WITH_POLKIT_TRUE@ $(GIO_LIBS) \
+@WITH_POLKIT_TRUE@ $(POLKIT_LIBS) \
+@WITH_POLKIT_TRUE@ $(ACL_LIBS) \
+@WITH_POLKIT_TRUE@ $(PIE_LDFLAGS) \
+@WITH_POLKIT_TRUE@ $(NULL)
+
+@WITH_POLKIT_TRUE@spice_client_glib_usb_acl_helper_CPPFLAGS = \
+@WITH_POLKIT_TRUE@ $(SPICE_CFLAGS) \
+@WITH_POLKIT_TRUE@ $(GLIB2_CFLAGS) \
+@WITH_POLKIT_TRUE@ $(GIO_CFLAGS) \
+@WITH_POLKIT_TRUE@ $(POLKIT_CFLAGS) \
+@WITH_POLKIT_TRUE@ $(PIE_CFLAGS) \
+@WITH_POLKIT_TRUE@ $(NULL)
+
+spicy_screenshot_SOURCES = \
+ spicy-screenshot.c \
+ spice-cmdline.h \
+ spice-cmdline.c \
+ $(NULL)
+
+spicy_screenshot_LDADD = \
+ libspice-client-glib-2.0.la \
+ $(GOBJECT2_LIBS) \
+ $(NULL)
+
+spicy_stats_SOURCES = \
+ spicy-stats.c \
+ spice-cmdline.h \
+ spice-cmdline.c \
+ $(NULL)
+
+spicy_stats_LDADD = \
+ libspice-client-glib-2.0.la \
+ $(GOBJECT2_LIBS) \
+ $(NULL)
+
+@G_IR_SCANNER_SYMBOL_PREFIX_FALSE@PREFIX_ARGS = --strip-prefix=Spice
+@G_IR_SCANNER_SYMBOL_PREFIX_TRUE@PREFIX_ARGS = --symbol-prefix=spice --identifier-prefix=Spice
+INTROSPECTION_GIRS = $(am__append_17) $(am__append_18)
+INTROSPECTION_SCANNER_ARGS = --warn-all --accept-unprefixed --add-include-path=$(builddir) $(PREFIX_ARGS)
+INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir)
+@HAVE_INTROSPECTION_TRUE@glib_introspection_files = \
+@HAVE_INTROSPECTION_TRUE@ $(libspice_client_glibinclude_HEADERS) \
+@HAVE_INTROSPECTION_TRUE@ $(nodist_libspice_client_glibinclude_HEADERS) \
+@HAVE_INTROSPECTION_TRUE@ spice-audio.c \
+@HAVE_INTROSPECTION_TRUE@ spice-client.c \
+@HAVE_INTROSPECTION_TRUE@ spice-session.c \
+@HAVE_INTROSPECTION_TRUE@ spice-channel.c \
+@HAVE_INTROSPECTION_TRUE@ spice-glib-enums.c \
+@HAVE_INTROSPECTION_TRUE@ spice-option.c \
+@HAVE_INTROSPECTION_TRUE@ spice-util.c \
+@HAVE_INTROSPECTION_TRUE@ channel-webdav.c \
+@HAVE_INTROSPECTION_TRUE@ channel-cursor.c \
+@HAVE_INTROSPECTION_TRUE@ channel-display.c \
+@HAVE_INTROSPECTION_TRUE@ channel-inputs.c \
+@HAVE_INTROSPECTION_TRUE@ channel-main.c \
+@HAVE_INTROSPECTION_TRUE@ channel-playback.c \
+@HAVE_INTROSPECTION_TRUE@ channel-port.c \
+@HAVE_INTROSPECTION_TRUE@ channel-record.c \
+@HAVE_INTROSPECTION_TRUE@ channel-smartcard.c \
+@HAVE_INTROSPECTION_TRUE@ channel-usbredir.c \
+@HAVE_INTROSPECTION_TRUE@ smartcard-manager.c \
+@HAVE_INTROSPECTION_TRUE@ usb-device-manager.c \
+@HAVE_INTROSPECTION_TRUE@ $(NULL)
+
+@HAVE_INTROSPECTION_TRUE@gtk_introspection_files = \
+@HAVE_INTROSPECTION_TRUE@ $(libspice_client_gtkinclude_HEADERS) \
+@HAVE_INTROSPECTION_TRUE@ $(nodist_libspice_client_gtkinclude_HEADERS) \
+@HAVE_INTROSPECTION_TRUE@ spice-gtk-session.c \
+@HAVE_INTROSPECTION_TRUE@ spice-widget.c \
+@HAVE_INTROSPECTION_TRUE@ spice-grabsequence.c \
+@HAVE_INTROSPECTION_TRUE@ usb-device-widget.c \
+@HAVE_INTROSPECTION_TRUE@ $(NULL)
+
+@HAVE_INTROSPECTION_TRUE@SpiceClientGLib_2_0_gir_INCLUDES = GObject-2.0 Gio-2.0
+@HAVE_INTROSPECTION_TRUE@SpiceClientGLib_2_0_gir_CFLAGS = $(SPICE_COMMON_CPPFLAGS)
+@HAVE_INTROSPECTION_TRUE@SpiceClientGLib_2_0_gir_LIBS = libspice-client-glib-2.0.la
+@HAVE_INTROSPECTION_TRUE@SpiceClientGLib_2_0_gir_FILES = $(glib_introspection_files)
+@HAVE_INTROSPECTION_TRUE@SpiceClientGLib_2_0_gir_EXPORT_PACKAGES = spice-client-glib-2.0
+@HAVE_INTROSPECTION_TRUE@SpiceClientGLib_2_0_gir_SCANNERFLAGS = --c-include="spice-client.h"
+@HAVE_INTROSPECTION_TRUE@@WITH_GTK_TRUE@SpiceClientGtk_3_0_gir_INCLUDES = GObject-2.0 Gtk-3.0 SpiceClientGLib-2.0
+@HAVE_INTROSPECTION_TRUE@@WITH_GTK_TRUE@SpiceClientGtk_3_0_gir_CFLAGS = $(SPICE_COMMON_CPPFLAGS)
+@HAVE_INTROSPECTION_TRUE@@WITH_GTK_TRUE@SpiceClientGtk_3_0_gir_LIBS = libspice-client-gtk-3.0.la libspice-client-glib-2.0.la
+@HAVE_INTROSPECTION_TRUE@@WITH_GTK_TRUE@SpiceClientGtk_3_0_gir_FILES = $(gtk_introspection_files)
+@HAVE_INTROSPECTION_TRUE@@WITH_GTK_TRUE@SpiceClientGtk_3_0_gir_EXPORT_PACKAGES = spice-client-gtk-3.0
+@HAVE_INTROSPECTION_TRUE@@WITH_GTK_TRUE@SpiceClientGtk_3_0_gir_SCANNERFLAGS = --c-include="spice-widget.h"
+@HAVE_INTROSPECTION_TRUE@girdir = $(datadir)/gir-1.0
+@HAVE_INTROSPECTION_TRUE@gir_DATA = $(INTROSPECTION_GIRS)
+@HAVE_INTROSPECTION_TRUE@typelibsdir = $(libdir)/girepository-1.0
+@HAVE_INTROSPECTION_TRUE@typelibs_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+spice-version.h: $(top_builddir)/config.status $(srcdir)/spice-version.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libspice-client-glib-2.0.la: $(libspice_client_glib_2_0_la_OBJECTS) $(libspice_client_glib_2_0_la_DEPENDENCIES) $(EXTRA_libspice_client_glib_2_0_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libspice_client_glib_2_0_la_LINK) -rpath $(libdir) $(libspice_client_glib_2_0_la_OBJECTS) $(libspice_client_glib_2_0_la_LIBADD) $(LIBS)
+
+libspice-client-gtk-3.0.la: $(libspice_client_gtk_3_0_la_OBJECTS) $(libspice_client_gtk_3_0_la_DEPENDENCIES) $(EXTRA_libspice_client_gtk_3_0_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libspice_client_gtk_3_0_la_LINK) $(am_libspice_client_gtk_3_0_la_rpath) $(libspice_client_gtk_3_0_la_OBJECTS) $(libspice_client_gtk_3_0_la_LIBADD) $(LIBS)
+install-aclPROGRAMS: $(acl_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(acl_PROGRAMS)'; test -n "$(acldir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(acldir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(acldir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(acldir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(acldir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-aclPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(acl_PROGRAMS)'; test -n "$(acldir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(acldir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(acldir)" && rm -f $$files
+
+clean-aclPROGRAMS:
+ @list='$(acl_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+spice-client-glib-usb-acl-helper$(EXEEXT): $(spice_client_glib_usb_acl_helper_OBJECTS) $(spice_client_glib_usb_acl_helper_DEPENDENCIES) $(EXTRA_spice_client_glib_usb_acl_helper_DEPENDENCIES)
+ @rm -f spice-client-glib-usb-acl-helper$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(spice_client_glib_usb_acl_helper_OBJECTS) $(spice_client_glib_usb_acl_helper_LDADD) $(LIBS)
+
+spicy$(EXEEXT): $(spicy_OBJECTS) $(spicy_DEPENDENCIES) $(EXTRA_spicy_DEPENDENCIES)
+ @rm -f spicy$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(spicy_OBJECTS) $(spicy_LDADD) $(LIBS)
+
+spicy-screenshot$(EXEEXT): $(spicy_screenshot_OBJECTS) $(spicy_screenshot_DEPENDENCIES) $(EXTRA_spicy_screenshot_DEPENDENCIES)
+ @rm -f spicy-screenshot$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(spicy_screenshot_OBJECTS) $(spicy_screenshot_LDADD) $(LIBS)
+
+spicy-stats$(EXEEXT): $(spicy_stats_OBJECTS) $(spicy_stats_DEPENDENCIES) $(EXTRA_spicy_stats_DEPENDENCIES)
+ @rm -f spicy-stats$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(spicy_stats_OBJECTS) $(spicy_stats_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bio-gio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-base.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-cursor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-display-gst.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-display-mjpeg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-display.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-inputs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-main.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-playback.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-port.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-record.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-smartcard.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-usbredir.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel-webdav.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client_sw_canvas.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/continuation.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coroutine_gthread.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coroutine_ucontext.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coroutine_winfibers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode-glz.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode-jpeg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decode-zlib.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/desktop-integration.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gio-coroutine.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/giopipe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smartcard-manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-audio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-channel.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-client.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-cmdline.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-file-transfer-task.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-glib-enums.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-glib-main.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-grabsequence.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-gstaudio.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-gtk-session.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-marshal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-option.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-pulse.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-session.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-uri.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-widget-cairo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-widget-egl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-widget-enums.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-widget.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spicy-screenshot.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spicy-spice-cmdline.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spicy-spicy-connect.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spicy-spicy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spicy-stats.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usb-acl-helper.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usb-device-manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usb-device-widget.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usbdk_api.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usbutil.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmcstream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vncdisplaykeymap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/win-usb-dev.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/win-usb-driver-install.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wocky-http-proxy.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.o: spice-client-glib-usb-acl-helper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spice_client_glib_usb_acl_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.o -MD -MP -MF $(DEPDIR)/spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.Tpo -c -o spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.o `test -f 'spice-client-glib-usb-acl-helper.c' || echo '$(srcdir)/'`spice-client-glib-usb-acl-helper.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.Tpo $(DEPDIR)/spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spice-client-glib-usb-acl-helper.c' object='spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spice_client_glib_usb_acl_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.o `test -f 'spice-client-glib-usb-acl-helper.c' || echo '$(srcdir)/'`spice-client-glib-usb-acl-helper.c
+
+spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.obj: spice-client-glib-usb-acl-helper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spice_client_glib_usb_acl_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.obj -MD -MP -MF $(DEPDIR)/spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.Tpo -c -o spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.obj `if test -f 'spice-client-glib-usb-acl-helper.c'; then $(CYGPATH_W) 'spice-client-glib-usb-acl-helper.c'; else $(CYGPATH_W) '$(srcdir)/spice-client-glib-usb-acl-helper.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.Tpo $(DEPDIR)/spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spice-client-glib-usb-acl-helper.c' object='spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spice_client_glib_usb_acl_helper_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spice_client_glib_usb_acl_helper-spice-client-glib-usb-acl-helper.obj `if test -f 'spice-client-glib-usb-acl-helper.c'; then $(CYGPATH_W) 'spice-client-glib-usb-acl-helper.c'; else $(CYGPATH_W) '$(srcdir)/spice-client-glib-usb-acl-helper.c'; fi`
+
+spicy-spicy.o: spicy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spicy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spicy-spicy.o -MD -MP -MF $(DEPDIR)/spicy-spicy.Tpo -c -o spicy-spicy.o `test -f 'spicy.c' || echo '$(srcdir)/'`spicy.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/spicy-spicy.Tpo $(DEPDIR)/spicy-spicy.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spicy.c' object='spicy-spicy.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spicy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spicy-spicy.o `test -f 'spicy.c' || echo '$(srcdir)/'`spicy.c
+
+spicy-spicy.obj: spicy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spicy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spicy-spicy.obj -MD -MP -MF $(DEPDIR)/spicy-spicy.Tpo -c -o spicy-spicy.obj `if test -f 'spicy.c'; then $(CYGPATH_W) 'spicy.c'; else $(CYGPATH_W) '$(srcdir)/spicy.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/spicy-spicy.Tpo $(DEPDIR)/spicy-spicy.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spicy.c' object='spicy-spicy.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spicy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spicy-spicy.obj `if test -f 'spicy.c'; then $(CYGPATH_W) 'spicy.c'; else $(CYGPATH_W) '$(srcdir)/spicy.c'; fi`
+
+spicy-spicy-connect.o: spicy-connect.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spicy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spicy-spicy-connect.o -MD -MP -MF $(DEPDIR)/spicy-spicy-connect.Tpo -c -o spicy-spicy-connect.o `test -f 'spicy-connect.c' || echo '$(srcdir)/'`spicy-connect.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/spicy-spicy-connect.Tpo $(DEPDIR)/spicy-spicy-connect.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spicy-connect.c' object='spicy-spicy-connect.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spicy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spicy-spicy-connect.o `test -f 'spicy-connect.c' || echo '$(srcdir)/'`spicy-connect.c
+
+spicy-spicy-connect.obj: spicy-connect.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spicy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spicy-spicy-connect.obj -MD -MP -MF $(DEPDIR)/spicy-spicy-connect.Tpo -c -o spicy-spicy-connect.obj `if test -f 'spicy-connect.c'; then $(CYGPATH_W) 'spicy-connect.c'; else $(CYGPATH_W) '$(srcdir)/spicy-connect.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/spicy-spicy-connect.Tpo $(DEPDIR)/spicy-spicy-connect.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spicy-connect.c' object='spicy-spicy-connect.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spicy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spicy-spicy-connect.obj `if test -f 'spicy-connect.c'; then $(CYGPATH_W) 'spicy-connect.c'; else $(CYGPATH_W) '$(srcdir)/spicy-connect.c'; fi`
+
+spicy-spice-cmdline.o: spice-cmdline.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spicy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spicy-spice-cmdline.o -MD -MP -MF $(DEPDIR)/spicy-spice-cmdline.Tpo -c -o spicy-spice-cmdline.o `test -f 'spice-cmdline.c' || echo '$(srcdir)/'`spice-cmdline.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/spicy-spice-cmdline.Tpo $(DEPDIR)/spicy-spice-cmdline.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spice-cmdline.c' object='spicy-spice-cmdline.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spicy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spicy-spice-cmdline.o `test -f 'spice-cmdline.c' || echo '$(srcdir)/'`spice-cmdline.c
+
+spicy-spice-cmdline.obj: spice-cmdline.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spicy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT spicy-spice-cmdline.obj -MD -MP -MF $(DEPDIR)/spicy-spice-cmdline.Tpo -c -o spicy-spice-cmdline.obj `if test -f 'spice-cmdline.c'; then $(CYGPATH_W) 'spice-cmdline.c'; else $(CYGPATH_W) '$(srcdir)/spice-cmdline.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/spicy-spice-cmdline.Tpo $(DEPDIR)/spicy-spice-cmdline.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='spice-cmdline.c' object='spicy-spice-cmdline.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(spicy_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o spicy-spice-cmdline.obj `if test -f 'spice-cmdline.c'; then $(CYGPATH_W) 'spice-cmdline.c'; else $(CYGPATH_W) '$(srcdir)/spice-cmdline.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-dist_libspice_client_glibincludeDATA: $(dist_libspice_client_glibinclude_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_libspice_client_glibinclude_DATA)'; test -n "$(libspice_client_glibincludedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libspice_client_glibincludedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libspice_client_glibincludedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(libspice_client_glibincludedir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(libspice_client_glibincludedir)" || exit $$?; \
+ done
+
+uninstall-dist_libspice_client_glibincludeDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_libspice_client_glibinclude_DATA)'; test -n "$(libspice_client_glibincludedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(libspice_client_glibincludedir)'; $(am__uninstall_files_from_dir)
+install-girDATA: $(gir_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(gir_DATA)'; test -n "$(girdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(girdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(girdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(girdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(girdir)" || exit $$?; \
+ done
+
+uninstall-girDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(gir_DATA)'; test -n "$(girdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(girdir)'; $(am__uninstall_files_from_dir)
+install-typelibsDATA: $(typelibs_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(typelibs_DATA)'; test -n "$(typelibsdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(typelibsdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(typelibsdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(typelibsdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(typelibsdir)" || exit $$?; \
+ done
+
+uninstall-typelibsDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(typelibs_DATA)'; test -n "$(typelibsdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(typelibsdir)'; $(am__uninstall_files_from_dir)
+install-libspice_client_glibincludeHEADERS: $(libspice_client_glibinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(libspice_client_glibinclude_HEADERS)'; test -n "$(libspice_client_glibincludedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libspice_client_glibincludedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libspice_client_glibincludedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libspice_client_glibincludedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libspice_client_glibincludedir)" || exit $$?; \
+ done
+
+uninstall-libspice_client_glibincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libspice_client_glibinclude_HEADERS)'; test -n "$(libspice_client_glibincludedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(libspice_client_glibincludedir)'; $(am__uninstall_files_from_dir)
+install-libspice_client_gtkincludeHEADERS: $(libspice_client_gtkinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(libspice_client_gtkinclude_HEADERS)'; test -n "$(libspice_client_gtkincludedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libspice_client_gtkincludedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libspice_client_gtkincludedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libspice_client_gtkincludedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libspice_client_gtkincludedir)" || exit $$?; \
+ done
+
+uninstall-libspice_client_gtkincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libspice_client_gtkinclude_HEADERS)'; test -n "$(libspice_client_gtkincludedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(libspice_client_gtkincludedir)'; $(am__uninstall_files_from_dir)
+install-nodist_libspice_client_glibincludeHEADERS: $(nodist_libspice_client_glibinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(nodist_libspice_client_glibinclude_HEADERS)'; test -n "$(libspice_client_glibincludedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libspice_client_glibincludedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libspice_client_glibincludedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libspice_client_glibincludedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libspice_client_glibincludedir)" || exit $$?; \
+ done
+
+uninstall-nodist_libspice_client_glibincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nodist_libspice_client_glibinclude_HEADERS)'; test -n "$(libspice_client_glibincludedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(libspice_client_glibincludedir)'; $(am__uninstall_files_from_dir)
+install-nodist_libspice_client_gtkincludeHEADERS: $(nodist_libspice_client_gtkinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(nodist_libspice_client_gtkinclude_HEADERS)'; test -n "$(libspice_client_gtkincludedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libspice_client_gtkincludedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libspice_client_gtkincludedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libspice_client_gtkincludedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libspice_client_gtkincludedir)" || exit $$?; \
+ done
+
+uninstall-nodist_libspice_client_gtkincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nodist_libspice_client_gtkinclude_HEADERS)'; test -n "$(libspice_client_gtkincludedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(libspice_client_gtkincludedir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS)
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(acldir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libspice_client_glibincludedir)" "$(DESTDIR)$(girdir)" "$(DESTDIR)$(typelibsdir)" "$(DESTDIR)$(libspice_client_glibincludedir)" "$(DESTDIR)$(libspice_client_gtkincludedir)" "$(DESTDIR)$(libspice_client_glibincludedir)" "$(DESTDIR)$(libspice_client_gtkincludedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+@WITH_POLKIT_FALSE@install-data-hook:
+clean: clean-recursive
+
+clean-am: clean-aclPROGRAMS clean-binPROGRAMS clean-generic \
+ clean-libLTLIBRARIES clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-aclPROGRAMS \
+ install-dist_libspice_client_glibincludeDATA install-girDATA \
+ install-libspice_client_glibincludeHEADERS \
+ install-libspice_client_gtkincludeHEADERS \
+ install-nodist_libspice_client_glibincludeHEADERS \
+ install-nodist_libspice_client_gtkincludeHEADERS \
+ install-typelibsDATA
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-aclPROGRAMS uninstall-binPROGRAMS \
+ uninstall-dist_libspice_client_glibincludeDATA \
+ uninstall-girDATA uninstall-libLTLIBRARIES \
+ uninstall-libspice_client_glibincludeHEADERS \
+ uninstall-libspice_client_gtkincludeHEADERS \
+ uninstall-nodist_libspice_client_glibincludeHEADERS \
+ uninstall-nodist_libspice_client_gtkincludeHEADERS \
+ uninstall-typelibsDATA
+
+.MAKE: $(am__recursive_targets) all check install install-am \
+ install-data-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-aclPROGRAMS clean-binPROGRAMS \
+ clean-generic clean-libLTLIBRARIES clean-libtool cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-aclPROGRAMS install-am \
+ install-binPROGRAMS install-data install-data-am \
+ install-data-hook install-dist_libspice_client_glibincludeDATA \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-girDATA install-html install-html-am install-info \
+ install-info-am install-libLTLIBRARIES \
+ install-libspice_client_glibincludeHEADERS \
+ install-libspice_client_gtkincludeHEADERS install-man \
+ install-nodist_libspice_client_glibincludeHEADERS \
+ install-nodist_libspice_client_gtkincludeHEADERS install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ install-typelibsDATA installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-aclPROGRAMS uninstall-am uninstall-binPROGRAMS \
+ uninstall-dist_libspice_client_glibincludeDATA \
+ uninstall-girDATA uninstall-libLTLIBRARIES \
+ uninstall-libspice_client_glibincludeHEADERS \
+ uninstall-libspice_client_gtkincludeHEADERS \
+ uninstall-nodist_libspice_client_glibincludeHEADERS \
+ uninstall-nodist_libspice_client_gtkincludeHEADERS \
+ uninstall-typelibsDATA
+
+.PRECIOUS: Makefile
+
+
+@WITH_POLKIT_TRUE@install-data-hook:
+@WITH_POLKIT_TRUE@ -chown root $(DESTDIR)$(acldir)/spice-client-glib-usb-acl-helper
+@WITH_POLKIT_TRUE@ -chmod u+s $(DESTDIR)$(acldir)/spice-client-glib-usb-acl-helper
+
+$(libspice_client_glib_2_0_la_SOURCES): spice-glib-enums.h spice-marshal.h
+
+@WITH_GTK_TRUE@$(libspice_client_gtk_3_0_la_SOURCES): spice-glib-enums.h spice-widget-enums.h
+
+spice-marshal.c: spice-marshal.h
+spice-glib-enums.c: spice-glib-enums.h
+spice-widget-enums.c: spice-widget-enums.h
+
+spice-marshal.c: spice-marshal.txt
+ $(AM_V_GEN)echo "#include \"config.h\"" > $@ && \
+ echo "#include \"spice-marshal.h\"" > $@ && \
+ glib-genmarshal --body $< >> $@ || (rm -f $@ && exit 1)
+
+spice-marshal.h: spice-marshal.txt
+ $(AM_V_GEN)glib-genmarshal --header $< > $@ || (rm -f $@ && exit 1)
+
+spice-glib-enums.c: spice-channel.h channel-inputs.h spice-session.h
+ $(AM_V_GEN)glib-mkenums --fhead "#include \"config.h\"\n\n" \
+ --fhead "#include <glib-object.h>\n" \
+ --fhead "#include \"spice-glib-enums.h\"\n\n" \
+ --fprod "\n#include \"spice-session.h\"\n" \
+ --fprod "\n#include \"spice-channel.h\"\n" \
+ --fprod "\n#include \"channel-inputs.h\"\n" \
+ --vhead "static const G@Type@Value _@enum_name@_values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n};\n\n" \
+ --vtail "GType\n@enum_name@_get_type (void)\n{\n" \
+ --vtail " static GType type = 0;\n" \
+ --vtail " static volatile gsize type_volatile = 0;\n\n" \
+ --vtail " if (g_once_init_enter(&type_volatile)) {\n" \
+ --vtail " type = g_@type@_register_static (\"@EnumName@\", _@enum_name@_values);\n" \
+ --vtail " g_once_init_leave(&type_volatile, type);\n" \
+ --vtail " }\n\n" \
+ --vtail " return type;\n}\n\n" \
+ $^ > $@
+
+spice-glib-enums.h: spice-channel.h channel-inputs.h spice-session.h
+ $(AM_V_GEN)glib-mkenums --fhead "#ifndef SPICE_GLIB_ENUMS_H\n" \
+ --fhead "#define SPICE_GLIB_ENUMS_H\n\n" \
+ --fhead "G_BEGIN_DECLS\n\n" \
+ --ftail "G_END_DECLS\n\n" \
+ --ftail "#endif /* SPICE_CHANNEL_ENUMS_H */\n" \
+ --eprod "#define SPICE_TYPE_@ENUMSHORT@ @enum_name@_get_type()\n" \
+ --eprod "GType @enum_name@_get_type (void);\n" \
+ $^ > $@
+
+spice-widget-enums.c: spice-widget.h
+ $(AM_V_GEN)glib-mkenums --fhead "#include \"config.h\"\n\n" \
+ --fhead "#include <glib-object.h>\n" \
+ --fhead "#include \"spice-widget-enums.h\"\n\n" \
+ --fprod "\n#include \"spice-widget.h\"\n" \
+ --vhead "static const G@Type@Value _@enum_name@_values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n};\n\n" \
+ --vtail "GType\n@enum_name@_get_type (void)\n{\n" \
+ --vtail " static GType type = 0;\n" \
+ --vtail " static volatile gsize type_volatile = 0;\n\n" \
+ --vtail " if (g_once_init_enter(&type_volatile)) {\n" \
+ --vtail " type = g_@type@_register_static (\"@EnumName@\", _@enum_name@_values);\n" \
+ --vtail " g_once_init_leave(&type_volatile, type);\n" \
+ --vtail " }\n\n" \
+ --vtail " return type;\n}\n\n" \
+ $< > $@
+
+spice-widget-enums.h: spice-widget.h
+ $(AM_V_GEN)glib-mkenums --fhead "#ifndef SPICE_WIDGET_ENUMS_H\n" \
+ --fhead "#define SPICE_WIDGET_ENUMS_H\n\n" \
+ --fhead "G_BEGIN_DECLS\n\n" \
+ --ftail "G_END_DECLS\n\n" \
+ --ftail "#endif /* SPICE_WIDGET_ENUMS_H */\n" \
+ --eprod "#define SPICE_TYPE_@ENUMSHORT@ @enum_name@_get_type()\n" \
+ --eprod "GType @enum_name@_get_type (void);\n" \
+ $< > $@
+
+vncdisplaykeymap.c: $(KEYMAPS)
+
+$(KEYMAPS): $(KEYMAP_GEN) keymaps.csv
+
+# Note despite being autogenerated these are not part of CLEANFILES, they
+# are actually a part of EXTRA_DIST to avoid the need for perl(Text::CSV) by
+# end users
+vncdisplaykeymap_xorgevdev2xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgevdev xtkbd > $@ || rm $@
+
+vncdisplaykeymap_xorgkbd2xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgkbd xtkbd > $@ || rm $@
+
+vncdisplaykeymap_xorgxquartz2xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgxquartz xtkbd > $@ || rm $@
+
+vncdisplaykeymap_xorgxwin2xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv xorgxwin xtkbd > $@ || rm $@
+
+vncdisplaykeymap_osx2xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv osx xtkbd > $@ || rm $@
+
+vncdisplaykeymap_win322xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv win32 xtkbd > $@ || rm $@
+
+vncdisplaykeymap_x112xtkbd.c:
+ $(AM_V_GEN)$(KEYMAP_GEN) $(srcdir)/keymaps.csv x11 xtkbd > $@ || rm $@
+
+-include $(INTROSPECTION_MAKEFILE)
+
+@HAVE_INTROSPECTION_TRUE@SpiceClientGLib-2.0.gir: libspice-client-glib-2.0.la
+
+@HAVE_INTROSPECTION_TRUE@@WITH_GTK_TRUE@SpiceClientGtk-3.0.gir: libspice-client-gtk-3.0.la SpiceClientGLib-2.0.gir
+
+update-map-file: $(libspice_client_gtkinclude_HEADERS) $(nodist_libspice_client_gtkinclude_HEADERS) $(libspice_client_glibinclude_HEADERS) $(nodist_libspice_client_glibinclude_HEADERS)
+ ( echo "SPICEGTK_1 {" ; \
+ echo "global:" ; \
+ ctags -f - -I G_GNUC_CONST --c-kinds=p $^ | awk '/^spice_/ { print $$1 ";" }' | sort ; \
+ echo "local:" ; \
+ echo "*;" ; \
+ echo "};" ) > $(srcdir)/map-file
+
+update-glib-sym-file: $(libspice_client_glibinclude_HEADERS) $(nodist_libspice_client_glibinclude_HEADERS)
+ ( ctags -f - -I G_GNUC_CONST --c-kinds=p $^ | awk '/^spice_/ { print $$1 }' | sort ; \
+ ) > $(srcdir)/spice-glib-sym-file
+
+update-gtk-sym-file: $(libspice_client_gtkinclude_HEADERS) $(nodist_libspice_client_gtkinclude_HEADERS)
+ ( ctags -f - -I G_GNUC_CONST --c-kinds=p $^ | awk '/^spice_/ { print $$1 }' | sort ; \
+ ) > $(srcdir)/spice-gtk-sym-file
+
+update-symbol-files: update-map-file update-glib-sym-file update-gtk-sym-file
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <string.h>
+#include <glib.h>
+
+#include "spice-util.h"
+#include "bio-gio.h"
+
+typedef struct bio_gsocket_method {
+ BIO_METHOD method;
+ GIOStream *stream;
+} bio_gsocket_method;
+
+#define BIO_GET_GSOCKET(bio) (((bio_gsocket_method*)bio->method)->gsocket)
+#define BIO_GET_ISTREAM(bio) (g_io_stream_get_input_stream(((bio_gsocket_method*)bio->method)->stream))
+#define BIO_GET_OSTREAM(bio) (g_io_stream_get_output_stream(((bio_gsocket_method*)bio->method)->stream))
+
+static int bio_gio_write(BIO *bio, const char *in, int inl)
+{
+ gssize ret;
+ GError *error = NULL;
+
+ ret = g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(BIO_GET_OSTREAM(bio)),
+ in, inl, NULL, &error);
+ BIO_clear_retry_flags(bio);
+
+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
+ BIO_set_retry_write(bio);
+ if (error != NULL) {
+ g_warning("%s", error->message);
+ g_clear_error(&error);
+ }
+
+ return ret;
+}
+
+static int bio_gio_read(BIO *bio, char *out, int outl)
+{
+ gssize ret;
+ GError *error = NULL;
+
+ ret = g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(BIO_GET_ISTREAM(bio)),
+ out, outl, NULL, &error);
+ BIO_clear_retry_flags(bio);
+
+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
+ BIO_set_retry_read(bio);
+ else if (error != NULL)
+ g_warning("%s", error->message);
+
+ g_clear_error(&error);
+
+ return ret;
+}
+
+static int bio_gio_destroy(BIO *bio)
+{
+ if (bio == NULL || bio->method == NULL)
+ return 0;
+
+ SPICE_DEBUG("bio gsocket destroy");
+ g_clear_pointer(&bio->method, g_free);
+
+ return 1;
+}
+
+static int bio_gio_puts(BIO *bio, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = bio_gio_write(bio, str, n);
+
+ return ret;
+}
+
+G_GNUC_INTERNAL
+BIO* bio_new_giostream(GIOStream *stream)
+{
+ // TODO: make an actual new BIO type, or just switch to GTls already...
+ BIO *bio = BIO_new_socket(-1, BIO_NOCLOSE);
+
+ bio_gsocket_method *bio_method = g_new(bio_gsocket_method, 1);
+ bio_method->method = *bio->method;
+ bio_method->stream = stream;
+
+ bio->method->destroy(bio);
+ bio->method = (BIO_METHOD*)bio_method;
+
+ bio->method->bwrite = bio_gio_write;
+ bio->method->bread = bio_gio_read;
+ bio->method->bputs = bio_gio_puts;
+ bio->method->destroy = bio_gio_destroy;
+
+ return bio;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef BIO_GIO_H_
+# define BIO_GIO_H_
+
+#include <openssl/bio.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+BIO* bio_new_giostream(GIOStream *stream);
+
+G_END_DECLS
+
+#endif /* !BIO_GIO_H_ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+
+#include "spice-session-priv.h"
+#include "spice-channel-priv.h"
+
+/* coroutine context */
+static void
+spice_channel_handle_set_ack(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ SpiceMsgSetAck* ack = spice_msg_in_parsed(in);
+ SpiceMsgOut *out = spice_msg_out_new(channel, SPICE_MSGC_ACK_SYNC);
+ SpiceMsgcAckSync sync = {
+ .generation = ack->generation,
+ };
+
+ c->message_ack_window = c->message_ack_count = ack->window;
+ c->marshallers->msgc_ack_sync(out->marshaller, &sync);
+ spice_msg_out_send_internal(out);
+}
+
+/* coroutine context */
+static void
+spice_channel_handle_ping(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ SpiceMsgPing *ping = spice_msg_in_parsed(in);
+ SpiceMsgOut *pong = spice_msg_out_new(channel, SPICE_MSGC_PONG);
+
+ c->marshallers->msgc_pong(pong->marshaller, ping);
+ spice_msg_out_send_internal(pong);
+}
+
+/* coroutine context */
+static void
+spice_channel_handle_notify(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ static const char* severity_strings[] = {"info", "warn", "error"};
+ static const char* visibility_strings[] = {"!", "!!", "!!!"};
+
+ SpiceMsgNotify *notify = spice_msg_in_parsed(in);
+ const char *severity = "?";
+ const char *visibility = "?";
+ const char *message_str = NULL;
+
+ if (notify->severity <= SPICE_NOTIFY_SEVERITY_ERROR) {
+ severity = severity_strings[notify->severity];
+ }
+ if (notify->visibilty <= SPICE_NOTIFY_VISIBILITY_HIGH) {
+ visibility = visibility_strings[notify->visibilty];
+ }
+
+ if (notify->message_len &&
+ notify->message_len <= in->dpos - sizeof(*notify)) {
+ message_str = (char*)notify->message;
+ }
+
+ CHANNEL_DEBUG(channel, "%s -- %s%s #%u%s%.*s", __FUNCTION__,
+ severity, visibility, notify->what,
+ message_str ? ": " : "", (int)notify->message_len,
+ message_str ? message_str : "");
+}
+
+/* coroutine context */
+static void
+spice_channel_handle_disconnect(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisconnect *disconnect = spice_msg_in_parsed(in);
+
+ CHANNEL_DEBUG(channel, "%s: ts: %" PRIu64", reason: %u", __FUNCTION__,
+ disconnect->time_stamp, disconnect->reason);
+}
+
+typedef struct WaitForChannelData
+{
+ SpiceWaitForChannel *wait;
+ SpiceChannel *channel;
+} WaitForChannelData;
+
+/* coroutine and main context */
+static gboolean wait_for_channel(gpointer data)
+{
+ WaitForChannelData *wfc = data;
+ SpiceChannelPrivate *c = wfc->channel->priv;
+ SpiceChannel *wait_channel;
+
+ wait_channel = spice_session_lookup_channel(c->session, wfc->wait->channel_id, wfc->wait->channel_type);
+ g_return_val_if_fail(wait_channel != NULL, TRUE);
+
+ if (wait_channel->priv->last_message_serial >= wfc->wait->message_serial)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* coroutine context */
+G_GNUC_INTERNAL
+void spice_channel_handle_wait_for_channels(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ SpiceMsgWaitForChannels *wfc = spice_msg_in_parsed(in);
+ int i;
+
+ for (i = 0; i < wfc->wait_count; ++i) {
+ WaitForChannelData data = {
+ .wait = wfc->wait_list + i,
+ .channel = channel
+ };
+
+ CHANNEL_DEBUG(channel, "waiting for serial %" PRIu64 " (%d/%d)", data.wait->message_serial, i + 1, wfc->wait_count);
+ if (g_coroutine_condition_wait(&c->coroutine, wait_for_channel, &data))
+ CHANNEL_DEBUG(channel, "waiting for serial %" PRIu64 ", done", data.wait->message_serial);
+ else
+ CHANNEL_DEBUG(channel, "waiting for serial %" PRIu64 ", cancelled", data.wait->message_serial);
+ }
+}
+
+static void
+get_msg_handler(SpiceChannel *channel, SpiceMsgIn *in, gpointer data)
+{
+ SpiceMsgIn **msg = data;
+
+ g_return_if_fail(msg != NULL);
+ g_return_if_fail(*msg == NULL);
+
+ spice_msg_in_ref(in);
+ *msg = in;
+}
+
+/* coroutine context */
+static void
+spice_channel_handle_migrate(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgOut *out;
+ SpiceMsgIn *data = NULL;
+ SpiceMsgMigrate *mig = spice_msg_in_parsed(in);
+ SpiceChannelPrivate *c = channel->priv;
+
+ CHANNEL_DEBUG(channel, "%s: flags %u", __FUNCTION__, mig->flags);
+ if (mig->flags & SPICE_MIGRATE_NEED_FLUSH) {
+ /* if peer version > 1: pushing the mark msg before all other messgages and sending it,
+ * and only it */
+ if (c->peer_hdr.major_version == 1) {
+ /* iterate_write is blocking and flushing all pending write */
+ SPICE_CHANNEL_GET_CLASS(channel)->iterate_write(channel);
+ }
+ out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MIGRATE_FLUSH_MARK);
+ spice_msg_out_send_internal(out);
+ }
+ if (mig->flags & SPICE_MIGRATE_NEED_DATA_TRANSFER) {
+ spice_channel_recv_msg(channel, get_msg_handler, &data);
+ if (!data) {
+ g_critical("expected SPICE_MSG_MIGRATE_DATA, got empty message");
+ goto end;
+ } else if (spice_header_get_msg_type(data->header, c->use_mini_header) !=
+ SPICE_MSG_MIGRATE_DATA) {
+ g_critical("expected SPICE_MSG_MIGRATE_DATA, got %d",
+ spice_header_get_msg_type(data->header, c->use_mini_header));
+ goto end;
+ }
+ }
+
+ /* swapping channels sockets */
+ spice_session_channel_migrate(c->session, channel);
+
+ /* pushing the MIGRATE_DATA before all other pending messages */
+ if ((mig->flags & SPICE_MIGRATE_NEED_DATA_TRANSFER) && (data != NULL)) {
+ out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MIGRATE_DATA);
+ spice_marshaller_add(out->marshaller, data->data,
+ spice_header_get_msg_size(data->header, c->use_mini_header));
+ spice_msg_out_send_internal(out);
+ }
+
+end:
+ if (data)
+ spice_msg_in_unref(data);
+}
+
+
+static void set_handlers(SpiceChannelClassPrivate *klass,
+ const spice_msg_handler* handlers, const int n)
+{
+ int i;
+
+ g_array_set_size(klass->handlers, MAX(klass->handlers->len, n));
+ for (i = 0; i < n; i++) {
+ if (handlers[i])
+ g_array_index(klass->handlers, spice_msg_handler, i) = handlers[i];
+ }
+}
+
+static void spice_channel_add_base_handlers(SpiceChannelClassPrivate *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_SET_ACK ] = spice_channel_handle_set_ack,
+ [ SPICE_MSG_PING ] = spice_channel_handle_ping,
+ [ SPICE_MSG_NOTIFY ] = spice_channel_handle_notify,
+ [ SPICE_MSG_DISCONNECTING ] = spice_channel_handle_disconnect,
+ [ SPICE_MSG_WAIT_FOR_CHANNELS ] = spice_channel_handle_wait_for_channels,
+ [ SPICE_MSG_MIGRATE ] = spice_channel_handle_migrate,
+ };
+
+ set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
+}
+
+G_GNUC_INTERNAL
+void spice_channel_set_handlers(SpiceChannelClass *klass,
+ const spice_msg_handler* handlers, const int n)
+{
+ klass->priv =
+ G_TYPE_CLASS_GET_PRIVATE (klass, spice_channel_get_type (), SpiceChannelClassPrivate);
+
+ g_return_if_fail(klass->priv->handlers == NULL);
+ klass->priv->handlers = g_array_sized_new(FALSE, TRUE, sizeof(spice_msg_handler), n);
+
+ spice_channel_add_base_handlers(klass->priv);
+ set_handlers(klass->priv, handlers, n);
+}
+
+static void
+vmc_write_free_cb(uint8_t *data, void *user_data)
+{
+ GTask *task = user_data;
+ gsize count = GPOINTER_TO_SIZE(g_task_get_task_data(task));
+
+ g_task_return_int(task, count);
+
+ g_object_unref(task);
+}
+
+G_GNUC_INTERNAL
+void spice_vmc_write_async(SpiceChannel *self,
+ const void *buffer, gsize count,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SpiceMsgOut *msg;
+ GTask *task;
+
+ task = g_task_new(self, cancellable, callback, user_data);
+ g_task_set_task_data(task, GSIZE_TO_POINTER(count), NULL);
+
+ msg = spice_msg_out_new(SPICE_CHANNEL(self), SPICE_MSGC_SPICEVMC_DATA);
+ spice_marshaller_add_ref_full(msg->marshaller, (uint8_t*)buffer, count,
+ vmc_write_free_cb, task);
+ spice_msg_out_send(msg);
+}
+
+G_GNUC_INTERNAL
+gssize spice_vmc_write_finish(SpiceChannel *self,
+ GAsyncResult *result, GError **error)
+{
+ GTask *task;
+
+ g_return_val_if_fail(result != NULL, -1);
+
+ task = G_TASK(result);
+
+ g_return_val_if_fail(g_task_is_valid(task, self), -1);
+
+ return g_task_propagate_int(task, error);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+
+#include "spice-channel-priv.h"
+#include "spice-channel-cache.h"
+#include "spice-marshal.h"
+
+/**
+ * SECTION:channel-cursor
+ * @short_description: update cursor shape and position
+ * @title: Cursor Channel
+ * @section_id:
+ * @see_also: #SpiceChannel, and the GTK widget #SpiceDisplay
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * The Spice protocol defines a set of messages for controlling cursor
+ * shape and position on the remote display area. The cursor changes
+ * that should be reflected on the display are notified by
+ * signals. See for example #SpiceCursorChannel::cursor-set
+ * #SpiceCursorChannel::cursor-move signals.
+ */
+
+#define SPICE_CURSOR_CHANNEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_CURSOR_CHANNEL, SpiceCursorChannelPrivate))
+
+typedef struct display_cursor display_cursor;
+
+struct display_cursor {
+ SpiceCursorHeader hdr;
+ gboolean default_cursor;
+ int refcount;
+ guint32 data[];
+};
+
+struct _SpiceCursorChannelPrivate {
+ display_cache *cursors;
+ gboolean init_done;
+};
+
+enum {
+ SPICE_CURSOR_SET,
+ SPICE_CURSOR_MOVE,
+ SPICE_CURSOR_HIDE,
+ SPICE_CURSOR_RESET,
+
+ SPICE_CURSOR_LAST_SIGNAL,
+};
+
+static guint signals[SPICE_CURSOR_LAST_SIGNAL];
+
+static display_cursor * display_cursor_ref(display_cursor *cursor);
+static void display_cursor_unref(display_cursor *cursor);
+static void channel_set_handlers(SpiceChannelClass *klass);
+
+G_DEFINE_TYPE(SpiceCursorChannel, spice_cursor_channel, SPICE_TYPE_CHANNEL)
+
+/* ------------------------------------------------------------------ */
+
+static void spice_cursor_channel_init(SpiceCursorChannel *channel)
+{
+ SpiceCursorChannelPrivate *c;
+
+ c = channel->priv = SPICE_CURSOR_CHANNEL_GET_PRIVATE(channel);
+
+ c->cursors = cache_new((GDestroyNotify)display_cursor_unref);
+}
+
+static void spice_cursor_channel_finalize(GObject *obj)
+{
+ SpiceCursorChannel *channel = SPICE_CURSOR_CHANNEL(obj);
+ SpiceCursorChannelPrivate *c = channel->priv;
+
+ g_clear_pointer(&c->cursors, cache_free);
+
+ if (G_OBJECT_CLASS(spice_cursor_channel_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_cursor_channel_parent_class)->finalize(obj);
+}
+
+/* coroutine context */
+static void spice_cursor_channel_reset(SpiceChannel *channel, gboolean migrating)
+{
+ SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
+
+ cache_clear(c->cursors);
+ c->init_done = FALSE;
+
+ SPICE_CHANNEL_CLASS(spice_cursor_channel_parent_class)->channel_reset(channel, migrating);
+}
+
+static void spice_cursor_channel_class_init(SpiceCursorChannelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
+
+ gobject_class->finalize = spice_cursor_channel_finalize;
+ channel_class->channel_reset = spice_cursor_channel_reset;
+
+ /**
+ * SpiceCursorChannel::cursor-set:
+ * @cursor: the #SpiceCursorChannel that emitted the signal
+ * @width: width of the shape
+ * @height: height of the shape
+ * @hot_x: horizontal offset of the 'hotspot' of the cursor
+ * @hot_y: vertical offset of the 'hotspot' of the cursor
+ * @rgba: 32bits shape data, or %NULL if default cursor. It might
+ * be freed after the signal is emitted, so make sure to copy it
+ * if you need it later!
+ *
+ * The #SpiceCursorChannel::cursor-set signal is emitted to modify
+ * cursor aspect and position on the display area.
+ **/
+ signals[SPICE_CURSOR_SET] =
+ g_signal_new("cursor-set",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceCursorChannelClass, cursor_set),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__INT_INT_INT_INT_POINTER,
+ G_TYPE_NONE,
+ 5,
+ G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_POINTER);
+
+ /**
+ * SpiceCursorChannel::cursor-move:
+ * @cursor: the #SpiceCursorChannel that emitted the signal
+ * @x: x position
+ * @y: y position
+ *
+ * The #SpiceCursorChannel::cursor-move signal is emitted to update
+ * the cursor position on the display area.
+ **/
+ signals[SPICE_CURSOR_MOVE] =
+ g_signal_new("cursor-move",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceCursorChannelClass, cursor_move),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__INT_INT,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_INT, G_TYPE_INT);
+
+ /**
+ * SpiceCursorChannel::cursor-hide:
+ * @cursor: the #SpiceCursorChannel that emitted the signal
+ *
+ * The #SpiceCursorChannel::cursor-hide signal is emitted to hide
+ * the cursor/pointer on the display area.
+ **/
+ signals[SPICE_CURSOR_HIDE] =
+ g_signal_new("cursor-hide",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceCursorChannelClass, cursor_hide),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ /**
+ * SpiceCursorChannel::cursor-reset:
+ * @cursor: the #SpiceCursorChannel that emitted the signal
+ *
+ * The #SpiceCursorChannel::cursor-reset signal is emitted to
+ * reset the cursor to its default context.
+ **/
+ signals[SPICE_CURSOR_RESET] =
+ g_signal_new("cursor-reset",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceCursorChannelClass, cursor_reset),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_class_add_private(klass, sizeof(SpiceCursorChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
+}
+
+/* ------------------------------------------------------------------ */
+
+#ifdef DEBUG_CURSOR
+static void print_cursor(display_cursor *cursor, const guint8 *data)
+{
+ int x, y, bpl;
+ const guint8 *xor, *and;
+
+ bpl = (cursor->hdr.width + 7) / 8;
+ and = data;
+ xor = and + bpl * cursor->hdr.height;
+
+ printf("data (%d x %d):\n", cursor->hdr.width, cursor->hdr.height);
+ for (y = 0 ; y < cursor->hdr.height; ++y) {
+ for (x = 0 ; x < cursor->hdr.width / 8; x++) {
+ printf("%02X", and[x]);
+ }
+ and += bpl;
+ printf("\n");
+ }
+ printf("xor:\n");
+ for (y = 0 ; y < cursor->hdr.height; ++y) {
+ for (x = 0 ; x < cursor->hdr.width / 8; ++x) {
+ printf("%02X", xor[x]);
+ }
+ xor += bpl;
+ printf("\n");
+ }
+}
+#endif
+
+static void mono_cursor(display_cursor *cursor, const guint8 *data)
+{
+ int bpl = (cursor->hdr.width + 7) / 8;
+ const guint8 *xor, *and;
+ guint8 *dest;
+ dest = (uint8_t *)cursor->data;
+
+#ifdef DEBUG_CURSOR
+ print_cursor(cursor, data);
+#endif
+ and = data;
+ xor = and + bpl * cursor->hdr.height;
+ spice_mono_edge_highlight(cursor->hdr.width, cursor->hdr.height,
+ and, xor, dest);
+}
+
+static guint8 get_pix_mask(const guint8 *data, gint offset, gint pix_index)
+{
+ return data[offset + (pix_index >> 3)] & (0x80 >> (pix_index % 8));
+}
+
+static guint32 get_pix_hack(gint pix_index, gint width)
+{
+ return (((pix_index % width) ^ (pix_index / width)) & 1) ? 0xc0303030 : 0x30505050;
+}
+
+static display_cursor * display_cursor_ref(display_cursor *cursor)
+{
+ g_return_val_if_fail(cursor != NULL, NULL);
+ g_return_val_if_fail(cursor->refcount > 0, NULL);
+
+ cursor->refcount++;
+ return cursor;
+}
+
+static void display_cursor_unref(display_cursor *cursor)
+{
+ g_return_if_fail(cursor != NULL);
+ g_return_if_fail(cursor->refcount > 0);
+
+ cursor->refcount--;
+ if (cursor->refcount == 0)
+ g_free(cursor);
+}
+
+static const char *cursor_type_to_string(int type)
+{
+ switch (type) {
+ case SPICE_CURSOR_TYPE_MONO:
+ return "mono";
+ case SPICE_CURSOR_TYPE_ALPHA:
+ return "alpha";
+ case SPICE_CURSOR_TYPE_COLOR32:
+ return "color32";
+ case SPICE_CURSOR_TYPE_COLOR16:
+ return "color16";
+ case SPICE_CURSOR_TYPE_COLOR4:
+ return "color4";
+ }
+ return "unknown";
+}
+
+static display_cursor *set_cursor(SpiceChannel *channel, SpiceCursor *scursor)
+{
+ SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
+ SpiceCursorHeader *hdr = &scursor->header;
+ display_cursor *cursor;
+ size_t size;
+ gint i, pix_mask, pix;
+ const guint8* data;
+ guint8 *rgba;
+ guint8 val;
+
+ CHANNEL_DEBUG(channel, "%s: flags %x, size %u", __FUNCTION__,
+ scursor->flags, scursor->data_size);
+
+ if (scursor->flags & SPICE_CURSOR_FLAGS_NONE)
+ return NULL;
+
+ CHANNEL_DEBUG(channel, "%s: type %s(%d), %" PRIx64 ", %dx%d", __FUNCTION__,
+ cursor_type_to_string(hdr->type), hdr->type, hdr->unique,
+ hdr->width, hdr->height);
+
+ if (scursor->flags & SPICE_CURSOR_FLAGS_FROM_CACHE) {
+ cursor = cache_find(c->cursors, hdr->unique);
+ g_return_val_if_fail(cursor != NULL, NULL);
+ return display_cursor_ref(cursor);
+ }
+
+ g_return_val_if_fail(scursor->data_size != 0, NULL);
+
+ size = 4u * hdr->width * hdr->height;
+ cursor = g_malloc0(sizeof(*cursor) + size);
+ cursor->hdr = *hdr;
+ cursor->default_cursor = FALSE;
+ cursor->refcount = 1;
+ data = scursor->data;
+
+ switch (hdr->type) {
+ case SPICE_CURSOR_TYPE_MONO:
+ mono_cursor(cursor, data);
+ break;
+ case SPICE_CURSOR_TYPE_ALPHA:
+ memcpy(cursor->data, data, size);
+ break;
+ case SPICE_CURSOR_TYPE_COLOR32:
+ memcpy(cursor->data, data, size);
+ for (i = 0; i < hdr->width * hdr->height; i++) {
+ pix_mask = get_pix_mask(data, size, i);
+ if (pix_mask && *((guint32*)data + i) == 0xffffff) {
+ cursor->data[i] = get_pix_hack(i, hdr->width);
+ } else {
+ cursor->data[i] |= (pix_mask ? 0 : 0xff000000);
+ }
+ }
+ break;
+ case SPICE_CURSOR_TYPE_COLOR16:
+ for (i = 0; i < hdr->width * hdr->height; i++) {
+ pix_mask = get_pix_mask(data, size, i);
+ pix = *((guint16*)data + i);
+ if (pix_mask && pix == 0x7fff) {
+ cursor->data[i] = get_pix_hack(i, hdr->width);
+ } else {
+ cursor->data[i] |= ((pix & 0x1f) << 3) | ((pix & 0x3e0) << 6) |
+ ((pix & 0x7c00) << 9) | (pix_mask ? 0 : 0xff000000);
+ }
+ }
+ break;
+ case SPICE_CURSOR_TYPE_COLOR4:
+ size = ((unsigned int)(SPICE_ALIGN(hdr->width, 2) / 2)) * hdr->height;
+ for (i = 0; i < hdr->width * hdr->height; i++) {
+ pix_mask = get_pix_mask(data, size + (sizeof(uint32_t) << 4), i);
+ int idx = (i & 1) ? (data[i >> 1] & 0x0f) : ((data[i >> 1] & 0xf0) >> 4);
+ pix = *((uint32_t*)(data + size) + idx);
+ if (pix_mask && pix == 0xffffff) {
+ cursor->data[i] = get_pix_hack(i, hdr->width);
+ } else {
+ cursor->data[i] = pix | (pix_mask ? 0 : 0xff000000);
+ }
+ }
+
+ break;
+ default:
+ g_warning("%s: unimplemented cursor type %d", __FUNCTION__,
+ hdr->type);
+ cursor->default_cursor = TRUE;
+ goto cache_add;
+ }
+
+ rgba = (guint8*)cursor->data;
+ for (i = 0; i < hdr->width * hdr->height; i++) {
+ val = rgba[0];
+ rgba[0] = rgba[2];
+ rgba[2] = val;
+ rgba += 4;
+ }
+
+cache_add:
+ if (scursor->flags & SPICE_CURSOR_FLAGS_CACHE_ME) {
+ cache_add(c->cursors, hdr->unique, display_cursor_ref(cursor));
+ }
+
+ return cursor;
+}
+
+/* coroutine context */
+static void emit_cursor_set(SpiceChannel *channel, display_cursor *cursor)
+{
+ g_return_if_fail(cursor != NULL);
+ g_coroutine_signal_emit(channel, signals[SPICE_CURSOR_SET], 0,
+ cursor->hdr.width, cursor->hdr.height,
+ cursor->hdr.hot_spot_x, cursor->hdr.hot_spot_y,
+ cursor->default_cursor ? NULL : cursor->data);
+}
+
+/* coroutine context */
+static void cursor_handle_init(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgCursorInit *init = spice_msg_in_parsed(in);
+ SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
+ display_cursor *cursor;
+
+ g_return_if_fail(c->init_done == FALSE);
+
+ cache_clear(c->cursors);
+ cursor = set_cursor(channel, &init->cursor);
+ c->init_done = TRUE;
+ if (cursor)
+ emit_cursor_set(channel, cursor);
+ if (!init->visible || !cursor)
+ g_coroutine_signal_emit(channel, signals[SPICE_CURSOR_HIDE], 0);
+ if (cursor)
+ display_cursor_unref(cursor);
+}
+
+/* coroutine context */
+static void cursor_handle_reset(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
+
+ CHANNEL_DEBUG(channel, "%s, init_done: %d", __FUNCTION__, c->init_done);
+
+ cache_clear(c->cursors);
+ g_coroutine_signal_emit(channel, signals[SPICE_CURSOR_RESET], 0);
+ c->init_done = FALSE;
+}
+
+/* coroutine context */
+static void cursor_handle_set(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgCursorSet *set = spice_msg_in_parsed(in);
+ SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
+ display_cursor *cursor;
+
+ g_return_if_fail(c->init_done == TRUE);
+
+ cursor = set_cursor(channel, &set->cursor);
+ if (cursor)
+ emit_cursor_set(channel, cursor);
+ else
+ g_coroutine_signal_emit(channel, signals[SPICE_CURSOR_HIDE], 0);
+
+
+ if (cursor)
+ display_cursor_unref(cursor);
+}
+
+/* coroutine context */
+static void cursor_handle_move(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgCursorMove *move = spice_msg_in_parsed(in);
+ SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
+
+ g_return_if_fail(c->init_done == TRUE);
+
+ g_coroutine_signal_emit(channel, signals[SPICE_CURSOR_MOVE], 0,
+ move->position.x, move->position.y);
+}
+
+/* coroutine context */
+static void cursor_handle_hide(SpiceChannel *channel, SpiceMsgIn *in)
+{
+#ifdef EXTRA_CHECKS
+ SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
+
+ g_return_if_fail(c->init_done == TRUE);
+#endif
+
+ g_coroutine_signal_emit(channel, signals[SPICE_CURSOR_HIDE], 0);
+}
+
+/* coroutine context */
+static void cursor_handle_trail(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
+
+ g_return_if_fail(c->init_done == TRUE);
+
+ g_warning("%s: TODO", __FUNCTION__);
+}
+
+/* coroutine context */
+static void cursor_handle_inval_one(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
+ SpiceMsgDisplayInvalOne *zap = spice_msg_in_parsed(in);
+
+ g_return_if_fail(c->init_done == TRUE);
+
+ cache_remove(c->cursors, zap->id);
+}
+
+/* coroutine context */
+static void cursor_handle_inval_all(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceCursorChannelPrivate *c = SPICE_CURSOR_CHANNEL(channel)->priv;
+
+ cache_clear(c->cursors);
+}
+
+static void channel_set_handlers(SpiceChannelClass *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_CURSOR_INIT ] = cursor_handle_init,
+ [ SPICE_MSG_CURSOR_RESET ] = cursor_handle_reset,
+ [ SPICE_MSG_CURSOR_SET ] = cursor_handle_set,
+ [ SPICE_MSG_CURSOR_MOVE ] = cursor_handle_move,
+ [ SPICE_MSG_CURSOR_HIDE ] = cursor_handle_hide,
+ [ SPICE_MSG_CURSOR_TRAIL ] = cursor_handle_trail,
+ [ SPICE_MSG_CURSOR_INVAL_ONE ] = cursor_handle_inval_one,
+ [ SPICE_MSG_CURSOR_INVAL_ALL ] = cursor_handle_inval_all,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_CURSOR_CHANNEL_H__
+#define __SPICE_CLIENT_CURSOR_CHANNEL_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_CURSOR_CHANNEL (spice_cursor_channel_get_type())
+#define SPICE_CURSOR_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_CURSOR_CHANNEL, SpiceCursorChannel))
+#define SPICE_CURSOR_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_CURSOR_CHANNEL, SpiceCursorChannelClass))
+#define SPICE_IS_CURSOR_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_CURSOR_CHANNEL))
+#define SPICE_IS_CURSOR_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_CURSOR_CHANNEL))
+#define SPICE_CURSOR_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_CURSOR_CHANNEL, SpiceCursorChannelClass))
+
+typedef struct _SpiceCursorChannel SpiceCursorChannel;
+typedef struct _SpiceCursorChannelClass SpiceCursorChannelClass;
+typedef struct _SpiceCursorChannelPrivate SpiceCursorChannelPrivate;
+
+/**
+ * SpiceCursorChannel:
+ *
+ * The #SpiceCursorChannel struct is opaque and should not be accessed directly.
+ */
+struct _SpiceCursorChannel {
+ SpiceChannel parent;
+
+ /*< private >*/
+ SpiceCursorChannelPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpiceCursorChannelClass:
+ * @parent_class: Parent class.
+ * @cursor_set: Signal class handler for the #SpiceCursorChannel::cursor-set signal.
+ * @cursor_move: Signal class handler for the #SpiceCursorChannel::cursor-move signal.
+ * @cursor_hide: Signal class handler for the #SpiceCursorChannel::cursor-hide signal.
+ * @cursor_reset: Signal class handler for the #SpiceCursorChannel::cursor-reset signal.
+ *
+ * Class structure for #SpiceCursorChannel.
+ */
+struct _SpiceCursorChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*cursor_set)(SpiceCursorChannel *channel, gint width, gint height,
+ gint hot_x, gint hot_y, gpointer rgba);
+ void (*cursor_move)(SpiceCursorChannel *channel, gint x, gint y);
+ void (*cursor_hide)(SpiceCursorChannel *channel);
+ void (*cursor_reset)(SpiceCursorChannel *channel);
+
+ /*< private >*/
+ /* Do not add fields to this struct */
+};
+
+GType spice_cursor_channel_get_type(void);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_CURSOR_CHANNEL_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2015-2016 CodeWeavers, Inc
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+#include "spice-channel-priv.h"
+
+#include "channel-display-priv.h"
+
+#include <gst/gst.h>
+#include <gst/app/gstappsrc.h>
+#include <gst/app/gstappsink.h>
+
+
+/* GStreamer decoder implementation */
+
+typedef struct SpiceGstDecoder {
+ VideoDecoder base;
+
+ /* ---------- GStreamer pipeline ---------- */
+
+ GstAppSrc *appsrc;
+ GstAppSink *appsink;
+ GstElement *pipeline;
+ GstClock *clock;
+
+ /* ---------- Decoding and display queues ---------- */
+
+ uint32_t last_mm_time;
+
+ GMutex queues_mutex;
+ GQueue *decoding_queue;
+ GQueue *display_queue;
+ guint timer_id;
+} SpiceGstDecoder;
+
+
+/* ---------- SpiceFrame ---------- */
+
+typedef struct _SpiceFrame {
+ GstClockTime timestamp;
+ SpiceMsgIn *msg;
+ GstSample *sample;
+} SpiceFrame;
+
+static SpiceFrame *create_frame(GstBuffer *buffer, SpiceMsgIn *msg)
+{
+ SpiceFrame *frame = spice_new(SpiceFrame, 1);
+ frame->timestamp = GST_BUFFER_PTS(buffer);
+ frame->msg = msg;
+ spice_msg_in_ref(msg);
+ frame->sample = NULL;
+ return frame;
+}
+
+static void free_frame(SpiceFrame *frame)
+{
+ spice_msg_in_unref(frame->msg);
+ if (frame->sample) {
+ gst_sample_unref(frame->sample);
+ }
+ free(frame);
+}
+
+
+/* ---------- GStreamer pipeline ---------- */
+
+static void schedule_frame(SpiceGstDecoder *decoder);
+
+/* main context */
+static gboolean display_frame(gpointer video_decoder)
+{
+ SpiceGstDecoder *decoder = (SpiceGstDecoder*)video_decoder;
+ SpiceFrame *frame;
+ GstCaps *caps;
+ gint width, height;
+ GstStructure *s;
+ GstBuffer *buffer;
+ GstMapInfo mapinfo;
+
+ decoder->timer_id = 0;
+
+ g_mutex_lock(&decoder->queues_mutex);
+ frame = g_queue_pop_head(decoder->display_queue);
+ g_mutex_unlock(&decoder->queues_mutex);
+ /* If the queue is empty we don't even need to reschedule */
+ g_return_val_if_fail(frame, G_SOURCE_REMOVE);
+
+ if (!frame->sample) {
+ spice_warning("got a frame without a sample!");
+ goto error;
+ }
+
+ caps = gst_sample_get_caps(frame->sample);
+ if (!caps) {
+ spice_warning("GStreamer error: could not get the caps of the sample");
+ goto error;
+ }
+
+ s = gst_caps_get_structure(caps, 0);
+ if (!gst_structure_get_int(s, "width", &width) ||
+ !gst_structure_get_int(s, "height", &height)) {
+ spice_warning("GStreamer error: could not get the size of the frame");
+ goto error;
+ }
+
+ buffer = gst_sample_get_buffer(frame->sample);
+ if (!gst_buffer_map(buffer, &mapinfo, GST_MAP_READ)) {
+ spice_warning("GStreamer error: could not map the buffer");
+ goto error;
+ }
+
+ stream_display_frame(decoder->base.stream, frame->msg,
+ width, height, mapinfo.data);
+ gst_buffer_unmap(buffer, &mapinfo);
+
+ error:
+ free_frame(frame);
+ schedule_frame(decoder);
+ return G_SOURCE_REMOVE;
+}
+
+/* main loop or GStreamer streaming thread */
+static void schedule_frame(SpiceGstDecoder *decoder)
+{
+ guint32 now = stream_get_time(decoder->base.stream);
+ g_mutex_lock(&decoder->queues_mutex);
+
+ while (!decoder->timer_id) {
+ SpiceFrame *frame = g_queue_peek_head(decoder->display_queue);
+ if (!frame) {
+ break;
+ }
+
+ SpiceStreamDataHeader *op = spice_msg_in_parsed(frame->msg);
+ if (now < op->multi_media_time) {
+ decoder->timer_id = g_timeout_add(op->multi_media_time - now,
+ display_frame, decoder);
+ } else if (g_queue_get_length(decoder->display_queue) == 1) {
+ /* Still attempt to display the least out of date frame so the
+ * video is not completely frozen for an extended period of time.
+ */
+ decoder->timer_id = g_timeout_add(0, display_frame, decoder);
+ } else {
+ SPICE_DEBUG("%s: rendering too late by %u ms (ts: %u, mmtime: %u), dropping",
+ __FUNCTION__, now - op->multi_media_time,
+ op->multi_media_time, now);
+ stream_dropped_frame_on_playback(decoder->base.stream);
+ g_queue_pop_head(decoder->display_queue);
+ free_frame(frame);
+ }
+ }
+
+ g_mutex_unlock(&decoder->queues_mutex);
+}
+
+/* GStreamer thread
+ *
+ * We cannot use GStreamer's signals because they are not always run in
+ * the main context. So use a callback (lower overhead) and have it pull
+ * the sample to avoid a race with free_pipeline(). This means queuing the
+ * decoded frames outside GStreamer. So while we're at it, also schedule
+ * the frame display ourselves in schedule_frame().
+ */
+static GstFlowReturn new_sample(GstAppSink *gstappsink, gpointer video_decoder)
+{
+ SpiceGstDecoder *decoder = video_decoder;
+
+ GstSample *sample = gst_app_sink_pull_sample(decoder->appsink);
+ GstBuffer *buffer = sample ? gst_sample_get_buffer(sample) : NULL;
+ if (sample) {
+ g_mutex_lock(&decoder->queues_mutex);
+
+ /* gst_app_sink_pull_sample() sometimes returns the same buffer twice
+ * or buffers that have a modified, and thus unrecognizable, PTS.
+ * Blindly removing frames from the decoding_queue until we find a
+ * match would only empty the queue, resulting in later buffers not
+ * finding a match either, etc. So check the buffer has a matching
+ * frame first.
+ */
+ SpiceFrame *frame;
+ GList *l = g_queue_peek_head_link(decoder->decoding_queue);
+ while (l) {
+ frame = l->data;
+ if (frame->timestamp == GST_BUFFER_PTS(buffer)) {
+ /* The frame is now ready for display */
+ frame->sample = sample;
+ g_queue_push_tail(decoder->display_queue, frame);
+
+ /* Now that we know there is a match, remove it and the older
+ * frames from the decoding queue.
+ */
+ while ((frame = g_queue_pop_head(decoder->decoding_queue))) {
+ if (frame->timestamp == GST_BUFFER_PTS(buffer)) {
+ break;
+ }
+ /* The GStreamer pipeline dropped the corresponding
+ * buffer.
+ */
+ SPICE_DEBUG("the GStreamer pipeline dropped a frame");
+ free_frame(frame);
+ }
+ break;
+ }
+ l = l->next;
+ }
+ if (!l) {
+ spice_warning("got an unexpected decoded buffer!");
+ gst_sample_unref(sample);
+ }
+
+ g_mutex_unlock(&decoder->queues_mutex);
+ schedule_frame(decoder);
+ } else {
+ spice_warning("GStreamer error: could not pull sample");
+ }
+ return GST_FLOW_OK;
+}
+
+static void free_pipeline(SpiceGstDecoder *decoder)
+{
+ if (!decoder->pipeline) {
+ return;
+ }
+
+ gst_element_set_state(decoder->pipeline, GST_STATE_NULL);
+ gst_object_unref(decoder->appsrc);
+ gst_object_unref(decoder->appsink);
+ gst_object_unref(decoder->pipeline);
+ gst_object_unref(decoder->clock);
+ decoder->pipeline = NULL;
+}
+
+static gboolean create_pipeline(SpiceGstDecoder *decoder)
+{
+ const gchar *src_caps, *gstdec_name;
+ switch (decoder->base.codec_type) {
+ case SPICE_VIDEO_CODEC_TYPE_MJPEG:
+ src_caps = "caps=image/jpeg";
+ gstdec_name = "jpegdec";
+ break;
+ case SPICE_VIDEO_CODEC_TYPE_VP8:
+ /* typefind is unable to identify VP8 streams by design.
+ * See: https://bugzilla.gnome.org/show_bug.cgi?id=756457
+ */
+ src_caps = "caps=video/x-vp8";
+ gstdec_name = "vp8dec";
+ break;
+ case SPICE_VIDEO_CODEC_TYPE_H264:
+ /* h264 streams detection works fine and setting an incomplete cap
+ * causes errors. So let typefind do all the work.
+ */
+ src_caps = "";
+ gstdec_name = "h264parse ! avdec_h264";
+ break;
+ default:
+ SPICE_DEBUG("Unknown codec type %d. Trying decodebin.",
+ decoder->base.codec_type);
+ src_caps = "";
+ gstdec_name = NULL;
+ break;
+ }
+
+ /* decodebin will use vaapi if installed, which for a time could
+ * intentionally crash the application. So only use decodebin as a
+ * fallback or when SPICE_GSTVIDEO_AUTO is set.
+ * See: https://bugs.freedesktop.org/show_bug.cgi?id=90884
+ */
+ if (gstdec_name == NULL || g_getenv("SPICE_GSTVIDEO_AUTO") != NULL) {
+ gstdec_name = "decodebin";
+ }
+
+ /* - We schedule the frame display ourselves so set sync=false on appsink
+ * so the pipeline decodes them as fast as possible. This will also
+ * minimize the risk of frames getting lost when we rebuild the
+ * pipeline.
+ * - Set max-bytes=0 on appsrc so it does not drop frames that may be
+ * needed by those that follow.
+ */
+ gchar *desc = g_strdup_printf("appsrc name=src is-live=true format=time max-bytes=0 block=true %s ! %s ! videoconvert ! appsink name=sink caps=video/x-raw,format=BGRx sync=false drop=false", src_caps, gstdec_name);
+ SPICE_DEBUG("GStreamer pipeline: %s", desc);
+
+ GError *err = NULL;
+ decoder->pipeline = gst_parse_launch_full(desc, NULL, GST_PARSE_FLAG_FATAL_ERRORS, &err);
+ g_free(desc);
+ if (!decoder->pipeline) {
+ spice_warning("GStreamer error: %s", err->message);
+ g_clear_error(&err);
+ return FALSE;
+ }
+
+ decoder->appsrc = GST_APP_SRC(gst_bin_get_by_name(GST_BIN(decoder->pipeline), "src"));
+ decoder->appsink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(decoder->pipeline), "sink"));
+ GstAppSinkCallbacks appsink_cbs = {NULL, NULL, &new_sample, {NULL}};
+ gst_app_sink_set_callbacks(decoder->appsink, &appsink_cbs, decoder, NULL);
+
+ decoder->clock = gst_pipeline_get_clock(GST_PIPELINE(decoder->pipeline));
+
+ if (gst_element_set_state(decoder->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
+ SPICE_DEBUG("GStreamer error: Unable to set the pipeline to the playing state.");
+ free_pipeline(decoder);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/* ---------- VideoDecoder's public API ---------- */
+
+static void spice_gst_decoder_reschedule(VideoDecoder *video_decoder)
+{
+ SpiceGstDecoder *decoder = (SpiceGstDecoder*)video_decoder;
+ if (decoder->timer_id != 0) {
+ g_source_remove(decoder->timer_id);
+ decoder->timer_id = 0;
+ }
+ schedule_frame(decoder);
+}
+
+/* main context */
+static void spice_gst_decoder_destroy(VideoDecoder *video_decoder)
+{
+ SpiceGstDecoder *decoder = (SpiceGstDecoder*)video_decoder;
+
+ /* Stop and free the pipeline to ensure there will not be any further
+ * new_sample() call (clearing thread-safety concerns).
+ */
+ free_pipeline(decoder);
+
+ /* Even if we kept the decoder around, once we return the stream will be
+ * destroyed making it impossible to display frames. So cancel any
+ * scheduled display_frame() call and drop the queued frames.
+ */
+ if (decoder->timer_id) {
+ g_source_remove(decoder->timer_id);
+ }
+ g_mutex_clear(&decoder->queues_mutex);
+ SpiceFrame *frame;
+ while ((frame = g_queue_pop_head(decoder->decoding_queue))) {
+ free_frame(frame);
+ }
+ g_queue_free(decoder->decoding_queue);
+ while ((frame = g_queue_pop_head(decoder->display_queue))) {
+ free_frame(frame);
+ }
+ g_queue_free(decoder->display_queue);
+
+ free(decoder);
+
+ /* Don't call gst_deinit() as other parts of the client
+ * may still be using GStreamer.
+ */
+}
+
+static void release_buffer_data(gpointer data)
+{
+ SpiceMsgIn* frame_msg = (SpiceMsgIn*)data;
+ spice_msg_in_unref(frame_msg);
+}
+
+static void spice_gst_decoder_queue_frame(VideoDecoder *video_decoder,
+ SpiceMsgIn *frame_msg,
+ int32_t latency)
+{
+ SpiceGstDecoder *decoder = (SpiceGstDecoder*)video_decoder;
+
+ uint8_t *data;
+ uint32_t size = spice_msg_in_frame_data(frame_msg, &data);
+ if (size == 0) {
+ SPICE_DEBUG("got an empty frame buffer!");
+ return;
+ }
+
+ SpiceStreamDataHeader *frame_op = spice_msg_in_parsed(frame_msg);
+ if (frame_op->multi_media_time < decoder->last_mm_time) {
+ SPICE_DEBUG("new-frame-time < last-frame-time (%u < %u):"
+ " resetting stream, id %u",
+ frame_op->multi_media_time,
+ decoder->last_mm_time, frame_op->id);
+ /* Let GStreamer deal with the frame anyway */
+ }
+ decoder->last_mm_time = frame_op->multi_media_time;
+
+ if (latency < 0 &&
+ decoder->base.codec_type == SPICE_VIDEO_CODEC_TYPE_MJPEG) {
+ /* Dropping MJPEG frames has no impact on those that follow and
+ * saves CPU so do it.
+ */
+ SPICE_DEBUG("dropping a late MJPEG frame");
+ return;
+ }
+
+ /* ref() the frame_msg for the buffer */
+ spice_msg_in_ref(frame_msg);
+ GstBuffer *buffer = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS,
+ data, size, 0, size,
+ frame_msg, &release_buffer_data);
+
+ GST_BUFFER_DURATION(buffer) = GST_CLOCK_TIME_NONE;
+ GST_BUFFER_DTS(buffer) = GST_CLOCK_TIME_NONE;
+ GST_BUFFER_PTS(buffer) = gst_clock_get_time(decoder->clock) - gst_element_get_base_time(decoder->pipeline) + ((uint64_t)MAX(0, latency)) * 1000 * 1000;
+
+ g_mutex_lock(&decoder->queues_mutex);
+ g_queue_push_tail(decoder->decoding_queue, create_frame(buffer, frame_msg));
+ g_mutex_unlock(&decoder->queues_mutex);
+
+ if (gst_app_src_push_buffer(decoder->appsrc, buffer) != GST_FLOW_OK) {
+ SPICE_DEBUG("GStreamer error: unable to push frame of size %u", size);
+ stream_dropped_frame_on_playback(decoder->base.stream);
+ }
+}
+
+static gboolean gstvideo_init(void)
+{
+ static int success = 0;
+ if (!success) {
+ GError *err = NULL;
+ if (gst_init_check(NULL, NULL, &err)) {
+ success = 1;
+ } else {
+ spice_warning("Disabling GStreamer video support: %s", err->message);
+ g_clear_error(&err);
+ success = -1;
+ }
+ }
+ return success > 0;
+}
+
+G_GNUC_INTERNAL
+VideoDecoder* create_gstreamer_decoder(int codec_type, display_stream *stream)
+{
+ SpiceGstDecoder *decoder = NULL;
+
+ if (gstvideo_init()) {
+ decoder = spice_new0(SpiceGstDecoder, 1);
+ decoder->base.destroy = spice_gst_decoder_destroy;
+ decoder->base.reschedule = spice_gst_decoder_reschedule;
+ decoder->base.queue_frame = spice_gst_decoder_queue_frame;
+ decoder->base.codec_type = codec_type;
+ decoder->base.stream = stream;
+ g_mutex_init(&decoder->queues_mutex);
+ decoder->decoding_queue = g_queue_new();
+ decoder->display_queue = g_queue_new();
+
+ if (!create_pipeline(decoder)) {
+ decoder->base.destroy((VideoDecoder*)decoder);
+ decoder = NULL;
+ }
+ }
+
+ return (VideoDecoder*)decoder;
+}
+
+G_GNUC_INTERNAL
+gboolean gstvideo_has_codec(int codec_type)
+{
+ gboolean has_codec = FALSE;
+
+ VideoDecoder *decoder = create_gstreamer_decoder(codec_type, NULL);
+ if (decoder) {
+ has_codec = TRUE;
+ decoder->destroy(decoder);
+ }
+
+ return has_codec;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+#include "spice-channel-priv.h"
+
+#include "channel-display-priv.h"
+
+
+/* MJpeg decoder implementation */
+
+typedef struct MJpegDecoder {
+ VideoDecoder base;
+
+ /* ---------- The builtin mjpeg decoder ---------- */
+
+ struct jpeg_source_mgr mjpeg_src;
+ struct jpeg_decompress_struct mjpeg_cinfo;
+ struct jpeg_error_mgr mjpeg_jerr;
+
+ /* ---------- Frame queue ---------- */
+
+ GQueue *msgq;
+ SpiceMsgIn *cur_frame_msg;
+ guint timer_id;
+
+ /* ---------- Output frame data ---------- */
+
+ uint8_t *out_frame;
+ uint32_t out_size;
+} MJpegDecoder;
+
+
+/* ---------- The JPEG library callbacks ---------- */
+
+static void mjpeg_src_init(struct jpeg_decompress_struct *cinfo)
+{
+ MJpegDecoder *decoder = SPICE_CONTAINEROF(cinfo->src, MJpegDecoder, mjpeg_src);
+
+ uint8_t *data;
+ cinfo->src->bytes_in_buffer = spice_msg_in_frame_data(decoder->cur_frame_msg, &data);
+ cinfo->src->next_input_byte = data;
+}
+
+static boolean mjpeg_src_fill(struct jpeg_decompress_struct *cinfo)
+{
+ g_critical("need more input data");
+ return 0;
+}
+
+static void mjpeg_src_skip(struct jpeg_decompress_struct *cinfo,
+ long num_bytes)
+{
+ cinfo->src->next_input_byte += num_bytes;
+}
+
+static void mjpeg_src_term(struct jpeg_decompress_struct *cinfo)
+{
+ /* nothing */
+}
+
+
+/* ---------- Decoder proper ---------- */
+
+static void mjpeg_decoder_schedule(MJpegDecoder *decoder);
+
+/* main context */
+static gboolean mjpeg_decoder_decode_frame(gpointer video_decoder)
+{
+ MJpegDecoder *decoder = (MJpegDecoder*)video_decoder;
+ gboolean back_compat = decoder->base.stream->channel->priv->peer_hdr.major_version == 1;
+ JDIMENSION width, height;
+ uint8_t *dest;
+ uint8_t *lines[4];
+
+ jpeg_read_header(&decoder->mjpeg_cinfo, 1);
+ width = decoder->mjpeg_cinfo.image_width;
+ height = decoder->mjpeg_cinfo.image_height;
+ if (decoder->out_size < width * height * 4) {
+ g_free(decoder->out_frame);
+ decoder->out_size = width * height * 4;
+ decoder->out_frame = g_malloc(decoder->out_size);
+ }
+ dest = decoder->out_frame;
+
+#ifdef JCS_EXTENSIONS
+ // requires jpeg-turbo
+ if (back_compat)
+ decoder->mjpeg_cinfo.out_color_space = JCS_EXT_RGBX;
+ else
+ decoder->mjpeg_cinfo.out_color_space = JCS_EXT_BGRX;
+#else
+#warning "You should consider building with libjpeg-turbo"
+ decoder->mjpeg_cinfo.out_color_space = JCS_RGB;
+#endif
+
+#ifndef SPICE_QUALITY
+ decoder->mjpeg_cinfo.dct_method = JDCT_IFAST;
+ decoder->mjpeg_cinfo.do_fancy_upsampling = FALSE;
+ decoder->mjpeg_cinfo.do_block_smoothing = FALSE;
+ decoder->mjpeg_cinfo.dither_mode = JDITHER_ORDERED;
+#endif
+ // TODO: in theory should check cinfo.output_height match with our height
+ jpeg_start_decompress(&decoder->mjpeg_cinfo);
+ /* rec_outbuf_height is the recommended size of the output buffer we
+ * pass to libjpeg for optimum performance
+ */
+ if (decoder->mjpeg_cinfo.rec_outbuf_height > G_N_ELEMENTS(lines)) {
+ jpeg_abort_decompress(&decoder->mjpeg_cinfo);
+ g_return_val_if_reached(G_SOURCE_REMOVE);
+ }
+
+ while (decoder->mjpeg_cinfo.output_scanline < decoder->mjpeg_cinfo.output_height) {
+ /* only used when JCS_EXTENSIONS is undefined */
+ G_GNUC_UNUSED unsigned int lines_read;
+
+ for (unsigned int j = 0; j < decoder->mjpeg_cinfo.rec_outbuf_height; j++) {
+ lines[j] = dest;
+#ifdef JCS_EXTENSIONS
+ dest += 4 * width;
+#else
+ dest += 3 * width;
+#endif
+ }
+ lines_read = jpeg_read_scanlines(&decoder->mjpeg_cinfo, lines,
+ decoder->mjpeg_cinfo.rec_outbuf_height);
+#ifndef JCS_EXTENSIONS
+ {
+ uint8_t *s = lines[0];
+ uint32_t *d = (uint32_t *)s;
+
+ if (back_compat) {
+ for (unsigned int j = lines_read * width; j > 0; ) {
+ j -= 1; // reverse order, bad for cache?
+ d[j] = s[j * 3 + 0] |
+ s[j * 3 + 1] << 8 |
+ s[j * 3 + 2] << 16;
+ }
+ } else {
+ for (unsigned int j = lines_read * width; j > 0; ) {
+ j -= 1; // reverse order, bad for cache?
+ d[j] = s[j * 3 + 0] << 16 |
+ s[j * 3 + 1] << 8 |
+ s[j * 3 + 2];
+ }
+ }
+ }
+#endif
+ dest = &(decoder->out_frame[decoder->mjpeg_cinfo.output_scanline * width * 4]);
+ }
+ jpeg_finish_decompress(&decoder->mjpeg_cinfo);
+
+ /* Display the frame and dispose of it */
+ stream_display_frame(decoder->base.stream, decoder->cur_frame_msg,
+ width, height, decoder->out_frame);
+ spice_msg_in_unref(decoder->cur_frame_msg);
+ decoder->cur_frame_msg = NULL;
+ decoder->timer_id = 0;
+
+ /* Schedule the next frame */
+ mjpeg_decoder_schedule(decoder);
+
+ return G_SOURCE_REMOVE;
+}
+
+/* ---------- VideoDecoder's queue scheduling ---------- */
+
+static void mjpeg_decoder_schedule(MJpegDecoder *decoder)
+{
+ SPICE_DEBUG("%s", __FUNCTION__);
+ if (decoder->timer_id) {
+ return;
+ }
+
+ guint32 time = stream_get_time(decoder->base.stream);
+ SpiceMsgIn *frame_msg = decoder->cur_frame_msg;
+ decoder->cur_frame_msg = NULL;
+ do {
+ if (frame_msg) {
+ SpiceStreamDataHeader *op = spice_msg_in_parsed(frame_msg);
+ if (time <= op->multi_media_time) {
+ guint32 d = op->multi_media_time - time;
+ decoder->cur_frame_msg = frame_msg;
+ decoder->timer_id = g_timeout_add(d, mjpeg_decoder_decode_frame, decoder);
+ break;
+ }
+
+ SPICE_DEBUG("%s: rendering too late by %u ms (ts: %u, mmtime: %u), dropping ",
+ __FUNCTION__, time - op->multi_media_time,
+ op->multi_media_time, time);
+ stream_dropped_frame_on_playback(decoder->base.stream);
+ spice_msg_in_unref(frame_msg);
+ }
+ frame_msg = g_queue_pop_head(decoder->msgq);
+ } while (frame_msg);
+}
+
+
+/* mjpeg_decoder_drop_queue() helper */
+static void _msg_in_unref_func(gpointer data, gpointer user_data)
+{
+ spice_msg_in_unref(data);
+}
+
+static void mjpeg_decoder_drop_queue(MJpegDecoder *decoder)
+{
+ if (decoder->timer_id != 0) {
+ g_source_remove(decoder->timer_id);
+ decoder->timer_id = 0;
+ }
+ if (decoder->cur_frame_msg) {
+ spice_msg_in_unref(decoder->cur_frame_msg);
+ decoder->cur_frame_msg = NULL;
+ }
+ g_queue_foreach(decoder->msgq, _msg_in_unref_func, NULL);
+ g_queue_clear(decoder->msgq);
+}
+
+/* ---------- VideoDecoder's public API ---------- */
+
+static void mjpeg_decoder_queue_frame(VideoDecoder *video_decoder,
+ SpiceMsgIn *frame_msg, int32_t latency)
+{
+ MJpegDecoder *decoder = (MJpegDecoder*)video_decoder;
+ SpiceMsgIn *last_msg;
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+
+ last_msg = g_queue_peek_tail(decoder->msgq);
+ if (last_msg) {
+ SpiceStreamDataHeader *last_op, *frame_op;
+ last_op = spice_msg_in_parsed(last_msg);
+ frame_op = spice_msg_in_parsed(frame_msg);
+ if (frame_op->multi_media_time < last_op->multi_media_time) {
+ /* This should really not happen */
+ SPICE_DEBUG("new-frame-time < last-frame-time (%u < %u):"
+ " resetting stream, id %u",
+ frame_op->multi_media_time,
+ last_op->multi_media_time, frame_op->id);
+ mjpeg_decoder_drop_queue(decoder);
+ }
+ }
+
+ /* Dropped MJPEG frames don't impact the ones that come after.
+ * So drop late frames as early as possible to save on processing time.
+ */
+ if (latency < 0) {
+ return;
+ }
+
+ spice_msg_in_ref(frame_msg);
+ g_queue_push_tail(decoder->msgq, frame_msg);
+ mjpeg_decoder_schedule(decoder);
+}
+
+static void mjpeg_decoder_reschedule(VideoDecoder *video_decoder)
+{
+ MJpegDecoder *decoder = (MJpegDecoder*)video_decoder;
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+ if (decoder->timer_id != 0) {
+ g_source_remove(decoder->timer_id);
+ decoder->timer_id = 0;
+ }
+ mjpeg_decoder_schedule(decoder);
+}
+
+static void mjpeg_decoder_destroy(VideoDecoder* video_decoder)
+{
+ MJpegDecoder *decoder = (MJpegDecoder*)video_decoder;
+
+ mjpeg_decoder_drop_queue(decoder);
+ jpeg_destroy_decompress(&decoder->mjpeg_cinfo);
+ g_free(decoder->out_frame);
+ free(decoder);
+}
+
+G_GNUC_INTERNAL
+VideoDecoder* create_mjpeg_decoder(int codec_type, display_stream *stream)
+{
+ g_return_val_if_fail(codec_type == SPICE_VIDEO_CODEC_TYPE_MJPEG, NULL);
+
+ MJpegDecoder *decoder = spice_new0(MJpegDecoder, 1);
+
+ decoder->base.destroy = mjpeg_decoder_destroy;
+ decoder->base.reschedule = mjpeg_decoder_reschedule;
+ decoder->base.queue_frame = mjpeg_decoder_queue_frame;
+ decoder->base.codec_type = codec_type;
+ decoder->base.stream = stream;
+
+ decoder->msgq = g_queue_new();
+
+ decoder->mjpeg_cinfo.err = jpeg_std_error(&decoder->mjpeg_jerr);
+ jpeg_create_decompress(&decoder->mjpeg_cinfo);
+
+ decoder->mjpeg_src.init_source = mjpeg_src_init;
+ decoder->mjpeg_src.fill_input_buffer = mjpeg_src_fill;
+ decoder->mjpeg_src.skip_input_data = mjpeg_src_skip;
+ decoder->mjpeg_src.resync_to_restart = jpeg_resync_to_restart;
+ decoder->mjpeg_src.term_source = mjpeg_src_term;
+ decoder->mjpeg_cinfo.src = &decoder->mjpeg_src;
+
+ /* All the other fields are initialized to zero by spice_new0(). */
+
+ return (VideoDecoder*)decoder;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef CHANNEL_DISPLAY_PRIV_H_
+# define CHANNEL_DISPLAY_PRIV_H_
+
+#include <pixman.h>
+#ifdef WIN32
+/* We need some hacks to avoid warnings from the jpeg headers */
+#define HAVE_BOOLEAN
+#define XMD_H
+#endif
+#include <jpeglib.h>
+
+#include "common/canvas_utils.h"
+#include "client_sw_canvas.h"
+#include "common/ring.h"
+#include "common/quic.h"
+#include "common/rop3.h"
+
+G_BEGIN_DECLS
+
+typedef struct display_stream display_stream;
+
+typedef struct VideoDecoder VideoDecoder;
+struct VideoDecoder {
+ /* Releases the video decoder's resources */
+ void (*destroy)(VideoDecoder *decoder);
+
+ /* Notifies the decoder that the mm-time clock changed. */
+ void (*reschedule)(VideoDecoder *decoder);
+
+ /* Decompresses the specified frame.
+ *
+ * @decoder: The video decoder.
+ * @frame_msg: The Spice message containing the compressed frame.
+ * @latency: How long in milliseconds until the frame should be
+ * displayed. Negative values mean the frame is late.
+ */
+ void (*queue_frame)(VideoDecoder *decoder, SpiceMsgIn *frame_msg, int32_t latency);
+
+ /* The format of the encoded video. */
+ int codec_type;
+
+ /* The associated display stream. */
+ display_stream *stream;
+};
+
+
+/* Instantiates the video decoder for the specified codec.
+ *
+ * @codec_type: The format of the video.
+ * @stream: The associated video stream.
+ * @return: A pointer to a structure implementing the VideoDecoder methods.
+ */
+#ifdef HAVE_BUILTIN_MJPEG
+VideoDecoder* create_mjpeg_decoder(int codec_type, display_stream *stream);
+#endif
+#ifdef HAVE_GSTVIDEO
+VideoDecoder* create_gstreamer_decoder(int codec_type, display_stream *stream);
+gboolean gstvideo_has_codec(int codec_type);
+#else
+# define gstvideo_has_codec(codec_type) FALSE
+#endif
+
+
+typedef struct display_surface {
+ guint32 surface_id;
+ bool primary;
+ enum SpiceSurfaceFmt format;
+ int width, height, stride, size;
+ uint8_t *data;
+ SpiceCanvas *canvas;
+ SpiceGlzDecoder *glz_decoder;
+ SpiceZlibDecoder *zlib_decoder;
+ SpiceJpegDecoder *jpeg_decoder;
+} display_surface;
+
+typedef struct drops_sequence_stats {
+ uint32_t len;
+ uint32_t start_mm_time;
+ uint32_t duration;
+} drops_sequence_stats;
+
+struct display_stream {
+ SpiceMsgIn *msg_create;
+ SpiceMsgIn *msg_clip;
+
+ /* from messages */
+ display_surface *surface;
+ const SpiceClip *clip;
+ QRegion region;
+ int have_region;
+
+ VideoDecoder *video_decoder;
+
+ SpiceChannel *channel;
+
+ /* stats */
+ uint32_t first_frame_mm_time;
+ uint32_t arrive_late_count;
+ uint64_t arrive_late_time;
+ uint32_t num_drops_on_playback;
+ uint32_t num_input_frames;
+ drops_sequence_stats cur_drops_seq_stats;
+ GArray *drops_seqs_stats_arr;
+ uint32_t num_drops_seqs;
+
+ uint32_t playback_sync_drops_seq_len;
+
+ /* playback quality report to server */
+ gboolean report_is_active;
+ uint32_t report_id;
+ uint32_t report_max_window;
+ uint32_t report_timeout;
+ uint64_t report_start_time;
+ uint32_t report_start_frame_time;
+ uint32_t report_num_frames;
+ uint32_t report_num_drops;
+ uint32_t report_drops_seq_len;
+};
+
+guint32 stream_get_time(display_stream *st);
+void stream_dropped_frame_on_playback(display_stream *st);
+void stream_display_frame(display_stream *st, SpiceMsgIn *frame_msg, uint32_t width, uint32_t height, uint8_t *data);
+uint32_t spice_msg_in_frame_data(SpiceMsgIn *frame_msg, uint8_t **data);
+
+
+G_END_DECLS
+
+#endif // CHANNEL_DISPLAY_PRIV_H_
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "spice-client.h"
+#include "spice-common.h"
+
+#include "spice-marshal.h"
+#include "spice-channel-priv.h"
+#include "spice-session-priv.h"
+#include "channel-display-priv.h"
+#include "decode.h"
+
+/**
+ * SECTION:channel-display
+ * @short_description: remote display area
+ * @title: Display Channel
+ * @section_id:
+ * @see_also: #SpiceChannel, and the GTK widget #SpiceDisplay
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * A class that handles the rendering of the remote display and inform
+ * of its updates.
+ *
+ * The creation of the main graphic buffer is signaled with
+ * #SpiceDisplayChannel::display-primary-create.
+ *
+ * The update of regions is notified by
+ * #SpiceDisplayChannel::display-invalidate signals.
+ */
+
+#define SPICE_DISPLAY_CHANNEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_DISPLAY_CHANNEL, SpiceDisplayChannelPrivate))
+
+#define MONITORS_MAX 256
+
+struct _SpiceDisplayChannelPrivate {
+ GHashTable *surfaces;
+ display_surface *primary;
+ display_cache *images;
+ display_cache *palettes;
+ SpiceImageCache image_cache;
+ SpicePaletteCache palette_cache;
+ SpiceImageSurfaces image_surfaces;
+ SpiceGlzDecoderWindow *glz_window;
+ display_stream **streams;
+ int nstreams;
+ gboolean mark;
+ guint mark_false_event_id;
+ GArray *monitors;
+ guint monitors_max;
+ gboolean enable_adaptive_streaming;
+#ifdef G_OS_WIN32
+ HDC dc;
+#endif
+ SpiceGlScanout scanout;
+};
+
+G_DEFINE_TYPE(SpiceDisplayChannel, spice_display_channel, SPICE_TYPE_CHANNEL)
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_WIDTH,
+ PROP_HEIGHT,
+ PROP_MONITORS,
+ PROP_MONITORS_MAX,
+ PROP_GL_SCANOUT,
+};
+
+enum {
+ SPICE_DISPLAY_PRIMARY_CREATE,
+ SPICE_DISPLAY_PRIMARY_DESTROY,
+ SPICE_DISPLAY_INVALIDATE,
+ SPICE_DISPLAY_MARK,
+ SPICE_DISPLAY_GL_DRAW,
+
+ SPICE_DISPLAY_LAST_SIGNAL,
+};
+
+static guint signals[SPICE_DISPLAY_LAST_SIGNAL];
+
+static void spice_display_channel_up(SpiceChannel *channel);
+static void channel_set_handlers(SpiceChannelClass *klass);
+
+static void clear_surfaces(SpiceChannel *channel, gboolean keep_primary);
+static void clear_streams(SpiceChannel *channel);
+static display_surface *find_surface(SpiceDisplayChannelPrivate *c, guint32 surface_id);
+static void spice_display_channel_reset(SpiceChannel *channel, gboolean migrating);
+static void spice_display_channel_reset_capabilities(SpiceChannel *channel);
+static void destroy_canvas(display_surface *surface);
+static void destroy_stream(SpiceChannel *channel, int id);
+static void display_session_mm_time_reset_cb(SpiceSession *session, gpointer data);
+static SpiceGlScanout* spice_gl_scanout_copy(const SpiceGlScanout *scanout);
+
+G_DEFINE_BOXED_TYPE(SpiceGlScanout, spice_gl_scanout,
+ (GBoxedCopyFunc)spice_gl_scanout_copy,
+ (GBoxedFreeFunc)spice_gl_scanout_free)
+
+/* ------------------------------------------------------------------ */
+
+static SpiceGlScanout*
+spice_gl_scanout_copy(const SpiceGlScanout *scanout)
+{
+ SpiceGlScanout *so = g_new(SpiceGlScanout, 1);
+
+ *so = *scanout;
+ so->fd = dup(so->fd);
+
+ return so;
+}
+
+void
+spice_gl_scanout_free(SpiceGlScanout *scanout)
+{
+ close(scanout->fd);
+
+ g_free(scanout);
+}
+
+static void spice_display_channel_dispose(GObject *object)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(object)->priv;
+
+ if (c->mark_false_event_id != 0) {
+ g_source_remove(c->mark_false_event_id);
+ c->mark_false_event_id = 0;
+ }
+
+ if (c->scanout.fd >= 0) {
+ close(c->scanout.fd);
+ c->scanout.fd = -1;
+ }
+
+ if (G_OBJECT_CLASS(spice_display_channel_parent_class)->dispose)
+ G_OBJECT_CLASS(spice_display_channel_parent_class)->dispose(object);
+}
+
+static void spice_display_channel_finalize(GObject *object)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(object)->priv;
+
+ g_clear_pointer(&c->monitors, g_array_unref);
+ clear_surfaces(SPICE_CHANNEL(object), FALSE);
+ g_hash_table_unref(c->surfaces);
+ clear_streams(SPICE_CHANNEL(object));
+ g_clear_pointer(&c->palettes, cache_free);
+
+ if (G_OBJECT_CLASS(spice_display_channel_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_display_channel_parent_class)->finalize(object);
+}
+
+static void spice_display_channel_constructed(GObject *object)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(object)->priv;
+ SpiceSession *s = spice_channel_get_session(SPICE_CHANNEL(object));
+
+ g_return_if_fail(s != NULL);
+ spice_session_get_caches(s, &c->images, &c->glz_window);
+ c->palettes = cache_new(g_free);
+
+ g_return_if_fail(c->glz_window != NULL);
+ g_return_if_fail(c->images != NULL);
+ g_return_if_fail(c->palettes != NULL);
+
+ c->monitors = g_array_new(FALSE, TRUE, sizeof(SpiceDisplayMonitorConfig));
+ spice_g_signal_connect_object(s, "mm-time-reset",
+ G_CALLBACK(display_session_mm_time_reset_cb),
+ SPICE_CHANNEL(object), 0);
+
+
+ if (G_OBJECT_CLASS(spice_display_channel_parent_class)->constructed)
+ G_OBJECT_CLASS(spice_display_channel_parent_class)->constructed(object);
+}
+
+static void spice_display_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceDisplayChannel *channel = SPICE_DISPLAY_CHANNEL(object);
+ SpiceDisplayChannelPrivate *c = channel->priv;
+
+ switch (prop_id) {
+ case PROP_WIDTH: {
+ g_value_set_uint(value, c->primary ? c->primary->width : 0);
+ break;
+ }
+ case PROP_HEIGHT: {
+ g_value_set_uint(value, c->primary ? c->primary->height : 0);
+ break;
+ }
+ case PROP_MONITORS: {
+ g_value_set_boxed(value, c->monitors);
+ break;
+ }
+ case PROP_MONITORS_MAX: {
+ g_value_set_uint(value, c->monitors_max);
+ break;
+ }
+ case PROP_GL_SCANOUT: {
+ g_value_set_static_boxed(value, spice_display_get_gl_scanout(channel));
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_display_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+/* main or coroutine context */
+static void spice_display_channel_reset(SpiceChannel *channel, gboolean migrating)
+{
+ /* palettes, images, and glz_window are cleared in the session */
+ clear_streams(channel);
+ clear_surfaces(channel, TRUE);
+
+ SPICE_CHANNEL_CLASS(spice_display_channel_parent_class)->channel_reset(channel, migrating);
+}
+
+static void spice_display_channel_class_init(SpiceDisplayChannelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
+
+ gobject_class->finalize = spice_display_channel_finalize;
+ gobject_class->dispose = spice_display_channel_dispose;
+ gobject_class->get_property = spice_display_get_property;
+ gobject_class->set_property = spice_display_set_property;
+ gobject_class->constructed = spice_display_channel_constructed;
+
+ channel_class->channel_up = spice_display_channel_up;
+ channel_class->channel_reset = spice_display_channel_reset;
+ channel_class->channel_reset_capabilities = spice_display_channel_reset_capabilities;
+
+ g_object_class_install_property
+ (gobject_class, PROP_HEIGHT,
+ g_param_spec_uint("height",
+ "Display height",
+ "The primary surface height",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_WIDTH,
+ g_param_spec_uint("width",
+ "Display width",
+ "The primary surface width",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceDisplayChannel:monitors:
+ *
+ * Current monitors configuration.
+ *
+ * Since: 0.13
+ */
+ g_object_class_install_property
+ (gobject_class, PROP_MONITORS,
+ g_param_spec_boxed("monitors",
+ "Display monitors",
+ "The monitors configuration",
+ G_TYPE_ARRAY,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceDisplayChannel:monitors-max:
+ *
+ * The maximum number of monitors the server or guest supports.
+ * May change during client lifetime, for instance guest may
+ * reboot or dynamically adjust this.
+ *
+ * Since: 0.13
+ */
+ g_object_class_install_property
+ (gobject_class, PROP_MONITORS_MAX,
+ g_param_spec_uint("monitors-max",
+ "Max display monitors",
+ "The current maximum number of monitors",
+ 1, MONITORS_MAX, 1,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceDisplayChannel:gl-scanout:
+ * @display: the #SpiceDisplayChannel that emitted the signal
+ *
+ * The last #SpiceGlScanout received.
+ *
+ * Since: 0.31
+ */
+ g_object_class_install_property
+ (gobject_class, PROP_GL_SCANOUT,
+ g_param_spec_boxed("gl-scanout",
+ "GL scanout",
+ "GL scanout",
+ SPICE_TYPE_GL_SCANOUT,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceDisplayChannel::display-primary-create:
+ * @display: the #SpiceDisplayChannel that emitted the signal
+ * @format: %SPICE_SURFACE_FMT_32_xRGB or %SPICE_SURFACE_FMT_16_555;
+ * @width: width resolution
+ * @height: height resolution
+ * @stride: the buffer stride ("width" padding)
+ * @shmid: identifier of the shared memory segment associated with
+ * the @imgdata, or -1 if not shm
+ * @imgdata: pointer to surface buffer
+ *
+ * The #SpiceDisplayChannel::display-primary-create signal
+ * provides main display buffer data.
+ **/
+ signals[SPICE_DISPLAY_PRIMARY_CREATE] =
+ g_signal_new("display-primary-create",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceDisplayChannelClass,
+ display_primary_create),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__INT_INT_INT_INT_INT_POINTER,
+ G_TYPE_NONE,
+ 6,
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_POINTER);
+
+ /**
+ * SpiceDisplayChannel::display-primary-destroy:
+ * @display: the #SpiceDisplayChannel that emitted the signal
+ *
+ * The #SpiceDisplayChannel::display-primary-destroy signal is
+ * emitted when the primary surface is freed and should not be
+ * accessed anymore.
+ **/
+ signals[SPICE_DISPLAY_PRIMARY_DESTROY] =
+ g_signal_new("display-primary-destroy",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceDisplayChannelClass,
+ display_primary_destroy),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ /**
+ * SpiceDisplayChannel::display-invalidate:
+ * @display: the #SpiceDisplayChannel that emitted the signal
+ * @x: x position
+ * @y: y position
+ * @width: width
+ * @height: height
+ *
+ * The #SpiceDisplayChannel::display-invalidate signal is emitted
+ * when the rectangular region x/y/w/h of the primary buffer is
+ * updated.
+ **/
+ signals[SPICE_DISPLAY_INVALIDATE] =
+ g_signal_new("display-invalidate",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceDisplayChannelClass,
+ display_invalidate),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__INT_INT_INT_INT,
+ G_TYPE_NONE,
+ 4,
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+
+ /**
+ * SpiceDisplayChannel::display-mark:
+ * @display: the #SpiceDisplayChannel that emitted the signal
+ * @mark: %TRUE when the display mark has been received
+ *
+ * The #SpiceDisplayChannel::display-mark signal is emitted when
+ * the %RED_DISPLAY_MARK command is received, and the display
+ * should be exposed.
+ **/
+ signals[SPICE_DISPLAY_MARK] =
+ g_signal_new("display-mark",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceDisplayChannelClass,
+ display_mark),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+
+ /**
+ * SpiceDisplayChannel::gl-draw:
+ * @display: the #SpiceDisplayChannel that emitted the signal
+ * @x: x position
+ * @y: y position
+ * @width: width
+ * @height: height
+ *
+ * The #SpiceDisplayChannel::draw signal is emitted when the
+ * rectangular region x/y/w/h of the GL scanout is updated and
+ * must be drawn. When the draw is finished, you must call
+ * spice_display_gl_draw_done() in order to release the GL
+ * resources.
+ *
+ * Since: 0.31
+ **/
+ signals[SPICE_DISPLAY_GL_DRAW] =
+ g_signal_new("gl-draw",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ 0, 0, NULL, NULL,
+ g_cclosure_user_marshal_VOID__UINT_UINT_UINT_UINT,
+ G_TYPE_NONE,
+ 4,
+ G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
+
+ g_type_class_add_private(klass, sizeof(SpiceDisplayChannelPrivate));
+
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
+}
+
+/**
+ * spice_display_get_primary:
+ * @channel: a #SpiceDisplayChannel
+ * @surface_id: a surface id
+ * @primary: a #SpiceDisplayPrimary
+ *
+ * Retrieve primary display surface @surface_id.
+ *
+ * Returns: %TRUE if the primary surface was found and its details
+ * collected in @primary.
+ */
+gboolean spice_display_get_primary(SpiceChannel *channel, guint32 surface_id,
+ SpiceDisplayPrimary *primary)
+{
+ g_return_val_if_fail(SPICE_IS_DISPLAY_CHANNEL(channel), FALSE);
+ g_return_val_if_fail(primary != NULL, FALSE);
+
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ display_surface *surface = find_surface(c, surface_id);
+
+ if (surface == NULL)
+ return FALSE;
+
+ g_return_val_if_fail(surface->primary, FALSE);
+
+ primary->format = surface->format;
+ primary->width = surface->width;
+ primary->height = surface->height;
+ primary->stride = surface->stride;
+ primary->shmid = -1;
+ primary->data = surface->data;
+ primary->marked = c->mark;
+ CHANNEL_DEBUG(channel, "get primary %p", primary->data);
+
+ return TRUE;
+}
+
+/**
+ * spice_display_change_preferred_compression:
+ * @channel: a #SpiceDisplayChannel
+ * @compression: a #SpiceImageCompression
+ *
+ * Tells the spice server to change the preferred image compression
+ * for the @channel.
+ *
+ * Since: 0.31
+ */
+void spice_display_change_preferred_compression(SpiceChannel *channel, gint compression)
+{
+ SpiceMsgOut *out;
+ SpiceMsgcDisplayPreferredCompression pref_comp_msg;
+
+ g_return_if_fail(SPICE_IS_DISPLAY_CHANNEL(channel));
+ g_return_if_fail(compression > SPICE_IMAGE_COMPRESSION_INVALID &&
+ compression < SPICE_IMAGE_COMPRESSION_ENUM_END);
+
+ if (!spice_channel_test_capability(channel, SPICE_DISPLAY_CAP_PREF_COMPRESSION)) {
+ CHANNEL_DEBUG(channel, "does not have capability to change the preferred compression");
+ return;
+ }
+
+ CHANNEL_DEBUG(channel, "changing preferred compression to %d", compression);
+
+ pref_comp_msg.image_compression = compression;
+ out = spice_msg_out_new(channel, SPICE_MSGC_DISPLAY_PREFERRED_COMPRESSION);
+ out->marshallers->msgc_display_preferred_compression(out->marshaller, &pref_comp_msg);
+ spice_msg_out_send_internal(out);
+}
+
+/**
+ * spice_display_get_gl_scanout:
+ * @channel: a #SpiceDisplayChannel
+ *
+ * Retrieves the GL scanout if available
+ *
+ * Returns: the current GL scanout, or %NULL if none or not valid
+ *
+ * Since: 0.31
+ **/
+const SpiceGlScanout *
+spice_display_get_gl_scanout(SpiceDisplayChannel *channel)
+{
+ g_return_val_if_fail(SPICE_IS_DISPLAY_CHANNEL(channel), NULL);
+
+ return channel->priv->scanout.fd != -1 ? &channel->priv->scanout : NULL;
+}
+
+/* ------------------------------------------------------------------ */
+
+static void image_put(SpiceImageCache *cache, uint64_t id, pixman_image_t *image)
+{
+ SpiceDisplayChannelPrivate *c =
+ SPICE_CONTAINEROF(cache, SpiceDisplayChannelPrivate, image_cache);
+
+ cache_add(c->images, id, pixman_image_ref(image));
+}
+
+typedef struct _WaitImageData
+{
+ gboolean lossy;
+ SpiceImageCache *cache;
+ uint64_t id;
+ pixman_image_t *image;
+} WaitImageData;
+
+static gboolean wait_image(gpointer data)
+{
+ gboolean lossy;
+ WaitImageData *wait = data;
+ SpiceDisplayChannelPrivate *c =
+ SPICE_CONTAINEROF(wait->cache, SpiceDisplayChannelPrivate, image_cache);
+ pixman_image_t *image = cache_find_lossy(c->images, wait->id, &lossy);
+
+ if (!image || (lossy && !wait->lossy))
+ return FALSE;
+
+ wait->image = pixman_image_ref(image);
+
+ return TRUE;
+}
+
+static pixman_image_t *image_get(SpiceImageCache *cache, uint64_t id)
+{
+ WaitImageData wait = {
+ .lossy = TRUE,
+ .cache = cache,
+ .id = id,
+ .image = NULL
+ };
+ if (!g_coroutine_condition_wait(g_coroutine_self(), wait_image, &wait))
+ SPICE_DEBUG("wait image got cancelled");
+
+ return wait.image;
+}
+
+static void palette_put(SpicePaletteCache *cache, SpicePalette *palette)
+{
+ SpiceDisplayChannelPrivate *c =
+ SPICE_CONTAINEROF(cache, SpiceDisplayChannelPrivate, palette_cache);
+
+ cache_add(c->palettes, palette->unique,
+ g_memdup(palette, sizeof(SpicePalette) +
+ palette->num_ents * sizeof(palette->ents[0])));
+}
+
+static SpicePalette *palette_get(SpicePaletteCache *cache, uint64_t id)
+{
+ SpiceDisplayChannelPrivate *c =
+ SPICE_CONTAINEROF(cache, SpiceDisplayChannelPrivate, palette_cache);
+
+ /* here the returned pointer is weak, no ref given to caller. it
+ * seems spice canvas usage is exclusively temporary, so it's ok.
+ * palette_release is a noop. */
+ return cache_find(c->palettes, id);
+}
+
+static void palette_remove(SpicePaletteCache *cache, uint64_t id)
+{
+ SpiceDisplayChannelPrivate *c =
+ SPICE_CONTAINEROF(cache, SpiceDisplayChannelPrivate, palette_cache);
+
+ cache_remove(c->palettes, id);
+}
+
+static void palette_release(SpicePaletteCache *cache, SpicePalette *palette)
+{
+ /* there is no refcount of palette, see palette_get() */
+}
+
+static void image_put_lossy(SpiceImageCache *cache, uint64_t id,
+ pixman_image_t *surface)
+{
+ SpiceDisplayChannelPrivate *c =
+ SPICE_CONTAINEROF(cache, SpiceDisplayChannelPrivate, image_cache);
+
+#ifndef NDEBUG
+ g_warn_if_fail(cache_find(c->images, id) == NULL);
+#endif
+
+ cache_add_lossy(c->images, id, pixman_image_ref(surface), TRUE);
+}
+
+static void image_replace_lossy(SpiceImageCache *cache, uint64_t id,
+ pixman_image_t *surface)
+{
+ image_put(cache, id, surface);
+}
+
+static pixman_image_t* image_get_lossless(SpiceImageCache *cache, uint64_t id)
+{
+ WaitImageData wait = {
+ .lossy = FALSE,
+ .cache = cache,
+ .id = id,
+ .image = NULL
+ };
+ if (!g_coroutine_condition_wait(g_coroutine_self(), wait_image, &wait))
+ SPICE_DEBUG("wait lossless got cancelled");
+
+ return wait.image;
+}
+
+static SpiceCanvas *surfaces_get(SpiceImageSurfaces *surfaces,
+ uint32_t surface_id)
+{
+ SpiceDisplayChannelPrivate *c =
+ SPICE_CONTAINEROF(surfaces, SpiceDisplayChannelPrivate, image_surfaces);
+
+ display_surface *s =
+ find_surface(c, surface_id);
+
+ return s ? s->canvas : NULL;
+}
+
+static SpiceImageCacheOps image_cache_ops = {
+ .put = image_put,
+ .get = image_get,
+
+ .put_lossy = image_put_lossy,
+ .replace_lossy = image_replace_lossy,
+ .get_lossless = image_get_lossless,
+};
+
+static SpicePaletteCacheOps palette_cache_ops = {
+ .put = palette_put,
+ .get = palette_get,
+ .release = palette_release,
+};
+
+static SpiceImageSurfacesOps image_surfaces_ops = {
+ .get = surfaces_get
+};
+
+#if defined(G_OS_WIN32)
+static HDC create_compatible_dc(void)
+{
+ HDC dc = CreateCompatibleDC(NULL);
+ if (!dc) {
+ g_warning("create compatible DC failed");
+ }
+ return dc;
+}
+#endif
+
+static void spice_display_channel_reset_capabilities(SpiceChannel *channel)
+{
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_DISPLAY_CAP_SIZED_STREAM);
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_DISPLAY_CAP_MONITORS_CONFIG);
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_DISPLAY_CAP_COMPOSITE);
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_DISPLAY_CAP_A8_SURFACE);
+#ifdef USE_LZ4
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_DISPLAY_CAP_LZ4_COMPRESSION);
+#endif
+ if (SPICE_DISPLAY_CHANNEL(channel)->priv->enable_adaptive_streaming) {
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_DISPLAY_CAP_STREAM_REPORT);
+ }
+#ifdef G_OS_UNIX
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_DISPLAY_CAP_GL_SCANOUT);
+#endif
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_DISPLAY_CAP_MULTI_CODEC);
+#ifdef HAVE_BUILTIN_MJPEG
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_DISPLAY_CAP_CODEC_MJPEG);
+#endif
+ if (gstvideo_has_codec(SPICE_VIDEO_CODEC_TYPE_MJPEG)) {
+ spice_channel_set_capability(SPICE_CHANNEL(channel),
+ SPICE_DISPLAY_CAP_CODEC_MJPEG);
+ } else {
+ SPICE_DEBUG("GStreamer does not support the mjpeg codec");
+ }
+ if (gstvideo_has_codec(SPICE_VIDEO_CODEC_TYPE_VP8)) {
+ spice_channel_set_capability(SPICE_CHANNEL(channel),
+ SPICE_DISPLAY_CAP_CODEC_VP8);
+ } else {
+ SPICE_DEBUG("GStreamer does not support the vp8 codec");
+ }
+ if (gstvideo_has_codec(SPICE_VIDEO_CODEC_TYPE_H264)) {
+ spice_channel_set_capability(SPICE_CHANNEL(channel),
+ SPICE_DISPLAY_CAP_CODEC_H264);
+ } else {
+ SPICE_DEBUG("GStreamer does not support the h264 codec");
+ }
+}
+
+static void destroy_surface(gpointer data)
+{
+ display_surface *surface = data;
+
+ destroy_canvas(surface);
+ g_free(surface);
+}
+
+static void spice_display_channel_init(SpiceDisplayChannel *channel)
+{
+ SpiceDisplayChannelPrivate *c;
+
+ c = channel->priv = SPICE_DISPLAY_CHANNEL_GET_PRIVATE(channel);
+
+ c->surfaces = g_hash_table_new_full(NULL, NULL, NULL, destroy_surface);
+ c->image_cache.ops = &image_cache_ops;
+ c->palette_cache.ops = &palette_cache_ops;
+ c->image_surfaces.ops = &image_surfaces_ops;
+#if defined(G_OS_WIN32)
+ c->dc = create_compatible_dc();
+#endif
+ c->monitors_max = 1;
+ c->scanout.fd = -1;
+
+ if (g_getenv("SPICE_DISABLE_ADAPTIVE_STREAMING")) {
+ SPICE_DEBUG("adaptive video disabled");
+ c->enable_adaptive_streaming = FALSE;
+ } else {
+ c->enable_adaptive_streaming = TRUE;
+ }
+ spice_display_channel_reset_capabilities(SPICE_CHANNEL(channel));
+}
+
+/* ------------------------------------------------------------------ */
+
+static int create_canvas(SpiceChannel *channel, display_surface *surface)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+
+ if (surface->primary) {
+ if (c->primary) {
+ if (c->primary->width == surface->width &&
+ c->primary->height == surface->height) {
+ CHANNEL_DEBUG(channel, "Reusing existing primary surface");
+ return 0;
+ }
+
+ g_coroutine_signal_emit(channel, signals[SPICE_DISPLAY_PRIMARY_DESTROY], 0);
+
+ g_hash_table_remove(c->surfaces, GINT_TO_POINTER(c->primary->surface_id));
+ }
+
+ CHANNEL_DEBUG(channel, "Create primary canvas");
+ }
+
+ surface->data = g_malloc0(surface->size);
+
+ g_return_val_if_fail(c->glz_window, 0);
+ g_warn_if_fail(surface->canvas == NULL);
+ g_warn_if_fail(surface->glz_decoder == NULL);
+ g_warn_if_fail(surface->zlib_decoder == NULL);
+ g_warn_if_fail(surface->jpeg_decoder == NULL);
+
+ surface->glz_decoder = glz_decoder_new(c->glz_window);
+ surface->zlib_decoder = zlib_decoder_new();
+ surface->jpeg_decoder = jpeg_decoder_new();
+
+ surface->canvas = canvas_create_for_data(surface->width,
+ surface->height,
+ surface->format,
+ surface->data,
+ surface->stride,
+ &c->image_cache,
+ &c->palette_cache,
+ &c->image_surfaces,
+ surface->glz_decoder,
+ surface->jpeg_decoder,
+ surface->zlib_decoder);
+
+ g_return_val_if_fail(surface->canvas != NULL, 0);
+ g_hash_table_insert(c->surfaces, GINT_TO_POINTER(surface->surface_id), surface);
+
+ if (surface->primary) {
+ g_warn_if_fail(c->primary == NULL);
+ c->primary = surface;
+ g_coroutine_signal_emit(channel, signals[SPICE_DISPLAY_PRIMARY_CREATE], 0,
+ surface->format, surface->width, surface->height,
+ surface->stride, -1, surface->data);
+
+ if (!spice_channel_test_capability(channel, SPICE_DISPLAY_CAP_MONITORS_CONFIG)) {
+ g_array_set_size(c->monitors, 1);
+ SpiceDisplayMonitorConfig *config = &g_array_index(c->monitors, SpiceDisplayMonitorConfig, 0);
+ config->x = config->y = 0;
+ config->width = surface->width;
+ config->height = surface->height;
+ g_coroutine_object_notify(G_OBJECT(channel), "monitors");
+ }
+ }
+
+ return 0;
+}
+
+static void destroy_canvas(display_surface *surface)
+{
+ if (surface == NULL)
+ return;
+
+ glz_decoder_destroy(surface->glz_decoder);
+ zlib_decoder_destroy(surface->zlib_decoder);
+ jpeg_decoder_destroy(surface->jpeg_decoder);
+
+ g_clear_pointer(&surface->data, g_free);
+ g_clear_pointer(&surface->canvas, surface->canvas->ops->destroy);
+}
+
+static display_surface *find_surface(SpiceDisplayChannelPrivate *c, guint32 surface_id)
+{
+ if (c->primary && c->primary->surface_id == surface_id)
+ return c->primary;
+
+ return g_hash_table_lookup(c->surfaces, GINT_TO_POINTER(surface_id));
+}
+
+/* main or coroutine context */
+static void clear_surfaces(SpiceChannel *channel, gboolean keep_primary)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ GHashTableIter iter;
+ display_surface *surface;
+
+ if (!keep_primary) {
+ c->primary = NULL;
+ g_coroutine_signal_emit(channel, signals[SPICE_DISPLAY_PRIMARY_DESTROY], 0);
+ }
+
+ g_hash_table_iter_init(&iter, c->surfaces);
+ while (g_hash_table_iter_next(&iter, NULL, (gpointer*)&surface)) {
+
+ if (keep_primary && surface->primary) {
+ CHANNEL_DEBUG(channel, "keeping existing primary surface, migration or reset");
+ continue;
+ }
+
+ g_hash_table_iter_remove(&iter);
+ }
+}
+
+/* coroutine context */
+static void emit_invalidate(SpiceChannel *channel, SpiceRect *bbox)
+{
+ g_coroutine_signal_emit(channel, signals[SPICE_DISPLAY_INVALIDATE], 0,
+ bbox->left, bbox->top,
+ bbox->right - bbox->left,
+ bbox->bottom - bbox->top);
+}
+
+/* ------------------------------------------------------------------ */
+
+/* coroutine context */
+static void spice_display_channel_up(SpiceChannel *channel)
+{
+ SpiceMsgOut *out;
+ SpiceSession *s = spice_channel_get_session(channel);
+ SpiceMsgcDisplayInit init;
+ int cache_size;
+ int glz_window_size;
+ SpiceImageCompression preferred_compression = SPICE_IMAGE_COMPRESSION_INVALID;
+
+ g_object_get(s,
+ "cache-size", &cache_size,
+ "glz-window-size", &glz_window_size,
+ "preferred-compression", &preferred_compression,
+ NULL);
+ CHANNEL_DEBUG(channel, "%s: cache_size %d, glz_window_size %d (bytes)", __FUNCTION__,
+ cache_size, glz_window_size);
+ init.pixmap_cache_id = 1;
+ init.glz_dictionary_id = 1;
+ init.pixmap_cache_size = cache_size / 4; /* pixels */
+ init.glz_dictionary_window_size = glz_window_size / 4; /* pixels */
+ out = spice_msg_out_new(channel, SPICE_MSGC_DISPLAY_INIT);
+ out->marshallers->msgc_display_init(out->marshaller, &init);
+ spice_msg_out_send_internal(out);
+
+ /* notify of existence of this monitor */
+ g_coroutine_object_notify(G_OBJECT(channel), "monitors");
+
+ if (preferred_compression != SPICE_IMAGE_COMPRESSION_INVALID) {
+ spice_display_change_preferred_compression(channel, preferred_compression);
+ }
+}
+
+#define DRAW(type) { \
+ display_surface *surface = \
+ find_surface(SPICE_DISPLAY_CHANNEL(channel)->priv, \
+ op->base.surface_id); \
+ g_return_if_fail(surface != NULL); \
+ surface->canvas->ops->draw_##type(surface->canvas, &op->base.box, \
+ &op->base.clip, &op->data); \
+ if (surface->primary) { \
+ emit_invalidate(channel, &op->base.box); \
+ } \
+}
+
+/* coroutine context */
+static void display_handle_mode(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ SpiceMsgDisplayMode *mode = spice_msg_in_parsed(in);
+ display_surface *surface;
+
+ g_warn_if_fail(c->mark == FALSE);
+
+ surface = g_new0(display_surface, 1);
+ surface->format = mode->bits == 32 ?
+ SPICE_SURFACE_FMT_32_xRGB : SPICE_SURFACE_FMT_16_555;
+ surface->width = mode->x_res;
+ surface->height = mode->y_res;
+ surface->stride = surface->width * 4;
+ surface->size = surface->height * surface->stride;
+ surface->primary = true;
+ create_canvas(channel, surface);
+}
+
+/* coroutine context */
+static void display_handle_mark(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+
+ CHANNEL_DEBUG(channel, "%s", __FUNCTION__);
+ g_return_if_fail(c->primary != NULL);
+#ifdef EXTRA_CHECKS
+ g_warn_if_fail(c->mark == FALSE);
+#endif
+
+ c->mark = TRUE;
+ g_coroutine_signal_emit(channel, signals[SPICE_DISPLAY_MARK], 0, TRUE);
+}
+
+/* coroutine context */
+static void display_handle_reset(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ display_surface *surface = c->primary;
+
+ CHANNEL_DEBUG(channel, "%s: TODO detach_from_screen", __FUNCTION__);
+
+ if (surface != NULL)
+ surface->canvas->ops->clear(surface->canvas);
+
+ cache_clear(c->palettes);
+
+ c->mark = FALSE;
+ g_coroutine_signal_emit(channel, signals[SPICE_DISPLAY_MARK], 0, FALSE);
+}
+
+/* coroutine context */
+static void display_handle_copy_bits(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayCopyBits *op = spice_msg_in_parsed(in);
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ display_surface *surface = find_surface(c, op->base.surface_id);
+
+ g_return_if_fail(surface != NULL);
+ surface->canvas->ops->copy_bits(surface->canvas, &op->base.box,
+ &op->base.clip, &op->src_pos);
+ if (surface->primary) {
+ emit_invalidate(channel, &op->base.box);
+ }
+}
+
+/* coroutine context */
+static void display_handle_inv_list(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ SpiceResourceList *list = spice_msg_in_parsed(in);
+ int i;
+
+ for (i = 0; i < list->count; i++) {
+ guint64 id = list->resources[i].id;
+
+ switch (list->resources[i].type) {
+ case SPICE_RES_TYPE_PIXMAP:
+ if (!cache_remove(c->images, id))
+ SPICE_DEBUG("fail to remove image %" G_GUINT64_FORMAT, id);
+ break;
+ default:
+ g_return_if_reached();
+ break;
+ }
+ }
+}
+
+/* coroutine context */
+static void display_handle_inv_pixmap_all(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+
+ spice_channel_handle_wait_for_channels(channel, in);
+ cache_clear(c->images);
+}
+
+/* coroutine context */
+static void display_handle_inv_palette(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ SpiceMsgDisplayInvalOne* op = spice_msg_in_parsed(in);
+
+ palette_remove(&c->palette_cache, op->id);
+}
+
+/* coroutine context */
+static void display_handle_inv_palette_all(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+
+ cache_clear(c->palettes);
+}
+
+/* ------------------------------------------------------------------ */
+
+static void display_update_stream_region(display_stream *st)
+{
+ int i;
+
+ switch (st->clip->type) {
+ case SPICE_CLIP_TYPE_RECTS:
+ region_clear(&st->region);
+ for (i = 0; i < st->clip->rects->num_rects; i++) {
+ region_add(&st->region, &st->clip->rects->rects[i]);
+ }
+ st->have_region = true;
+ break;
+ case SPICE_CLIP_TYPE_NONE:
+ default:
+ st->have_region = false;
+ break;
+ }
+}
+
+/* coroutine context */
+static void display_handle_stream_create(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ SpiceMsgDisplayStreamCreate *op = spice_msg_in_parsed(in);
+ display_stream *st;
+
+ CHANNEL_DEBUG(channel, "%s: id %u", __FUNCTION__, op->id);
+
+ if (op->id >= c->nstreams) {
+ int n = c->nstreams;
+ if (!c->nstreams) {
+ c->nstreams = 1;
+ }
+ while (op->id >= c->nstreams) {
+ c->nstreams *= 2;
+ }
+ c->streams = realloc(c->streams, c->nstreams * sizeof(c->streams[0]));
+ memset(c->streams + n, 0, (c->nstreams - n) * sizeof(c->streams[0]));
+ }
+ g_return_if_fail(c->streams[op->id] == NULL);
+ c->streams[op->id] = g_new0(display_stream, 1);
+ st = c->streams[op->id];
+
+ st->msg_create = in;
+ spice_msg_in_ref(in);
+ st->clip = &op->clip;
+ st->surface = find_surface(c, op->surface_id);
+ st->channel = channel;
+ st->drops_seqs_stats_arr = g_array_new(FALSE, FALSE, sizeof(drops_sequence_stats));
+
+ region_init(&st->region);
+ display_update_stream_region(st);
+
+ switch (op->codec_type) {
+#ifdef HAVE_BUILTIN_MJPEG
+ case SPICE_VIDEO_CODEC_TYPE_MJPEG:
+ st->video_decoder = create_mjpeg_decoder(op->codec_type, st);
+ break;
+#endif
+ default:
+#ifdef HAVE_GSTVIDEO
+ st->video_decoder = create_gstreamer_decoder(op->codec_type, st);
+#else
+ st->video_decoder = NULL;
+#endif
+ }
+ if (st->video_decoder == NULL) {
+ spice_printerr("could not create a video decoder for codec %u", op->codec_type);
+ destroy_stream(channel, op->id);
+ }
+}
+
+static const SpiceRect *stream_get_dest(display_stream *st, SpiceMsgIn *frame_msg)
+{
+ if (frame_msg == NULL ||
+ spice_msg_in_type(frame_msg) != SPICE_MSG_DISPLAY_STREAM_DATA_SIZED) {
+ SpiceMsgDisplayStreamCreate *info = spice_msg_in_parsed(st->msg_create);
+
+ return &info->dest;
+ } else {
+ SpiceMsgDisplayStreamDataSized *op = spice_msg_in_parsed(frame_msg);
+
+ return &op->dest;
+ }
+
+}
+
+static uint32_t stream_get_flags(display_stream *st)
+{
+ SpiceMsgDisplayStreamCreate *info = spice_msg_in_parsed(st->msg_create);
+
+ return info->flags;
+}
+
+G_GNUC_INTERNAL
+uint32_t spice_msg_in_frame_data(SpiceMsgIn *frame_msg, uint8_t **data)
+{
+ switch (spice_msg_in_type(frame_msg)) {
+ case SPICE_MSG_DISPLAY_STREAM_DATA: {
+ SpiceMsgDisplayStreamData *op = spice_msg_in_parsed(frame_msg);
+ *data = op->data;
+ return op->data_size;
+ }
+ case SPICE_MSG_DISPLAY_STREAM_DATA_SIZED: {
+ SpiceMsgDisplayStreamDataSized *op = spice_msg_in_parsed(frame_msg);
+ *data = op->data;
+ return op->data_size;
+ }
+ default:
+ *data = NULL;
+ g_return_val_if_reached(0);
+ }
+}
+
+G_GNUC_INTERNAL
+guint32 stream_get_time(display_stream *st)
+{
+ SpiceSession *session = spice_channel_get_session(st->channel);
+ return session ? spice_session_get_mm_time(session) : 0;
+}
+
+/* coroutine or main context */
+G_GNUC_INTERNAL
+void stream_dropped_frame_on_playback(display_stream *st)
+{
+ st->num_drops_on_playback++;
+}
+
+/* main context */
+G_GNUC_INTERNAL
+void stream_display_frame(display_stream *st, SpiceMsgIn *frame_msg,
+ uint32_t width, uint32_t height, uint8_t *data)
+{
+ const SpiceRect *dest;
+ int stride;
+
+ dest = stream_get_dest(st, frame_msg);
+
+ stride = width * sizeof(uint32_t);
+ if (!(stream_get_flags(st) & SPICE_STREAM_FLAGS_TOP_DOWN)) {
+ data += stride * (height - 1);
+ stride = -stride;
+ }
+
+ st->surface->canvas->ops->put_image(st->surface->canvas,
+#ifdef G_OS_WIN32
+ SPICE_DISPLAY_CHANNEL(st->channel)->priv->dc,
+#endif
+ dest, data,
+ width, height, stride,
+ st->have_region ? &st->region : NULL);
+
+ if (st->surface->primary)
+ g_signal_emit(st->channel, signals[SPICE_DISPLAY_INVALIDATE], 0,
+ dest->left, dest->top,
+ dest->right - dest->left,
+ dest->bottom - dest->top);
+}
+
+/* after a sequence of 3 drops, push a report to the server, even
+ * if the report window is bigger */
+#define STREAM_REPORT_DROP_SEQ_LEN_LIMIT 3
+
+static void display_update_stream_report(SpiceDisplayChannel *channel, uint32_t stream_id,
+ uint32_t frame_time, int32_t latency)
+{
+ SpiceDisplayChannelPrivate *c = channel->priv;
+ display_stream *st;
+ guint64 now;
+
+ g_return_if_fail(c != NULL);
+ g_return_if_fail(c->streams != NULL);
+ g_return_if_fail(c->nstreams > stream_id);
+
+ st = channel->priv->streams[stream_id];
+ g_return_if_fail(st != NULL);
+
+ if (!st->report_is_active) {
+ return;
+ }
+ now = g_get_monotonic_time();
+
+ if (st->report_num_frames == 0) {
+ st->report_start_frame_time = frame_time;
+ st->report_start_time = now;
+ }
+ st->report_num_frames++;
+
+ if (latency < 0) { // drop
+ st->report_num_drops++;
+ st->report_drops_seq_len++;
+ } else {
+ st->report_drops_seq_len = 0;
+ }
+
+ if (st->report_num_frames >= st->report_max_window ||
+ now - st->report_start_time >= st->report_timeout ||
+ st->report_drops_seq_len >= STREAM_REPORT_DROP_SEQ_LEN_LIMIT) {
+ SpiceMsgcDisplayStreamReport report;
+ SpiceSession *session = spice_channel_get_session(SPICE_CHANNEL(channel));
+ SpiceMsgOut *msg;
+
+ report.stream_id = stream_id;
+ report.unique_id = st->report_id;
+ report.start_frame_mm_time = st->report_start_frame_time;
+ report.end_frame_mm_time = frame_time;
+ report.num_frames = st->report_num_frames;
+ report.num_drops = st-> report_num_drops;
+ report.last_frame_delay = latency;
+ if (spice_session_is_playback_active(session)) {
+ report.audio_delay = spice_session_get_playback_latency(session);
+ } else {
+ report.audio_delay = UINT_MAX;
+ }
+
+ msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_DISPLAY_STREAM_REPORT);
+ msg->marshallers->msgc_display_stream_report(msg->marshaller, &report);
+ spice_msg_out_send(msg);
+
+ st->report_start_time = 0;
+ st->report_start_frame_time = 0;
+ st->report_num_frames = 0;
+ st->report_num_drops = 0;
+ st->report_drops_seq_len = 0;
+ }
+}
+
+/*
+ * Migration can occur between 2 spice-servers with different mm-times.
+ * Then, the following cases can happen after migration completes:
+ * (We refer to src/dst-time as the mm-times on the src/dst servers):
+ *
+ * (case 1) Frames with time ~= dst-time arrive to the client before the
+ * playback-channel updates the session's mm-time (i.e., the mm_time
+ * of the session is still based on the src-time).
+ * (a) If src-time < dst-time:
+ * display_stream_schedule schedules the next rendering to
+ * ~(dst-time - src-time) milliseconds from now.
+ * Since we assume monotonic mm_time, display_stream_schedule,
+ * returns immediately when a rendering timeout
+ * has already been set, and doesn't update the timeout,
+ * even after the mm_time is updated.
+ * When src-time << dst-time, a significant video frames loss will occur.
+ * (b) If src-time > dst-time
+ * Frames will be dropped till the mm-time will be updated.
+ * (case 2) mm-time is synced with dst-time, but frames that were in the command
+ * ring during migration still arrive (such frames hold src-time).
+ * (a) If src-time < dst-time
+ * The frames that hold src-time will be dropped, since their
+ * mm_time < session-mm_time. But all the new frames that are generated in
+ * the driver after migration, will be rendered appropriately.
+ * (b) If src-time > dst-time
+ * Similar consequences as in 1 (a)
+ * case 2 is less likely, since at takes at least 20 frames till the dst-server re-identifies
+ * the video stream and starts sending stream data
+ *
+ * display_session_mm_time_reset_cb handles case 1.a by notifying the
+ * video decoders through their reschedule() method, and case 2.b is handled
+ * directly by the video decoders in their queue_frame() method
+ */
+
+/* main context */
+static void display_session_mm_time_reset_cb(SpiceSession *session, gpointer data)
+{
+ SpiceChannel *channel = data;
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ guint i;
+
+ CHANNEL_DEBUG(channel, "%s", __FUNCTION__);
+
+ for (i = 0; i < c->nstreams; i++) {
+ display_stream *st;
+
+ if (c->streams[i] == NULL) {
+ continue;
+ }
+ SPICE_DEBUG("%s: stream-id %u", __FUNCTION__, i);
+ st = c->streams[i];
+ st->video_decoder->reschedule(st->video_decoder);
+ }
+}
+
+#define STREAM_PLAYBACK_SYNC_DROP_SEQ_LEN_LIMIT 5
+
+/* coroutine context */
+static void display_handle_stream_data(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ SpiceStreamDataHeader *op = spice_msg_in_parsed(in);
+ display_stream *st;
+ guint32 mmtime;
+ int32_t latency;
+
+ g_return_if_fail(c != NULL);
+ g_return_if_fail(c->streams != NULL);
+ g_return_if_fail(c->nstreams > op->id);
+
+ st = c->streams[op->id];
+ g_return_if_fail(st != NULL);
+ mmtime = stream_get_time(st);
+
+ if (spice_msg_in_type(in) == SPICE_MSG_DISPLAY_STREAM_DATA_SIZED) {
+ CHANNEL_DEBUG(channel, "stream %u contains sized data", op->id);
+ }
+
+ if (op->multi_media_time == 0) {
+ g_critical("Received frame with invalid 0 timestamp! perhaps wrong graphic driver?");
+ op->multi_media_time = mmtime + 100; /* workaround... */
+ }
+
+ if (!st->num_input_frames) {
+ st->first_frame_mm_time = op->multi_media_time;
+ }
+ st->num_input_frames++;
+
+ latency = op->multi_media_time - mmtime;
+ if (latency < 0) {
+ CHANNEL_DEBUG(channel, "stream data too late by %u ms (ts: %u, mmtime: %u), dropping",
+ mmtime - op->multi_media_time, op->multi_media_time, mmtime);
+ st->arrive_late_time += mmtime - op->multi_media_time;
+ st->arrive_late_count++;
+
+ if (!st->cur_drops_seq_stats.len) {
+ st->cur_drops_seq_stats.start_mm_time = op->multi_media_time;
+ }
+ st->cur_drops_seq_stats.len++;
+ st->playback_sync_drops_seq_len++;
+ } else {
+ CHANNEL_DEBUG(channel, "video latency: %d", latency);
+ if (st->cur_drops_seq_stats.len) {
+ st->cur_drops_seq_stats.duration = op->multi_media_time -
+ st->cur_drops_seq_stats.start_mm_time;
+ g_array_append_val(st->drops_seqs_stats_arr, st->cur_drops_seq_stats);
+ memset(&st->cur_drops_seq_stats, 0, sizeof(st->cur_drops_seq_stats));
+ st->num_drops_seqs++;
+ }
+ st->playback_sync_drops_seq_len = 0;
+ }
+
+ /* Let the video decoder queue the frames so it can optimize their
+ * decoding and best decide if/when to drop them when they are late,
+ * taking into account the impact on later frames.
+ */
+ st->video_decoder->queue_frame(st->video_decoder, in, latency);
+ if (c->enable_adaptive_streaming) {
+ display_update_stream_report(SPICE_DISPLAY_CHANNEL(channel), op->id,
+ op->multi_media_time, latency);
+ if (st->playback_sync_drops_seq_len >= STREAM_PLAYBACK_SYNC_DROP_SEQ_LEN_LIMIT) {
+ spice_session_sync_playback_latency(spice_channel_get_session(channel));
+ st->playback_sync_drops_seq_len = 0;
+ }
+ }
+}
+
+/* coroutine context */
+static void display_handle_stream_clip(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ SpiceMsgDisplayStreamClip *op = spice_msg_in_parsed(in);
+ display_stream *st;
+
+ g_return_if_fail(c != NULL);
+ g_return_if_fail(c->streams != NULL);
+ g_return_if_fail(c->nstreams > op->id);
+
+ st = c->streams[op->id];
+ g_return_if_fail(st != NULL);
+
+ if (st->msg_clip) {
+ spice_msg_in_unref(st->msg_clip);
+ }
+ spice_msg_in_ref(in);
+ st->msg_clip = in;
+ st->clip = &op->clip;
+ display_update_stream_region(st);
+}
+
+static void destroy_stream(SpiceChannel *channel, int id)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ display_stream *st;
+ int i;
+
+ g_return_if_fail(c != NULL);
+ g_return_if_fail(c->streams != NULL);
+ g_return_if_fail(c->nstreams > id);
+
+ st = c->streams[id];
+ if (!st)
+ return;
+
+ if (st->num_input_frames > 0) {
+ guint64 drops_duration_total = 0;
+ guint32 num_out_frames = st->num_input_frames - st->arrive_late_count - st->num_drops_on_playback;
+ CHANNEL_DEBUG(channel, "%s: id=%d #in-frames=%u out/in=%.2f "
+ "#drops-on-receive=%u avg-late-time(ms)=%.2f "
+ "#drops-on-playback=%u", __FUNCTION__,
+ id,
+ st->num_input_frames,
+ num_out_frames / (double)st->num_input_frames,
+ st->arrive_late_count,
+ st->arrive_late_count ? st->arrive_late_time / ((double)st->arrive_late_count): 0,
+ st->num_drops_on_playback);
+ if (st->num_drops_seqs) {
+ CHANNEL_DEBUG(channel, "%s: #drops-sequences=%u ==>", __FUNCTION__, st->num_drops_seqs);
+ }
+ for (i = 0; i < st->num_drops_seqs; i++) {
+ drops_sequence_stats *stats = &g_array_index(st->drops_seqs_stats_arr,
+ drops_sequence_stats,
+ i);
+ drops_duration_total += stats->duration;
+ CHANNEL_DEBUG(channel, "%s: \t len=%u start-ms=%u duration-ms=%u", __FUNCTION__,
+ stats->len,
+ stats->start_mm_time - st->first_frame_mm_time,
+ stats->duration);
+ }
+ if (st->num_drops_seqs) {
+ CHANNEL_DEBUG(channel, "%s: drops-total-duration=%"G_GUINT64_FORMAT" ==>", __FUNCTION__, drops_duration_total);
+ }
+ }
+
+ g_array_free(st->drops_seqs_stats_arr, TRUE);
+
+ if (st->video_decoder) {
+ st->video_decoder->destroy(st->video_decoder);
+ }
+
+ if (st->msg_clip)
+ spice_msg_in_unref(st->msg_clip);
+ spice_msg_in_unref(st->msg_create);
+
+ g_free(st);
+ c->streams[id] = NULL;
+}
+
+static void clear_streams(SpiceChannel *channel)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ int i;
+
+ for (i = 0; i < c->nstreams; i++) {
+ destroy_stream(channel, i);
+ }
+ g_clear_pointer(&c->streams, g_free);
+ c->nstreams = 0;
+}
+
+/* coroutine context */
+static void display_handle_stream_destroy(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayStreamDestroy *op = spice_msg_in_parsed(in);
+
+ g_return_if_fail(op != NULL);
+ CHANNEL_DEBUG(channel, "%s: id %u", __FUNCTION__, op->id);
+ destroy_stream(channel, op->id);
+}
+
+/* coroutine context */
+static void display_handle_stream_destroy_all(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ clear_streams(channel);
+}
+
+/* coroutine context */
+static void display_handle_stream_activate_report(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ SpiceMsgDisplayStreamActivateReport *op = spice_msg_in_parsed(in);
+ display_stream *st;
+
+ g_return_if_fail(c != NULL);
+ g_return_if_fail(c->streams != NULL);
+ g_return_if_fail(c->nstreams > op->stream_id);
+
+ st = c->streams[op->stream_id];
+ g_return_if_fail(st != NULL);
+
+ st->report_is_active = TRUE;
+ st->report_id = op->unique_id;
+ st->report_max_window = op->max_window_size;
+ st->report_timeout = op->timeout_ms * 1000;
+ st->report_start_time = 0;
+ st->report_start_frame_time = 0;
+ st->report_num_frames = 0;
+ st->report_num_drops = 0;
+ st->report_drops_seq_len = 0;
+}
+
+/* ------------------------------------------------------------------ */
+
+/* coroutine context */
+static void display_handle_draw_fill(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawFill *op = spice_msg_in_parsed(in);
+ DRAW(fill);
+}
+
+/* coroutine context */
+static void display_handle_draw_opaque(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawOpaque *op = spice_msg_in_parsed(in);
+ DRAW(opaque);
+}
+
+/* coroutine context */
+static void display_handle_draw_copy(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawCopy *op = spice_msg_in_parsed(in);
+ DRAW(copy);
+}
+
+/* coroutine context */
+static void display_handle_draw_blend(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawBlend *op = spice_msg_in_parsed(in);
+ DRAW(blend);
+}
+
+/* coroutine context */
+static void display_handle_draw_blackness(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawBlackness *op = spice_msg_in_parsed(in);
+ DRAW(blackness);
+}
+
+static void display_handle_draw_whiteness(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawWhiteness *op = spice_msg_in_parsed(in);
+ DRAW(whiteness);
+}
+
+/* coroutine context */
+static void display_handle_draw_invers(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawInvers *op = spice_msg_in_parsed(in);
+ DRAW(invers);
+}
+
+/* coroutine context */
+static void display_handle_draw_rop3(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawRop3 *op = spice_msg_in_parsed(in);
+ DRAW(rop3);
+}
+
+/* coroutine context */
+static void display_handle_draw_stroke(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawStroke *op = spice_msg_in_parsed(in);
+ DRAW(stroke);
+}
+
+/* coroutine context */
+static void display_handle_draw_text(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawText *op = spice_msg_in_parsed(in);
+ DRAW(text);
+}
+
+/* coroutine context */
+static void display_handle_draw_transparent(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawTransparent *op = spice_msg_in_parsed(in);
+ DRAW(transparent);
+}
+
+/* coroutine context */
+static void display_handle_draw_alpha_blend(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawAlphaBlend *op = spice_msg_in_parsed(in);
+ DRAW(alpha_blend);
+}
+
+/* coroutine context */
+static void display_handle_draw_composite(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayDrawComposite *op = spice_msg_in_parsed(in);
+ DRAW(composite);
+}
+
+/* coroutine context */
+static void display_handle_surface_create(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ SpiceMsgSurfaceCreate *create = spice_msg_in_parsed(in);
+ display_surface *surface = g_new0(display_surface, 1);
+
+ surface->surface_id = create->surface_id;
+ surface->format = create->format;
+ surface->width = create->width;
+ surface->height = create->height;
+ surface->stride = create->width * 4;
+ surface->size = surface->height * surface->stride;
+
+ if (create->flags & SPICE_SURFACE_FLAGS_PRIMARY) {
+ SPICE_DEBUG("primary flags: %x", create->flags);
+ surface->primary = true;
+ create_canvas(channel, surface);
+ if (c->mark_false_event_id != 0) {
+ g_source_remove(c->mark_false_event_id);
+ c->mark_false_event_id = FALSE;
+ }
+ } else {
+ surface->primary = false;
+ create_canvas(channel, surface);
+ }
+}
+
+static gboolean display_mark_false(gpointer data)
+{
+ SpiceChannel *channel = data;
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+
+ c->mark = FALSE;
+ g_signal_emit(channel, signals[SPICE_DISPLAY_MARK], 0, FALSE);
+
+ c->mark_false_event_id = 0;
+ return FALSE;
+}
+
+/* coroutine context */
+static void display_handle_surface_destroy(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgSurfaceDestroy *destroy = spice_msg_in_parsed(in);
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ display_surface *surface;
+
+ g_return_if_fail(destroy != NULL);
+
+ surface = find_surface(c, destroy->surface_id);
+ if (surface == NULL) {
+ /* this is not a problem in spicec, it happens as well and returns.. */
+ /* g_warn_if_reached(); */
+ return;
+ }
+ if (surface->primary) {
+ int id = spice_channel_get_channel_id(channel);
+ CHANNEL_DEBUG(channel, "%d: FIXME primary destroy, but is display really disabled?", id);
+ /* this is done with a timeout in spicec as well, it's *ugly* */
+ if (id != 0 && c->mark_false_event_id == 0) {
+ c->mark_false_event_id = g_timeout_add_seconds(1, display_mark_false, channel);
+ }
+ c->primary = NULL;
+ g_coroutine_signal_emit(channel, signals[SPICE_DISPLAY_PRIMARY_DESTROY], 0);
+ }
+
+ g_hash_table_remove(c->surfaces, GINT_TO_POINTER(surface->surface_id));
+}
+
+#define CLAMP_CHECK(x, low, high) (((x) > (high)) ? TRUE : (((x) < (low)) ? TRUE : FALSE))
+
+/* coroutine context */
+static void display_handle_monitors_config(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayMonitorsConfig *config = spice_msg_in_parsed(in);
+ SpiceDisplayChannelPrivate *c = SPICE_DISPLAY_CHANNEL(channel)->priv;
+ guint i;
+
+ g_return_if_fail(config != NULL);
+
+ if (config->count == 0) {
+ CHANNEL_DEBUG(channel, "received empty monitor config");
+ return;
+ }
+
+ CHANNEL_DEBUG(channel, "received new monitors config from guest: n: %d/%d", config->count, config->max_allowed);
+
+ c->monitors_max = config->max_allowed;
+ if (CLAMP_CHECK(c->monitors_max, 1, MONITORS_MAX)) {
+ g_warning("MonitorConfig max_allowed is not within permitted range, clamping");
+ c->monitors_max = CLAMP(c->monitors_max, 1, MONITORS_MAX);
+ }
+
+ if (CLAMP_CHECK(config->count, 1, c->monitors_max)) {
+ g_warning("MonitorConfig count is not within permitted range, clamping");
+ config->count = CLAMP(config->count, 1, c->monitors_max);
+ }
+
+ c->monitors = g_array_set_size(c->monitors, config->count);
+
+ for (i = 0; i < config->count; i++) {
+ SpiceDisplayMonitorConfig *mc = &g_array_index(c->monitors, SpiceDisplayMonitorConfig, i);
+ SpiceHead *head = &config->heads[i];
+ CHANNEL_DEBUG(channel, "monitor id: %u, surface id: %u, +%u+%u-%ux%u",
+ head->id, head->surface_id,
+ head->x, head->y, head->width, head->height);
+ mc->id = head->id;
+ mc->surface_id = head->surface_id;
+ mc->x = head->x;
+ mc->y = head->y;
+ mc->width = head->width;
+ mc->height = head->height;
+ }
+
+ g_coroutine_object_notify(G_OBJECT(channel), "monitors");
+}
+
+
+#ifdef G_OS_UNIX
+/* coroutine context */
+static void display_handle_gl_scanout_unix(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceDisplayChannel *display = SPICE_DISPLAY_CHANNEL(channel);
+ SpiceDisplayChannelPrivate *c = display->priv;
+ SpiceMsgDisplayGlScanoutUnix *scanout = spice_msg_in_parsed(in);
+
+ scanout->drm_dma_buf_fd = -1;
+ if (scanout->drm_fourcc_format != 0) {
+ scanout->drm_dma_buf_fd = spice_channel_unix_read_fd(channel);
+ CHANNEL_DEBUG(channel, "gl scanout fd: %d", scanout->drm_dma_buf_fd);
+ }
+
+ c->scanout.y0top = scanout->flags & SPICE_GL_SCANOUT_FLAGS_Y0TOP;
+ if (c->scanout.fd >= 0)
+ close(c->scanout.fd);
+ c->scanout.fd = scanout->drm_dma_buf_fd;
+ c->scanout.width = scanout->width;
+ c->scanout.height = scanout->height;
+ c->scanout.stride = scanout->stride;
+ c->scanout.format = scanout->drm_fourcc_format;
+
+ g_coroutine_object_notify(G_OBJECT(channel), "gl-scanout");
+}
+#endif
+
+/* coroutine context */
+static void display_handle_gl_draw(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgDisplayGlDraw *draw = spice_msg_in_parsed(in);
+
+ CHANNEL_DEBUG(channel, "gl draw %ux%u+%u+%u",
+ draw->w, draw->h, draw->x, draw->y);
+
+ g_coroutine_signal_emit(channel, signals[SPICE_DISPLAY_GL_DRAW], 0,
+ draw->x, draw->y,
+ draw->w, draw->h);
+}
+
+/**
+ * spice_display_gl_draw_done:
+ * @channel: a #SpiceDisplayChannel
+ *
+ * After a SpiceDisplayChannel::gl-draw is emitted, the client should
+ * draw the current display with the current GL scanout, and must
+ * release the GL resource with a call to spice_display_gl_draw_done()
+ * (failing to do so for each gl-draw may result in a frozen display).
+ *
+ * Since: 0.31
+ **/
+void spice_display_gl_draw_done(SpiceDisplayChannel *display)
+{
+ SpiceChannel *channel;
+ SpiceMsgOut *out;
+
+ g_return_if_fail(SPICE_IS_DISPLAY_CHANNEL(display));
+ channel = SPICE_CHANNEL(display);
+
+ out = spice_msg_out_new(channel, SPICE_MSGC_DISPLAY_GL_DRAW_DONE);
+ out->marshallers->msgc_display_gl_draw_done(out->marshaller, NULL);
+ spice_msg_out_send_internal(out);
+}
+
+static void channel_set_handlers(SpiceChannelClass *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_DISPLAY_MODE ] = display_handle_mode,
+ [ SPICE_MSG_DISPLAY_MARK ] = display_handle_mark,
+ [ SPICE_MSG_DISPLAY_RESET ] = display_handle_reset,
+ [ SPICE_MSG_DISPLAY_COPY_BITS ] = display_handle_copy_bits,
+ [ SPICE_MSG_DISPLAY_INVAL_LIST ] = display_handle_inv_list,
+ [ SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS ] = display_handle_inv_pixmap_all,
+ [ SPICE_MSG_DISPLAY_INVAL_PALETTE ] = display_handle_inv_palette,
+ [ SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES ] = display_handle_inv_palette_all,
+
+ [ SPICE_MSG_DISPLAY_STREAM_CREATE ] = display_handle_stream_create,
+ [ SPICE_MSG_DISPLAY_STREAM_DATA ] = display_handle_stream_data,
+ [ SPICE_MSG_DISPLAY_STREAM_CLIP ] = display_handle_stream_clip,
+ [ SPICE_MSG_DISPLAY_STREAM_DESTROY ] = display_handle_stream_destroy,
+ [ SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL ] = display_handle_stream_destroy_all,
+ [ SPICE_MSG_DISPLAY_STREAM_DATA_SIZED ] = display_handle_stream_data,
+ [ SPICE_MSG_DISPLAY_STREAM_ACTIVATE_REPORT ] = display_handle_stream_activate_report,
+
+ [ SPICE_MSG_DISPLAY_DRAW_FILL ] = display_handle_draw_fill,
+ [ SPICE_MSG_DISPLAY_DRAW_OPAQUE ] = display_handle_draw_opaque,
+ [ SPICE_MSG_DISPLAY_DRAW_COPY ] = display_handle_draw_copy,
+ [ SPICE_MSG_DISPLAY_DRAW_BLEND ] = display_handle_draw_blend,
+ [ SPICE_MSG_DISPLAY_DRAW_BLACKNESS ] = display_handle_draw_blackness,
+ [ SPICE_MSG_DISPLAY_DRAW_WHITENESS ] = display_handle_draw_whiteness,
+ [ SPICE_MSG_DISPLAY_DRAW_INVERS ] = display_handle_draw_invers,
+ [ SPICE_MSG_DISPLAY_DRAW_ROP3 ] = display_handle_draw_rop3,
+ [ SPICE_MSG_DISPLAY_DRAW_STROKE ] = display_handle_draw_stroke,
+ [ SPICE_MSG_DISPLAY_DRAW_TEXT ] = display_handle_draw_text,
+ [ SPICE_MSG_DISPLAY_DRAW_TRANSPARENT ] = display_handle_draw_transparent,
+ [ SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND ] = display_handle_draw_alpha_blend,
+ [ SPICE_MSG_DISPLAY_DRAW_COMPOSITE ] = display_handle_draw_composite,
+
+ [ SPICE_MSG_DISPLAY_SURFACE_CREATE ] = display_handle_surface_create,
+ [ SPICE_MSG_DISPLAY_SURFACE_DESTROY ] = display_handle_surface_destroy,
+
+ [ SPICE_MSG_DISPLAY_MONITORS_CONFIG ] = display_handle_monitors_config,
+#ifdef G_OS_UNIX
+ [ SPICE_MSG_DISPLAY_GL_SCANOUT_UNIX ] = display_handle_gl_scanout_unix,
+#endif
+ [ SPICE_MSG_DISPLAY_GL_DRAW ] = display_handle_gl_draw,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_DISPLAY_CHANNEL_H__
+#define __SPICE_CLIENT_DISPLAY_CHANNEL_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_DISPLAY_CHANNEL (spice_display_channel_get_type())
+#define SPICE_DISPLAY_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_DISPLAY_CHANNEL, SpiceDisplayChannel))
+#define SPICE_DISPLAY_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_DISPLAY_CHANNEL, SpiceDisplayChannelClass))
+#define SPICE_IS_DISPLAY_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_DISPLAY_CHANNEL))
+#define SPICE_IS_DISPLAY_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_DISPLAY_CHANNEL))
+#define SPICE_DISPLAY_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_DISPLAY_CHANNEL, SpiceDisplayChannelClass))
+
+typedef struct _SpiceDisplayChannel SpiceDisplayChannel;
+typedef struct _SpiceDisplayChannelClass SpiceDisplayChannelClass;
+typedef struct _SpiceDisplayChannelPrivate SpiceDisplayChannelPrivate;
+
+#define SPICE_TYPE_GL_SCANOUT (spice_gl_scanout_get_type ())
+
+/**
+ * SpiceGlScanout:
+ * @fd: a drm DMABUF file that can be imported with eglCreateImageKHR
+ * @width: width of the scanout
+ * @height: height of the scanout
+ * @stride: stride of the scanout
+ * @format: the drm fourcc format
+ * @y0top: orientation of the scanout
+ *
+ * Holds the information necessary for using the GL display scanout.
+ **/
+typedef struct _SpiceGlScanout SpiceGlScanout;
+struct _SpiceGlScanout {
+ gint fd;
+ guint32 width;
+ guint32 height;
+ guint32 stride;
+ guint32 format;
+ gboolean y0top;
+};
+
+/**
+ * SpiceDisplayMonitorConfig:
+ * @id: monitor id
+ * @surface_id: monitor surface id
+ * @x: x position of the monitor
+ * @y: y position of the monitor
+ * @width: width of the monitor
+ * @height: height of the monitor
+ *
+ * Holds a monitor configuration.
+ **/
+typedef struct _SpiceDisplayMonitorConfig SpiceDisplayMonitorConfig;
+struct _SpiceDisplayMonitorConfig {
+ guint id;
+ guint surface_id;
+ guint x;
+ guint y;
+ guint width;
+ guint height;
+};
+
+/**
+ * SpiceDisplayPrimary:
+ * @format: primary buffer format
+ * @width: width of the primary
+ * @height: height of the primary
+ * @stride: stride of the primary
+ * @shmid: identifier of the shared memory segment associated with
+ * the @data, or -1 if not shm
+ * @data: pointer to primary buffer
+ * @marked: whether the display is marked ready
+ *
+ * Holds the information necessary to use the primary surface.
+ **/
+typedef struct _SpiceDisplayPrimary SpiceDisplayPrimary;
+struct _SpiceDisplayPrimary {
+ enum SpiceSurfaceFmt format;
+ gint width;
+ gint height;
+ gint stride;
+ gint shmid;
+ guint8 *data;
+ gboolean marked;
+};
+
+/**
+ * SpiceDisplayChannel:
+ *
+ * The #SpiceDisplayChannel struct is opaque and should not be accessed directly.
+ */
+struct _SpiceDisplayChannel {
+ SpiceChannel parent;
+
+ /*< private >*/
+ SpiceDisplayChannelPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpiceDisplayChannelClass:
+ * @parent_class: Parent class.
+ * @display_primary_create: Signal class handler for the #SpiceDisplayChannel::display-primary-create signal.
+ * @display_primary_destroy: Signal class handler for the #SpiceDisplayChannel::display-primary-destroy signal.
+ * @display_invalidate: Signal class handler for the #SpiceDisplayChannel::display-invalidate signal.
+ * @display_mark: Signal class handler for the #SpiceDisplayChannel::display-mark signal.
+ *
+ * Class structure for #SpiceDisplayChannel.
+ */
+struct _SpiceDisplayChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*display_primary_create)(SpiceChannel *channel, gint format,
+ gint width, gint height, gint stride,
+ gint shmid, gpointer data);
+ void (*display_primary_destroy)(SpiceChannel *channel);
+ void (*display_invalidate)(SpiceChannel *channel,
+ gint x, gint y, gint w, gint h);
+ void (*display_mark)(SpiceChannel *channel,
+ gboolean mark);
+
+ /*< private >*/
+};
+
+GType spice_display_channel_get_type(void);
+gboolean spice_display_get_primary(SpiceChannel *channel, guint32 surface_id,
+ SpiceDisplayPrimary *primary);
+
+void spice_display_change_preferred_compression(SpiceChannel *channel, gint compression);
+
+GType spice_gl_scanout_get_type (void) G_GNUC_CONST;
+void spice_gl_scanout_free (SpiceGlScanout *scanout);
+
+const SpiceGlScanout* spice_display_get_gl_scanout(SpiceDisplayChannel *channel);
+void spice_display_gl_draw_done(SpiceDisplayChannel *channel);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_DISPLAY_CHANNEL_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+#include "spice-channel-priv.h"
+
+/**
+ * SECTION:channel-inputs
+ * @short_description: control the server mouse and keyboard
+ * @title: Inputs Channel
+ * @section_id:
+ * @see_also: #SpiceChannel, and the GTK widget #SpiceDisplay
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * Spice supports sending keyboard key events and keyboard leds
+ * synchronization. The key events are sent using
+ * spice_inputs_key_press() and spice_inputs_key_release() using
+ * a modified variant of PC XT scancodes.
+ *
+ * Guest keyboard leds state can be manipulated with
+ * spice_inputs_set_key_locks(). When key lock change, a notification
+ * is emitted with #SpiceInputsChannel::inputs-modifiers signal.
+ */
+
+#define SPICE_INPUTS_CHANNEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_INPUTS_CHANNEL, SpiceInputsChannelPrivate))
+
+struct _SpiceInputsChannelPrivate {
+ int bs;
+ int dx, dy;
+ unsigned int x, y, dpy;
+ int motion_count;
+ int modifiers;
+ guint32 locks;
+};
+
+G_DEFINE_TYPE(SpiceInputsChannel, spice_inputs_channel, SPICE_TYPE_CHANNEL)
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_KEY_MODIFIERS,
+};
+
+/* Signals */
+enum {
+ SPICE_INPUTS_MODIFIERS,
+
+ SPICE_INPUTS_LAST_SIGNAL,
+};
+
+static guint signals[SPICE_INPUTS_LAST_SIGNAL];
+
+static void spice_inputs_channel_up(SpiceChannel *channel);
+static void spice_inputs_channel_reset(SpiceChannel *channel, gboolean migrating);
+static void channel_set_handlers(SpiceChannelClass *klass);
+
+/* ------------------------------------------------------------------ */
+
+static void spice_inputs_channel_init(SpiceInputsChannel *channel)
+{
+ channel->priv = SPICE_INPUTS_CHANNEL_GET_PRIVATE(channel);
+}
+
+static void spice_inputs_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(object)->priv;
+
+ switch (prop_id) {
+ case PROP_KEY_MODIFIERS:
+ g_value_set_int(value, c->modifiers);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_inputs_channel_finalize(GObject *obj)
+{
+ if (G_OBJECT_CLASS(spice_inputs_channel_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_inputs_channel_parent_class)->finalize(obj);
+}
+
+static void spice_inputs_channel_class_init(SpiceInputsChannelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
+
+ gobject_class->finalize = spice_inputs_channel_finalize;
+ gobject_class->get_property = spice_inputs_get_property;
+ channel_class->channel_up = spice_inputs_channel_up;
+ channel_class->channel_reset = spice_inputs_channel_reset;
+
+ g_object_class_install_property
+ (gobject_class, PROP_KEY_MODIFIERS,
+ g_param_spec_int("key-modifiers",
+ "Key modifiers",
+ "Guest keyboard lock/led state",
+ 0, INT_MAX, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ /**
+ * SpiceInputsChannel::inputs-modifiers:
+ * @display: the #SpiceInputsChannel that emitted the signal
+ *
+ * The #SpiceInputsChannel::inputs-modifiers signal is emitted when
+ * the guest keyboard locks are changed. You can read the current
+ * state from #SpiceInputsChannel:key-modifiers property.
+ **/
+ /* TODO: use notify instead? */
+ signals[SPICE_INPUTS_MODIFIERS] =
+ g_signal_new("inputs-modifiers",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceInputsChannelClass, inputs_modifiers),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_class_add_private(klass, sizeof(SpiceInputsChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
+}
+
+/* ------------------------------------------------------------------ */
+
+static SpiceMsgOut* mouse_motion(SpiceInputsChannel *channel)
+{
+ SpiceInputsChannelPrivate *c = channel->priv;
+ SpiceMsgcMouseMotion motion;
+ SpiceMsgOut *msg;
+
+ if (!c->dx && !c->dy)
+ return NULL;
+
+ motion.buttons_state = c->bs;
+ motion.dx = c->dx;
+ motion.dy = c->dy;
+ msg = spice_msg_out_new(SPICE_CHANNEL(channel),
+ SPICE_MSGC_INPUTS_MOUSE_MOTION);
+ msg->marshallers->msgc_inputs_mouse_motion(msg->marshaller, &motion);
+
+ c->motion_count++;
+ c->dx = 0;
+ c->dy = 0;
+
+ return msg;
+}
+
+static SpiceMsgOut* mouse_position(SpiceInputsChannel *channel)
+{
+ SpiceInputsChannelPrivate *c = channel->priv;
+ SpiceMsgcMousePosition position;
+ SpiceMsgOut *msg;
+
+ if (c->dpy == -1)
+ return NULL;
+
+ /* CHANNEL_DEBUG(channel, "%s: +%d+%d", __FUNCTION__, c->x, c->y); */
+ position.buttons_state = c->bs;
+ position.x = c->x;
+ position.y = c->y;
+ position.display_id = c->dpy;
+ msg = spice_msg_out_new(SPICE_CHANNEL(channel),
+ SPICE_MSGC_INPUTS_MOUSE_POSITION);
+ msg->marshallers->msgc_inputs_mouse_position(msg->marshaller, &position);
+
+ c->motion_count++;
+ c->dpy = -1;
+
+ return msg;
+}
+
+/* main context */
+static void send_position(SpiceInputsChannel *channel)
+{
+ SpiceMsgOut *msg;
+
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
+ msg = mouse_position(channel);
+ if (!msg) /* if no motion */
+ return;
+
+ spice_msg_out_send(msg);
+}
+
+/* main context */
+static void send_motion(SpiceInputsChannel *channel)
+{
+ SpiceMsgOut *msg;
+
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
+ msg = mouse_motion(channel);
+ if (!msg) /* if no motion */
+ return;
+
+ spice_msg_out_send(msg);
+}
+
+/* coroutine context */
+static void inputs_handle_init(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(channel)->priv;
+ SpiceMsgInputsInit *init = spice_msg_in_parsed(in);
+
+ c->modifiers = init->keyboard_modifiers;
+ g_coroutine_signal_emit(channel, signals[SPICE_INPUTS_MODIFIERS], 0);
+}
+
+/* coroutine context */
+static void inputs_handle_modifiers(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(channel)->priv;
+ SpiceMsgInputsKeyModifiers *modifiers = spice_msg_in_parsed(in);
+
+ if (c->modifiers != modifiers->modifiers) {
+ c->modifiers = modifiers->modifiers;
+ g_coroutine_signal_emit(channel, signals[SPICE_INPUTS_MODIFIERS], 0);
+ }
+}
+
+/* coroutine context */
+static void inputs_handle_ack(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(channel)->priv;
+ SpiceMsgOut *msg;
+
+ c->motion_count -= SPICE_INPUT_MOTION_ACK_BUNCH;
+
+ msg = mouse_motion(SPICE_INPUTS_CHANNEL(channel));
+ if (msg) { /* if no motion, msg == NULL */
+ spice_msg_out_send_internal(msg);
+ }
+
+ msg = mouse_position(SPICE_INPUTS_CHANNEL(channel));
+ if (msg) {
+ spice_msg_out_send_internal(msg);
+ }
+}
+
+static void channel_set_handlers(SpiceChannelClass *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_INPUTS_INIT ] = inputs_handle_init,
+ [ SPICE_MSG_INPUTS_KEY_MODIFIERS ] = inputs_handle_modifiers,
+ [ SPICE_MSG_INPUTS_MOUSE_MOTION_ACK ] = inputs_handle_ack,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
+}
+
+/**
+ * spice_inputs_motion:
+ * @channel: a #SpiceInputsChannel
+ * @dx: delta X mouse coordinates
+ * @dy: delta Y mouse coordinates
+ * @button_state: SPICE_MOUSE_BUTTON_MASK flags
+ *
+ * Change mouse position (used in SPICE_MOUSE_MODE_CLIENT).
+ **/
+void spice_inputs_motion(SpiceInputsChannel *channel, gint dx, gint dy,
+ gint button_state)
+{
+ SpiceInputsChannelPrivate *c;
+
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_UNCONNECTED);
+ if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
+ return;
+
+ if (dx == 0 && dy == 0)
+ return;
+
+ c = channel->priv;
+ c->bs = button_state;
+ c->dx += dx;
+ c->dy += dy;
+
+ if (c->motion_count < SPICE_INPUT_MOTION_ACK_BUNCH * 2) {
+ send_motion(channel);
+ }
+}
+
+/**
+ * spice_inputs_position:
+ * @channel: a #SpiceInputsChannel
+ * @x: X mouse coordinates
+ * @y: Y mouse coordinates
+ * @display: display channel id
+ * @button_state: SPICE_MOUSE_BUTTON_MASK flags
+ *
+ * Change mouse position (used in SPICE_MOUSE_MODE_CLIENT).
+ **/
+void spice_inputs_position(SpiceInputsChannel *channel, gint x, gint y,
+ gint display, gint button_state)
+{
+ SpiceInputsChannelPrivate *c;
+
+ g_return_if_fail(channel != NULL);
+
+ if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
+ return;
+
+ c = channel->priv;
+ c->bs = button_state;
+ c->x = x;
+ c->y = y;
+ c->dpy = display;
+
+ if (c->motion_count < SPICE_INPUT_MOTION_ACK_BUNCH * 2) {
+ send_position(channel);
+ } else {
+ CHANNEL_DEBUG(channel, "over SPICE_INPUT_MOTION_ACK_BUNCH * 2, dropping");
+ }
+}
+
+/**
+ * spice_inputs_button_press:
+ * @channel: a #SpiceInputsChannel
+ * @button: a SPICE_MOUSE_BUTTON
+ * @button_state: SPICE_MOUSE_BUTTON_MASK flags
+ *
+ * Press a mouse button.
+ **/
+void spice_inputs_button_press(SpiceInputsChannel *channel, gint button,
+ gint button_state)
+{
+ SpiceInputsChannelPrivate *c;
+ SpiceMsgcMousePress press;
+ SpiceMsgOut *msg;
+
+ g_return_if_fail(channel != NULL);
+
+ if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
+ return;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
+ c = channel->priv;
+ switch (button) {
+ case SPICE_MOUSE_BUTTON_LEFT:
+ button_state |= SPICE_MOUSE_BUTTON_MASK_LEFT;
+ break;
+ case SPICE_MOUSE_BUTTON_MIDDLE:
+ button_state |= SPICE_MOUSE_BUTTON_MASK_MIDDLE;
+ break;
+ case SPICE_MOUSE_BUTTON_RIGHT:
+ button_state |= SPICE_MOUSE_BUTTON_MASK_RIGHT;
+ break;
+ }
+
+ c->bs = button_state;
+ send_motion(channel);
+ send_position(channel);
+
+ msg = spice_msg_out_new(SPICE_CHANNEL(channel),
+ SPICE_MSGC_INPUTS_MOUSE_PRESS);
+ press.button = button;
+ press.buttons_state = button_state;
+ msg->marshallers->msgc_inputs_mouse_press(msg->marshaller, &press);
+ spice_msg_out_send(msg);
+}
+
+/**
+ * spice_inputs_button_release:
+ * @channel: a #SpiceInputsChannel
+ * @button: a SPICE_MOUSE_BUTTON
+ * @button_state: SPICE_MOUSE_BUTTON_MASK flags
+ *
+ * Release a button.
+ **/
+void spice_inputs_button_release(SpiceInputsChannel *channel, gint button,
+ gint button_state)
+{
+ SpiceInputsChannelPrivate *c;
+ SpiceMsgcMouseRelease release;
+ SpiceMsgOut *msg;
+
+ g_return_if_fail(channel != NULL);
+
+ if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
+ return;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
+ c = channel->priv;
+ switch (button) {
+ case SPICE_MOUSE_BUTTON_LEFT:
+ button_state &= ~SPICE_MOUSE_BUTTON_MASK_LEFT;
+ break;
+ case SPICE_MOUSE_BUTTON_MIDDLE:
+ button_state &= ~SPICE_MOUSE_BUTTON_MASK_MIDDLE;
+ break;
+ case SPICE_MOUSE_BUTTON_RIGHT:
+ button_state &= ~SPICE_MOUSE_BUTTON_MASK_RIGHT;
+ break;
+ }
+
+ c->bs = button_state;
+ send_motion(channel);
+ send_position(channel);
+
+ msg = spice_msg_out_new(SPICE_CHANNEL(channel),
+ SPICE_MSGC_INPUTS_MOUSE_RELEASE);
+ release.button = button;
+ release.buttons_state = button_state;
+ msg->marshallers->msgc_inputs_mouse_release(msg->marshaller, &release);
+ spice_msg_out_send(msg);
+}
+
+/**
+ * spice_inputs_key_press:
+ * @channel: a #SpiceInputsChannel
+ * @scancode: a PC XT (set 1) key scancode. For scancodes with an %0xe0
+ * prefix, drop the prefix and OR the scancode with %0x100.
+ *
+ * Press a key.
+ **/
+void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode)
+{
+ SpiceMsgcKeyDown down;
+ SpiceMsgOut *msg;
+
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_UNCONNECTED);
+ if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
+ return;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
+ down.code = spice_make_scancode(scancode, FALSE);
+ msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_INPUTS_KEY_DOWN);
+ msg->marshallers->msgc_inputs_key_down(msg->marshaller, &down);
+ spice_msg_out_send(msg);
+}
+
+/**
+ * spice_inputs_key_release:
+ * @channel: a #SpiceInputsChannel
+ * @scancode: a PC XT (set 1) key scancode. For scancodes with an %0xe0
+ * prefix, drop the prefix and OR the scancode with %0x100.
+ *
+ * Release a key.
+ **/
+void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode)
+{
+ SpiceMsgcKeyUp up;
+ SpiceMsgOut *msg;
+
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_UNCONNECTED);
+ if (SPICE_CHANNEL(channel)->priv->state != SPICE_CHANNEL_STATE_READY)
+ return;
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
+ up.code = spice_make_scancode(scancode, TRUE);
+ msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_INPUTS_KEY_UP);
+ msg->marshallers->msgc_inputs_key_up(msg->marshaller, &up);
+ spice_msg_out_send(msg);
+}
+
+/**
+ * spice_inputs_key_press_and_release:
+ * @channel: a #SpiceInputsChannel
+ * @scancode: a PC XT (set 1) key scancode. For scancodes with an %0xe0
+ * prefix, drop the prefix and OR the scancode with %0x100.
+ *
+ * Press and release a key event atomically (in the same message).
+ *
+ * Since: 0.13
+ **/
+void spice_inputs_key_press_and_release(SpiceInputsChannel *input_channel, guint scancode)
+{
+ SpiceChannel *channel = SPICE_CHANNEL(input_channel);
+
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(channel->priv->state != SPICE_CHANNEL_STATE_UNCONNECTED);
+
+ if (channel->priv->state != SPICE_CHANNEL_STATE_READY)
+ return;
+ if (spice_channel_get_read_only(channel))
+ return;
+
+ if (spice_channel_test_capability(channel, SPICE_INPUTS_CAP_KEY_SCANCODE)) {
+ SpiceMsgOut *msg;
+ guint16 code;
+ guint8 *buf;
+
+ msg = spice_msg_out_new(channel, SPICE_MSGC_INPUTS_KEY_SCANCODE);
+ if (scancode < 0x100) {
+ buf = (guint8*)spice_marshaller_reserve_space(msg->marshaller, 2);
+ buf[0] = spice_make_scancode(scancode, FALSE);
+ buf[1] = spice_make_scancode(scancode, TRUE);
+ } else {
+ buf = (guint8*)spice_marshaller_reserve_space(msg->marshaller, 4);
+ code = spice_make_scancode(scancode, FALSE);
+ buf[0] = code & 0xff;
+ buf[1] = code >> 8;
+ code = spice_make_scancode(scancode, TRUE);
+ buf[2] = code & 0xff;
+ buf[3] = code >> 8;
+ }
+ spice_msg_out_send(msg);
+ } else {
+ CHANNEL_DEBUG(channel, "The server doesn't support atomic press and release");
+ spice_inputs_key_press(input_channel, scancode);
+ spice_inputs_key_release(input_channel, scancode);
+ }
+}
+
+/* main or coroutine context */
+static SpiceMsgOut* set_key_locks(SpiceInputsChannel *channel, guint locks)
+{
+ SpiceMsgcKeyModifiers modifiers;
+ SpiceMsgOut *msg;
+ SpiceInputsChannelPrivate *ic;
+ SpiceChannelPrivate *c;
+
+ g_return_val_if_fail(SPICE_IS_INPUTS_CHANNEL(channel), NULL);
+
+ ic = channel->priv;
+ c = SPICE_CHANNEL(channel)->priv;
+
+ ic->locks = locks;
+ if (c->state != SPICE_CHANNEL_STATE_READY)
+ return NULL;
+
+ msg = spice_msg_out_new(SPICE_CHANNEL(channel),
+ SPICE_MSGC_INPUTS_KEY_MODIFIERS);
+ modifiers.modifiers = locks;
+ msg->marshallers->msgc_inputs_key_modifiers(msg->marshaller, &modifiers);
+ return msg;
+}
+
+/**
+ * spice_inputs_set_key_locks:
+ * @channel: a #SpiceInputsChannel
+ * @locks: #SpiceInputsLock modifiers flags
+ *
+ * Set the keyboard locks on the guest (Caps, Num, Scroll..)
+ **/
+void spice_inputs_set_key_locks(SpiceInputsChannel *channel, guint locks)
+{
+ SpiceMsgOut *msg;
+
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
+ msg = set_key_locks(channel, locks);
+ if (!msg) /* you can set_key_locks() even if the channel is not ready */
+ return;
+
+ spice_msg_out_send(msg); /* main -> coroutine */
+}
+
+/* coroutine context */
+static void spice_inputs_channel_up(SpiceChannel *channel)
+{
+ SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(channel)->priv;
+ SpiceMsgOut *msg;
+
+ if (spice_channel_get_read_only(channel))
+ return;
+
+ msg = set_key_locks(SPICE_INPUTS_CHANNEL(channel), c->locks);
+ spice_msg_out_send_internal(msg);
+}
+
+static void spice_inputs_channel_reset(SpiceChannel *channel, gboolean migrating)
+{
+ SpiceInputsChannelPrivate *c = SPICE_INPUTS_CHANNEL(channel)->priv;
+ c->motion_count = 0;
+
+ SPICE_CHANNEL_CLASS(spice_inputs_channel_parent_class)->channel_reset(channel, migrating);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_INPUTS_CHANNEL_H__
+#define __SPICE_CLIENT_INPUTS_CHANNEL_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_INPUTS_CHANNEL (spice_inputs_channel_get_type())
+#define SPICE_INPUTS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_INPUTS_CHANNEL, SpiceInputsChannel))
+#define SPICE_INPUTS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_INPUTS_CHANNEL, SpiceInputsChannelClass))
+#define SPICE_IS_INPUTS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_INPUTS_CHANNEL))
+#define SPICE_IS_INPUTS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_INPUTS_CHANNEL))
+#define SPICE_INPUTS_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_INPUTS_CHANNEL, SpiceInputsChannelClass))
+
+typedef struct _SpiceInputsChannel SpiceInputsChannel;
+typedef struct _SpiceInputsChannelClass SpiceInputsChannelClass;
+typedef struct _SpiceInputsChannelPrivate SpiceInputsChannelPrivate;
+
+/**
+ * SpiceInputsLock:
+ * @SPICE_INPUTS_SCROLL_LOCK: Scroll Lock
+ * @SPICE_INPUTS_NUM_LOCK: Num Lock
+ * @SPICE_INPUTS_CAPS_LOCK: Caps Lock
+ *
+ * Constants used to synchronize modifiers between a client and a guest.
+ **/
+typedef enum {
+ SPICE_INPUTS_SCROLL_LOCK = (1 << 0),
+ SPICE_INPUTS_NUM_LOCK = (1 << 1),
+ SPICE_INPUTS_CAPS_LOCK = (1 << 2)
+} SpiceInputsLock;
+
+/**
+ * SpiceInputsChannel:
+ *
+ * The #SpiceInputsChannel struct is opaque and should not be accessed directly.
+ */
+struct _SpiceInputsChannel {
+ SpiceChannel parent;
+
+ /*< private >*/
+ SpiceInputsChannelPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpiceInputsChannelClass:
+ * @parent_class: Parent class.
+ * @inputs_modifiers: Signal class handler for the #SpiceInputsChannel::inputs-modifiers signal.
+ *
+ * Class structure for #SpiceInputsChannel.
+ */
+struct _SpiceInputsChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*inputs_modifiers)(SpiceChannel *channel);
+
+ /*< private >*/
+ /* Do not add fields to this struct */
+};
+
+GType spice_inputs_channel_get_type(void);
+
+void spice_inputs_motion(SpiceInputsChannel *channel, gint dx, gint dy,
+ gint button_state);
+void spice_inputs_position(SpiceInputsChannel *channel, gint x, gint y,
+ gint display, gint button_state);
+void spice_inputs_button_press(SpiceInputsChannel *channel, gint button,
+ gint button_state);
+void spice_inputs_button_release(SpiceInputsChannel *channel, gint button,
+ gint button_state);
+void spice_inputs_key_press(SpiceInputsChannel *channel, guint scancode);
+void spice_inputs_key_release(SpiceInputsChannel *channel, guint scancode);
+void spice_inputs_set_key_locks(SpiceInputsChannel *channel, guint locks);
+void spice_inputs_key_press_and_release(SpiceInputsChannel *channel, guint scancode);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_INPUTS_CHANNEL_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <math.h>
+#include <spice/vd_agent.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n-lib.h>
+
+#include "spice-client.h"
+#include "spice-common.h"
+#include "spice-marshal.h"
+
+#include "spice-util-priv.h"
+#include "spice-channel-priv.h"
+#include "spice-session-priv.h"
+#include "spice-audio-priv.h"
+#include "spice-file-transfer-task-priv.h"
+
+/**
+ * SECTION:channel-main
+ * @short_description: the main Spice channel
+ * @title: Main Channel
+ * @section_id:
+ * @see_also: #SpiceChannel, and the GTK widget #SpiceDisplay
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * The main channel is the Spice session control channel. It handles
+ * communication initialization (channels list), migrations, mouse
+ * modes, multimedia time, and agent communication.
+ *
+ *
+ */
+
+#define SPICE_MAIN_CHANNEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_MAIN_CHANNEL, SpiceMainChannelPrivate))
+
+#define MAX_DISPLAY 16 /* Note must fit in a guint32, see monitors_align */
+
+typedef struct spice_migrate spice_migrate;
+
+typedef enum {
+ DISPLAY_UNDEFINED,
+ DISPLAY_DISABLED,
+ DISPLAY_ENABLED,
+} SpiceDisplayState;
+
+typedef struct {
+ int x;
+ int y;
+ int width;
+ int height;
+ SpiceDisplayState display_state;
+} SpiceDisplayConfig;
+
+typedef struct {
+ GHashTable *xfer_task;
+ SpiceMainChannel *channel;
+ GFileProgressCallback progress_callback;
+ gpointer progress_callback_data;
+ GTask *task;
+ struct {
+ goffset total_sent;
+ goffset transfer_size;
+ guint num_files;
+ guint succeed;
+ guint cancelled;
+ guint failed;
+ } stats;
+} FileTransferOperation;
+
+struct _SpiceMainChannelPrivate {
+ enum SpiceMouseMode mouse_mode;
+ enum SpiceMouseMode requested_mouse_mode;
+ bool agent_connected;
+ bool agent_caps_received;
+
+ gboolean agent_display_config_sent;
+ guint8 display_color_depth;
+ gboolean display_disable_wallpaper:1;
+ gboolean display_disable_font_smooth:1;
+ gboolean display_disable_animation:1;
+ gboolean disable_display_position:1;
+ gboolean disable_display_align:1;
+
+ int agent_tokens;
+ VDAgentMessage agent_msg; /* partial msg reconstruction */
+ guint8 *agent_msg_data;
+ guint agent_msg_pos;
+ uint8_t agent_msg_size;
+ uint32_t agent_caps[VD_AGENT_CAPS_SIZE];
+ SpiceDisplayConfig display[MAX_DISPLAY];
+ gint timer_id;
+ GQueue *agent_msg_queue;
+ GHashTable *file_xfer_tasks;
+ GHashTable *flushing;
+
+ guint switch_host_delayed_id;
+ guint migrate_delayed_id;
+ spice_migrate *migrate_data;
+ int max_clipboard;
+
+ gboolean agent_volume_playback_sync;
+ gboolean agent_volume_record_sync;
+ GCancellable *cancellable_volume_info;
+};
+
+struct spice_migrate {
+ struct coroutine *from;
+ SpiceMigrationDstInfo *info;
+ SpiceSession *session;
+ guint nchannels;
+ SpiceChannel *src_channel;
+ SpiceChannel *dst_channel;
+ bool do_seamless; /* used as input and output for the seamless migration handshake.
+ input: whether to send to the dest SPICE_MSGC_MAIN_MIGRATE_DST_DO_SEAMLESS
+ output: whether the dest approved seamless migration
+ (SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK/NACK)
+ */
+ uint32_t src_mig_version;
+};
+
+G_DEFINE_TYPE(SpiceMainChannel, spice_main_channel, SPICE_TYPE_CHANNEL)
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_MOUSE_MODE,
+ PROP_AGENT_CONNECTED,
+ PROP_AGENT_CAPS_0,
+ PROP_DISPLAY_DISABLE_WALLPAPER,
+ PROP_DISPLAY_DISABLE_FONT_SMOOTH,
+ PROP_DISPLAY_DISABLE_ANIMATION,
+ PROP_DISPLAY_COLOR_DEPTH,
+ PROP_DISABLE_DISPLAY_POSITION,
+ PROP_DISABLE_DISPLAY_ALIGN,
+ PROP_MAX_CLIPBOARD,
+};
+
+/* Signals */
+enum {
+ SPICE_MAIN_MOUSE_UPDATE,
+ SPICE_MAIN_AGENT_UPDATE,
+ SPICE_MAIN_CLIPBOARD,
+ SPICE_MAIN_CLIPBOARD_GRAB,
+ SPICE_MAIN_CLIPBOARD_REQUEST,
+ SPICE_MAIN_CLIPBOARD_RELEASE,
+ SPICE_MAIN_CLIPBOARD_SELECTION,
+ SPICE_MAIN_CLIPBOARD_SELECTION_GRAB,
+ SPICE_MAIN_CLIPBOARD_SELECTION_REQUEST,
+ SPICE_MAIN_CLIPBOARD_SELECTION_RELEASE,
+ SPICE_MIGRATION_STARTED,
+ SPICE_MAIN_NEW_FILE_TRANSFER,
+ SPICE_MAIN_LAST_SIGNAL,
+};
+
+static guint signals[SPICE_MAIN_LAST_SIGNAL];
+
+static void spice_main_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
+static void channel_set_handlers(SpiceChannelClass *klass);
+static void agent_send_msg_queue(SpiceMainChannel *channel);
+static void agent_free_msg_queue(SpiceMainChannel *channel);
+static void migrate_channel_event_cb(SpiceChannel *channel, SpiceChannelEvent event,
+ gpointer data);
+static gboolean main_migrate_handshake_done(gpointer data);
+static void spice_main_channel_send_migration_handshake(SpiceChannel *channel);
+static void file_xfer_flushed(SpiceMainChannel *channel, gboolean success);
+static void file_xfer_read_async_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data);
+static void spice_main_set_max_clipboard(SpiceMainChannel *self, gint max);
+static void set_agent_connected(SpiceMainChannel *channel, gboolean connected);
+
+static void file_transfer_operation_free(FileTransferOperation *xfer_op);
+static void spice_main_channel_reset_all_xfer_operations(SpiceMainChannel *channel);
+static SpiceFileTransferTask *spice_main_channel_find_xfer_task_by_task_id(SpiceMainChannel *channel,
+ guint32 task_id);
+static void file_transfer_operation_task_finished(SpiceFileTransferTask *xfer_task,
+ GError *error,
+ gpointer userdata);
+static void file_transfer_operation_send_progress(SpiceFileTransferTask *xfer_task);
+
+/* ------------------------------------------------------------------ */
+
+static const char *agent_msg_types[] = {
+ [ VD_AGENT_MOUSE_STATE ] = "mouse state",
+ [ VD_AGENT_MONITORS_CONFIG ] = "monitors config",
+ [ VD_AGENT_REPLY ] = "reply",
+ [ VD_AGENT_CLIPBOARD ] = "clipboard",
+ [ VD_AGENT_DISPLAY_CONFIG ] = "display config",
+ [ VD_AGENT_ANNOUNCE_CAPABILITIES ] = "announce caps",
+ [ VD_AGENT_CLIPBOARD_GRAB ] = "clipboard grab",
+ [ VD_AGENT_CLIPBOARD_REQUEST ] = "clipboard request",
+ [ VD_AGENT_CLIPBOARD_RELEASE ] = "clipboard release",
+ [ VD_AGENT_AUDIO_VOLUME_SYNC ] = "volume-sync",
+};
+
+static const char *agent_caps[] = {
+ [ VD_AGENT_CAP_MOUSE_STATE ] = "mouse state",
+ [ VD_AGENT_CAP_MONITORS_CONFIG ] = "monitors config",
+ [ VD_AGENT_CAP_REPLY ] = "reply",
+ [ VD_AGENT_CAP_CLIPBOARD ] = "clipboard (old)",
+ [ VD_AGENT_CAP_DISPLAY_CONFIG ] = "display config",
+ [ VD_AGENT_CAP_CLIPBOARD_BY_DEMAND ] = "clipboard",
+ [ VD_AGENT_CAP_CLIPBOARD_SELECTION ] = "clipboard selection",
+ [ VD_AGENT_CAP_SPARSE_MONITORS_CONFIG ] = "sparse monitors",
+ [ VD_AGENT_CAP_GUEST_LINEEND_LF ] = "line-end lf",
+ [ VD_AGENT_CAP_GUEST_LINEEND_CRLF ] = "line-end crlf",
+ [ VD_AGENT_CAP_MAX_CLIPBOARD ] = "max-clipboard",
+ [ VD_AGENT_CAP_AUDIO_VOLUME_SYNC ] = "volume-sync",
+ [ VD_AGENT_CAP_MONITORS_CONFIG_POSITION ] = "monitors config position",
+};
+#define NAME(_a, _i) ((_i) < SPICE_N_ELEMENTS(_a) ? (_a[(_i)] ?: "?") : "?")
+
+/* ------------------------------------------------------------------ */
+
+static gboolean test_agent_cap(SpiceMainChannel *channel, guint32 cap)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+
+ if (!c->agent_caps_received)
+ return FALSE;
+
+ return VD_AGENT_HAS_CAPABILITY(c->agent_caps, G_N_ELEMENTS(c->agent_caps), cap);
+}
+
+static void spice_main_channel_reset_capabilties(SpiceChannel *channel)
+{
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE);
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_MAIN_CAP_NAME_AND_UUID);
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_MAIN_CAP_AGENT_CONNECTED_TOKENS);
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_MAIN_CAP_SEAMLESS_MIGRATE);
+}
+
+static void spice_main_channel_init(SpiceMainChannel *channel)
+{
+ SpiceMainChannelPrivate *c;
+
+ c = channel->priv = SPICE_MAIN_CHANNEL_GET_PRIVATE(channel);
+ c->agent_msg_queue = g_queue_new();
+ c->file_xfer_tasks = g_hash_table_new(g_direct_hash, g_direct_equal);
+ c->flushing = g_hash_table_new(g_direct_hash, g_direct_equal);
+ c->cancellable_volume_info = g_cancellable_new();
+
+ spice_main_channel_reset_capabilties(SPICE_CHANNEL(channel));
+ c->requested_mouse_mode = SPICE_MOUSE_MODE_CLIENT;
+}
+
+static gint spice_main_get_max_clipboard(SpiceMainChannel *self)
+{
+ g_return_val_if_fail(SPICE_IS_MAIN_CHANNEL(self), 0);
+
+ if (g_getenv("SPICE_MAX_CLIPBOARD"))
+ return atoi(g_getenv("SPICE_MAX_CLIPBOARD"));
+
+ return self->priv->max_clipboard;
+}
+
+static void spice_main_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceMainChannel *self = SPICE_MAIN_CHANNEL(object);
+ SpiceMainChannelPrivate *c = self->priv;
+
+ switch (prop_id) {
+ case PROP_MOUSE_MODE:
+ g_value_set_int(value, c->mouse_mode);
+ break;
+ case PROP_AGENT_CONNECTED:
+ g_value_set_boolean(value, c->agent_connected);
+ break;
+ case PROP_AGENT_CAPS_0:
+ g_value_set_int(value, c->agent_caps[0]);
+ break;
+ case PROP_DISPLAY_DISABLE_WALLPAPER:
+ g_value_set_boolean(value, c->display_disable_wallpaper);
+ break;
+ case PROP_DISPLAY_DISABLE_FONT_SMOOTH:
+ g_value_set_boolean(value, c->display_disable_font_smooth);
+ break;
+ case PROP_DISPLAY_DISABLE_ANIMATION:
+ g_value_set_boolean(value, c->display_disable_animation);
+ break;
+ case PROP_DISPLAY_COLOR_DEPTH:
+ g_value_set_uint(value, c->display_color_depth);
+ break;
+ case PROP_DISABLE_DISPLAY_POSITION:
+ g_value_set_boolean(value, c->disable_display_position);
+ break;
+ case PROP_DISABLE_DISPLAY_ALIGN:
+ g_value_set_boolean(value, c->disable_display_align);
+ break;
+ case PROP_MAX_CLIPBOARD:
+ g_value_set_int(value, spice_main_get_max_clipboard(self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_main_set_property(GObject *gobject, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ SpiceMainChannel *self = SPICE_MAIN_CHANNEL(gobject);
+ SpiceMainChannelPrivate *c = self->priv;
+
+ switch (prop_id) {
+ case PROP_DISPLAY_DISABLE_WALLPAPER:
+ c->display_disable_wallpaper = g_value_get_boolean(value);
+ break;
+ case PROP_DISPLAY_DISABLE_FONT_SMOOTH:
+ c->display_disable_font_smooth = g_value_get_boolean(value);
+ break;
+ case PROP_DISPLAY_DISABLE_ANIMATION:
+ c->display_disable_animation = g_value_get_boolean(value);
+ break;
+ case PROP_DISPLAY_COLOR_DEPTH: {
+ guint color_depth = g_value_get_uint(value);
+ g_return_if_fail(color_depth % 8 == 0);
+ c->display_color_depth = color_depth;
+ break;
+ }
+ case PROP_DISABLE_DISPLAY_POSITION:
+ c->disable_display_position = g_value_get_boolean(value);
+ break;
+ case PROP_DISABLE_DISPLAY_ALIGN:
+ c->disable_display_align = g_value_get_boolean(value);
+ break;
+ case PROP_MAX_CLIPBOARD:
+ spice_main_set_max_clipboard(self, g_value_get_int(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_main_channel_dispose(GObject *obj)
+{
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(obj)->priv;
+
+ if (c->timer_id) {
+ g_source_remove(c->timer_id);
+ c->timer_id = 0;
+ }
+
+ if (c->switch_host_delayed_id) {
+ g_source_remove(c->switch_host_delayed_id);
+ c->switch_host_delayed_id = 0;
+ }
+
+ if (c->migrate_delayed_id) {
+ g_source_remove(c->migrate_delayed_id);
+ c->migrate_delayed_id = 0;
+ }
+
+ g_clear_pointer(&c->file_xfer_tasks, g_hash_table_unref);
+ g_clear_pointer (&c->flushing, g_hash_table_unref);
+
+ g_cancellable_cancel(c->cancellable_volume_info);
+ g_clear_object(&c->cancellable_volume_info);
+
+ if (G_OBJECT_CLASS(spice_main_channel_parent_class)->dispose)
+ G_OBJECT_CLASS(spice_main_channel_parent_class)->dispose(obj);
+}
+
+static void spice_main_channel_finalize(GObject *obj)
+{
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(obj)->priv;
+
+ g_free(c->agent_msg_data);
+ agent_free_msg_queue(SPICE_MAIN_CHANNEL(obj));
+
+ if (G_OBJECT_CLASS(spice_main_channel_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_main_channel_parent_class)->finalize(obj);
+}
+
+/* coroutine context */
+static void spice_channel_iterate_write(SpiceChannel *channel)
+{
+ agent_send_msg_queue(SPICE_MAIN_CHANNEL(channel));
+
+ if (SPICE_CHANNEL_CLASS(spice_main_channel_parent_class)->iterate_write)
+ SPICE_CHANNEL_CLASS(spice_main_channel_parent_class)->iterate_write(channel);
+}
+
+/* main or coroutine context */
+static void spice_main_channel_reset_agent(SpiceMainChannel *channel)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+
+ c->agent_connected = FALSE;
+ c->agent_caps_received = FALSE;
+ c->agent_display_config_sent = FALSE;
+ c->agent_msg_pos = 0;
+ g_clear_pointer(&c->agent_msg_data, g_free);
+ c->agent_msg_size = 0;
+
+ spice_main_channel_reset_all_xfer_operations(channel);
+ file_xfer_flushed(channel, FALSE);
+}
+
+/* main or coroutine context */
+static void spice_main_channel_reset(SpiceChannel *channel, gboolean migrating)
+{
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
+
+ /* This is not part of reset_agent, since the spice-server expects any
+ pending multi-chunk messages to be completed by the client, even after
+ it has send an agent-disconnected msg as that is what the original
+ spicec did. Also see the TODO in server/reds.c reds_reset_vdp() */
+ c->agent_tokens = 0;
+ agent_free_msg_queue(SPICE_MAIN_CHANNEL(channel));
+ c->agent_msg_queue = g_queue_new();
+
+ c->agent_volume_playback_sync = FALSE;
+ c->agent_volume_record_sync = FALSE;
+
+ set_agent_connected(SPICE_MAIN_CHANNEL(channel), FALSE);
+
+ SPICE_CHANNEL_CLASS(spice_main_channel_parent_class)->channel_reset(channel, migrating);
+}
+
+static void spice_main_constructed(GObject *object)
+{
+ SpiceMainChannel *self = SPICE_MAIN_CHANNEL(object);
+ SpiceMainChannelPrivate *c = self->priv;
+
+ /* update default value */
+ c->max_clipboard = spice_main_get_max_clipboard(self);
+
+ if (G_OBJECT_CLASS(spice_main_channel_parent_class)->constructed)
+ G_OBJECT_CLASS(spice_main_channel_parent_class)->constructed(object);
+}
+
+static void spice_main_channel_class_init(SpiceMainChannelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
+
+ gobject_class->dispose = spice_main_channel_dispose;
+ gobject_class->finalize = spice_main_channel_finalize;
+ gobject_class->get_property = spice_main_get_property;
+ gobject_class->set_property = spice_main_set_property;
+ gobject_class->constructed = spice_main_constructed;
+
+ channel_class->handle_msg = spice_main_handle_msg;
+ channel_class->iterate_write = spice_channel_iterate_write;
+ channel_class->channel_reset = spice_main_channel_reset;
+ channel_class->channel_reset_capabilities = spice_main_channel_reset_capabilties;
+ channel_class->channel_send_migration_handshake = spice_main_channel_send_migration_handshake;
+
+ /**
+ * SpiceMainChannel:mouse-mode:
+ *
+ * Spice protocol specifies two mouse modes, client mode and
+ * server mode. In client mode (%SPICE_MOUSE_MODE_CLIENT), the
+ * affective mouse is the client side mouse: the client sends
+ * mouse position within the display and the server sends mouse
+ * shape messages. In server mode (%SPICE_MOUSE_MODE_SERVER), the
+ * client sends relative mouse movements and the server sends
+ * position and shape commands.
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_MOUSE_MODE,
+ g_param_spec_int("mouse-mode",
+ "Mouse mode",
+ "Mouse mode",
+ 0, INT_MAX, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ g_object_class_install_property
+ (gobject_class, PROP_AGENT_CONNECTED,
+ g_param_spec_boolean("agent-connected",
+ "Agent connected",
+ "Whether the agent is connected",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ g_object_class_install_property
+ (gobject_class, PROP_AGENT_CAPS_0,
+ g_param_spec_int("agent-caps-0",
+ "Agent caps 0",
+ "Agent capability bits 0 -> 31",
+ 0, INT_MAX, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
+ g_object_class_install_property
+ (gobject_class, PROP_DISPLAY_DISABLE_WALLPAPER,
+ g_param_spec_boolean("disable-wallpaper",
+ "Disable guest wallpaper",
+ "Disable guest wallpaper",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_DISPLAY_DISABLE_FONT_SMOOTH,
+ g_param_spec_boolean("disable-font-smooth",
+ "Disable guest font smooth",
+ "Disable guest font smoothing",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_DISPLAY_DISABLE_ANIMATION,
+ g_param_spec_boolean("disable-animation",
+ "Disable guest animations",
+ "Disable guest animations",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_DISABLE_DISPLAY_POSITION,
+ g_param_spec_boolean("disable-display-position",
+ "Disable display position",
+ "Disable using display position when setting monitor config",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_DISPLAY_COLOR_DEPTH,
+ g_param_spec_uint("color-depth",
+ "Color depth",
+ "Color depth", 0, 32, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceMainChannel:disable-display-align:
+ *
+ * Disable automatic horizontal display position alignment.
+ *
+ * Since: 0.13
+ */
+ g_object_class_install_property
+ (gobject_class, PROP_DISABLE_DISPLAY_ALIGN,
+ g_param_spec_boolean("disable-display-align",
+ "Disable display align",
+ "Disable display position alignment",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceMainChannel:max-clipboard:
+ *
+ * Maximum size of clipboard operations in bytes (default 100MB,
+ * -1 for unlimited size);
+ *
+ * Since: 0.22
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_MAX_CLIPBOARD,
+ g_param_spec_int("max-clipboard",
+ "max clipboard",
+ "Maximum clipboard data size",
+ -1, G_MAXINT, 100 * 1024 * 1024,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /* TODO use notify instead */
+ /**
+ * SpiceMainChannel::main-mouse-update:
+ * @main: the #SpiceMainChannel that emitted the signal
+ *
+ * Notify when the mouse mode has changed.
+ **/
+ signals[SPICE_MAIN_MOUSE_UPDATE] =
+ g_signal_new("main-mouse-update",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceMainChannelClass, mouse_update),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ /* TODO use notify instead */
+ /**
+ * SpiceMainChannel::main-agent-update:
+ * @main: the #SpiceMainChannel that emitted the signal
+ *
+ * Notify when the %SpiceMainChannel:agent-connected or
+ * %SpiceMainChannel:agent-caps-0 property change.
+ **/
+ signals[SPICE_MAIN_AGENT_UPDATE] =
+ g_signal_new("main-agent-update",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceMainChannelClass, agent_update),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+ /**
+ * SpiceMainChannel::main-clipboard:
+ * @main: the #SpiceMainChannel that emitted the signal
+ * @type: the VD_AGENT_CLIPBOARD data type
+ * @data: clipboard data
+ * @size: size of @data in bytes
+ *
+ * Provides guest clipboard data requested by spice_main_clipboard_request().
+ *
+ * Deprecated: 0.6: use SpiceMainChannel::main-clipboard-selection instead.
+ **/
+ signals[SPICE_MAIN_CLIPBOARD] =
+ g_signal_new("main-clipboard",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
+ 0,
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__UINT_POINTER_UINT,
+ G_TYPE_NONE,
+ 3,
+ G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_UINT);
+
+ /**
+ * SpiceMainChannel::main-clipboard-selection:
+ * @main: the #SpiceMainChannel that emitted the signal
+ * @selection: a VD_AGENT_CLIPBOARD_SELECTION clipboard
+ * @type: the VD_AGENT_CLIPBOARD data type
+ * @data: clipboard data
+ * @size: size of @data in bytes
+ *
+ * Informs that clipboard selection data are available.
+ *
+ * Since: 0.6
+ **/
+ signals[SPICE_MAIN_CLIPBOARD_SELECTION] =
+ g_signal_new("main-clipboard-selection",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__UINT_UINT_POINTER_UINT,
+ G_TYPE_NONE,
+ 4,
+ G_TYPE_UINT, G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_UINT);
+
+ /**
+ * SpiceMainChannel::main-clipboard-grab:
+ * @main: the #SpiceMainChannel that emitted the signal
+ * @types: the VD_AGENT_CLIPBOARD data types
+ * @ntypes: the number of @types
+ *
+ * Inform when clipboard data is available from the guest, and for
+ * which @types.
+ *
+ * Deprecated: 0.6: use SpiceMainChannel::main-clipboard-selection-grab instead.
+ **/
+ signals[SPICE_MAIN_CLIPBOARD_GRAB] =
+ g_signal_new("main-clipboard-grab",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
+ 0,
+ NULL, NULL,
+ g_cclosure_user_marshal_BOOLEAN__POINTER_UINT,
+ G_TYPE_BOOLEAN,
+ 2,
+ G_TYPE_POINTER, G_TYPE_UINT);
+
+ /**
+ * SpiceMainChannel::main-clipboard-selection-grab:
+ * @main: the #SpiceMainChannel that emitted the signal
+ * @selection: a VD_AGENT_CLIPBOARD_SELECTION clipboard
+ * @types: the VD_AGENT_CLIPBOARD data types
+ * @ntypes: the number of @types
+ *
+ * Inform when clipboard data is available from the guest, and for
+ * which @types.
+ *
+ * Since: 0.6
+ **/
+ signals[SPICE_MAIN_CLIPBOARD_SELECTION_GRAB] =
+ g_signal_new("main-clipboard-selection-grab",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_user_marshal_BOOLEAN__UINT_POINTER_UINT,
+ G_TYPE_BOOLEAN,
+ 3,
+ G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_UINT);
+
+ /**
+ * SpiceMainChannel::main-clipboard-request:
+ * @main: the #SpiceMainChannel that emitted the signal
+ * @types: the VD_AGENT_CLIPBOARD request type
+ *
+ * Request clipboard data from the client.
+ *
+ * Return value: %TRUE if the request is successful
+ *
+ * Deprecated: 0.6: use SpiceMainChannel::main-clipboard-selection-request instead.
+ **/
+ signals[SPICE_MAIN_CLIPBOARD_REQUEST] =
+ g_signal_new("main-clipboard-request",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
+ 0,
+ NULL, NULL,
+ g_cclosure_user_marshal_BOOLEAN__UINT,
+ G_TYPE_BOOLEAN,
+ 1,
+ G_TYPE_UINT);
+
+ /**
+ * SpiceMainChannel::main-clipboard-selection-request:
+ * @main: the #SpiceMainChannel that emitted the signal
+ * @selection: a VD_AGENT_CLIPBOARD_SELECTION clipboard
+ * @types: the VD_AGENT_CLIPBOARD request type
+ *
+ * Request clipboard data from the client.
+ *
+ * Return value: %TRUE if the request is successful
+ *
+ * Since: 0.6
+ **/
+ signals[SPICE_MAIN_CLIPBOARD_SELECTION_REQUEST] =
+ g_signal_new("main-clipboard-selection-request",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_user_marshal_BOOLEAN__UINT_UINT,
+ G_TYPE_BOOLEAN,
+ 2,
+ G_TYPE_UINT, G_TYPE_UINT);
+
+ /**
+ * SpiceMainChannel::main-clipboard-release:
+ * @main: the #SpiceMainChannel that emitted the signal
+ *
+ * Inform when the clipboard is released from the guest, when no
+ * clipboard data is available from the guest.
+ *
+ * Deprecated: 0.6: use SpiceMainChannel::main-clipboard-selection-release instead.
+ **/
+ signals[SPICE_MAIN_CLIPBOARD_RELEASE] =
+ g_signal_new("main-clipboard-release",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DEPRECATED,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ /**
+ * SpiceMainChannel::main-clipboard-selection-release:
+ * @main: the #SpiceMainChannel that emitted the signal
+ * @selection: a VD_AGENT_CLIPBOARD_SELECTION clipboard
+ *
+ * Inform when the clipboard is released from the guest, when no
+ * clipboard data is available from the guest.
+ *
+ * Since: 0.6
+ **/
+ signals[SPICE_MAIN_CLIPBOARD_SELECTION_RELEASE] =
+ g_signal_new("main-clipboard-selection-release",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_UINT);
+
+ /**
+ * SpiceMainChannel::migration-started:
+ * @main: the #SpiceMainChannel that emitted the signal
+ * @session: a migration #SpiceSession
+ *
+ * Inform when migration is starting. Application wishing to make
+ * connections themself can set the #SpiceSession:client-sockets
+ * to @TRUE, then follow #SpiceSession::channel-new creation, and
+ * use spice_channel_open_fd() once the socket is created.
+ *
+ **/
+ signals[SPICE_MIGRATION_STARTED] =
+ g_signal_new("migration-started",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_OBJECT);
+
+ /**
+ * SpiceMainChannel::new-file-transfer:
+ * @main: the #SpiceMainChannel that emitted the signal
+ * @task: a #SpiceFileTransferTask
+ *
+ * This signal is emitted when a new file transfer task has been initiated
+ * on this channel. Client applications may take a reference on the @task
+ * object and use it to monitor the status of the file transfer task.
+ *
+ * Since: 0.31
+ **/
+ signals[SPICE_MAIN_NEW_FILE_TRANSFER] =
+ g_signal_new("new-file-transfer",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_OBJECT);
+
+ g_type_class_add_private(klass, sizeof(SpiceMainChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
+}
+
+/* ------------------------------------------------------------------ */
+
+
+static void agent_free_msg_queue(SpiceMainChannel *channel)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+ SpiceMsgOut *out;
+
+ if (!c->agent_msg_queue)
+ return;
+
+ while (!g_queue_is_empty(c->agent_msg_queue)) {
+ out = g_queue_pop_head(c->agent_msg_queue);
+ spice_msg_out_unref(out);
+ }
+
+ g_clear_pointer(&c->agent_msg_queue, g_queue_free);
+}
+
+static gboolean flush_foreach_remove(gpointer key G_GNUC_UNUSED,
+ gpointer value, gpointer user_data)
+{
+ gboolean success = GPOINTER_TO_UINT(user_data);
+ GTask *result = value;
+ g_task_return_boolean(result, success);
+
+ return TRUE;
+}
+
+static void file_xfer_flushed(SpiceMainChannel *channel, gboolean success)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+ g_hash_table_foreach_remove(c->flushing, flush_foreach_remove,
+ GUINT_TO_POINTER(success));
+}
+
+static void file_xfer_flush_async(SpiceFileTransferTask *xfer_task,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ SpiceMainChannel *channel;
+ SpiceMainChannelPrivate *c;
+ gboolean was_empty;
+
+ channel = spice_file_transfer_task_get_channel(xfer_task);
+ task = g_task_new(xfer_task,
+ spice_file_transfer_task_get_cancellable(xfer_task),
+ callback,
+ user_data);
+
+ c = channel->priv;
+ was_empty = g_queue_is_empty(c->agent_msg_queue);
+ if (was_empty) {
+ g_task_return_boolean(task, TRUE);
+ g_object_unref(task);
+ return;
+ }
+
+ /* wait until the last message currently in the queue has been sent */
+ g_hash_table_insert(c->flushing, g_queue_peek_tail(c->agent_msg_queue), task);
+}
+
+static gboolean file_xfer_flush_finish(SpiceFileTransferTask *xfer_task,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = G_TASK(result);
+
+ g_return_val_if_fail(g_task_is_valid(result, xfer_task), FALSE);
+
+ return g_task_propagate_boolean(task, error);
+}
+
+/* coroutine context */
+static void agent_send_msg_queue(SpiceMainChannel *channel)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+ SpiceMsgOut *out;
+
+ while (c->agent_tokens > 0 &&
+ !g_queue_is_empty(c->agent_msg_queue)) {
+ GTask *task;
+ c->agent_tokens--;
+ out = g_queue_pop_head(c->agent_msg_queue);
+ spice_msg_out_send_internal(out);
+
+ task = g_hash_table_lookup(c->flushing, out);
+ if (task) {
+ /* if there's a flush task waiting for this message, finish it */
+ g_task_return_boolean(task, TRUE);
+ g_object_unref(task);
+ g_hash_table_remove(c->flushing, out);
+ }
+ }
+ if (g_queue_is_empty(c->agent_msg_queue) &&
+ g_hash_table_size(c->flushing) != 0) {
+ g_warning("unexpected flush task in list, clearing");
+ file_xfer_flushed(channel, TRUE);
+ }
+}
+
+/* any context: the message is not flushed immediately,
+ you can wakeup() the channel coroutine or send_msg_queue()
+
+ expected arguments, pair of data/data_size to send terminated with NULL:
+ agent_msg_queue_many(main, VD_AGENT_...,
+ &foo, sizeof(Foo),
+ data, data_size, NULL);
+*/
+G_GNUC_NULL_TERMINATED
+static void agent_msg_queue_many(SpiceMainChannel *channel, int type, const void *data, ...)
+{
+ va_list args;
+ SpiceMainChannelPrivate *c = channel->priv;
+ SpiceMsgOut *out;
+ VDAgentMessage msg;
+ guint8 *payload;
+ gsize paysize, s, mins, size = 0;
+ const guint8 *d;
+
+ G_STATIC_ASSERT(VD_AGENT_MAX_DATA_SIZE > sizeof(VDAgentMessage));
+
+ va_start(args, data);
+ for (d = data; d != NULL; d = va_arg(args, void*)) {
+ size += va_arg(args, gsize);
+ }
+ va_end(args);
+
+ msg.protocol = VD_AGENT_PROTOCOL;
+ msg.type = type;
+ msg.opaque = 0;
+ msg.size = size;
+
+ paysize = MIN(VD_AGENT_MAX_DATA_SIZE, size + sizeof(VDAgentMessage));
+ out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MAIN_AGENT_DATA);
+ payload = spice_marshaller_reserve_space(out->marshaller, paysize);
+ memcpy(payload, &msg, sizeof(VDAgentMessage));
+ payload += sizeof(VDAgentMessage);
+ paysize -= sizeof(VDAgentMessage);
+ if (paysize == 0) {
+ g_queue_push_tail(c->agent_msg_queue, out);
+ out = NULL;
+ }
+
+ va_start(args, data);
+ for (d = data; size > 0; d = va_arg(args, void*)) {
+ s = va_arg(args, gsize);
+ while (s > 0) {
+ if (out == NULL) {
+ paysize = MIN(VD_AGENT_MAX_DATA_SIZE, size);
+ out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MAIN_AGENT_DATA);
+ payload = spice_marshaller_reserve_space(out->marshaller, paysize);
+ }
+ mins = MIN(paysize, s);
+ memcpy(payload, d, mins);
+ d += mins;
+ payload += mins;
+ s -= mins;
+ size -= mins;
+ paysize -= mins;
+ if (paysize == 0) {
+ g_queue_push_tail(c->agent_msg_queue, out);
+ out = NULL;
+ }
+ }
+ }
+ va_end(args);
+ g_warn_if_fail(out == NULL);
+}
+
+static int monitors_cmp(const void *p1, const void *p2, gpointer user_data)
+{
+ const VDAgentMonConfig *m1 = p1;
+ const VDAgentMonConfig *m2 = p2;
+ double d1 = sqrt(m1->x * m1->x + m1->y * m1->y);
+ double d2 = sqrt(m2->x * m2->x + m2->y * m2->y);
+ int diff = d1 - d2;
+
+ return diff == 0 ? (char*)p1 - (char*)p2 : diff;
+}
+
+static void monitors_align(VDAgentMonConfig *monitors, int nmonitors)
+{
+ gint i, j, x = 0;
+ guint32 used = 0;
+ VDAgentMonConfig *sorted_monitors;
+
+ if (nmonitors == 0)
+ return;
+
+ /* sort by distance from origin */
+ sorted_monitors = g_memdup(monitors, nmonitors * sizeof(VDAgentMonConfig));
+ g_qsort_with_data(sorted_monitors, nmonitors, sizeof(VDAgentMonConfig), monitors_cmp, NULL);
+
+ /* super-KISS ltr alignment, feel free to improve */
+ for (i = 0; i < nmonitors; i++) {
+ /* Find where this monitor is in the sorted order */
+ for (j = 0; j < nmonitors; j++) {
+ /* Avoid using the same entry twice, this happens with older
+ virt-viewer versions which always set x and y to 0 */
+ if (used & (1 << j))
+ continue;
+ if (memcmp(&monitors[j], &sorted_monitors[i],
+ sizeof(VDAgentMonConfig)) == 0)
+ break;
+ }
+ used |= 1 << j;
+ monitors[j].x = x;
+ monitors[j].y = 0;
+ x += monitors[j].width;
+ if (monitors[j].width || monitors[j].height)
+ SPICE_DEBUG("#%d +%d+%d-%ux%u", j, monitors[j].x, monitors[j].y,
+ monitors[j].width, monitors[j].height);
+ }
+ g_free(sorted_monitors);
+}
+
+
+#define agent_msg_queue(Channel, Type, Size, Data) \
+ agent_msg_queue_many((Channel), (Type), (Data), (Size), NULL)
+
+/**
+ * spice_main_send_monitor_config:
+ * @channel: a #SpiceMainChannel
+ *
+ * Send monitors configuration previously set with
+ * spice_main_set_display() and spice_main_set_display_enabled()
+ *
+ * Returns: %TRUE on success.
+ **/
+gboolean spice_main_send_monitor_config(SpiceMainChannel *channel)
+{
+ SpiceMainChannelPrivate *c;
+ VDAgentMonitorsConfig *mon;
+ int i, j, monitors;
+ size_t size;
+
+ g_return_val_if_fail(SPICE_IS_MAIN_CHANNEL(channel), FALSE);
+ c = channel->priv;
+ g_return_val_if_fail(c->agent_connected, FALSE);
+
+ if (spice_main_agent_test_capability(channel,
+ VD_AGENT_CAP_SPARSE_MONITORS_CONFIG)) {
+ monitors = SPICE_N_ELEMENTS(c->display);
+ } else {
+ monitors = 0;
+ for (i = 0; i < SPICE_N_ELEMENTS(c->display); i++) {
+ if (c->display[i].display_state == DISPLAY_ENABLED)
+ monitors += 1;
+ }
+ }
+
+ size = sizeof(VDAgentMonitorsConfig) + sizeof(VDAgentMonConfig) * monitors;
+ mon = g_malloc0(size);
+
+ mon->num_of_monitors = monitors;
+ if (c->disable_display_position == FALSE ||
+ c->disable_display_align == FALSE)
+ mon->flags |= VD_AGENT_CONFIG_MONITORS_FLAG_USE_POS;
+
+ CHANNEL_DEBUG(channel, "sending new monitors config to guest");
+ j = 0;
+ for (i = 0; i < SPICE_N_ELEMENTS(c->display); i++) {
+ if (c->display[i].display_state != DISPLAY_ENABLED) {
+ if (spice_main_agent_test_capability(channel,
+ VD_AGENT_CAP_SPARSE_MONITORS_CONFIG))
+ j++;
+ continue;
+ }
+ mon->monitors[j].depth = c->display_color_depth ? c->display_color_depth : 32;
+ mon->monitors[j].width = c->display[i].width;
+ mon->monitors[j].height = c->display[i].height;
+ mon->monitors[j].x = c->display[i].x;
+ mon->monitors[j].y = c->display[i].y;
+ CHANNEL_DEBUG(channel, "monitor #%d: %ux%u+%d+%d @ %u bpp", j,
+ mon->monitors[j].width, mon->monitors[j].height,
+ mon->monitors[j].x, mon->monitors[j].y,
+ mon->monitors[j].depth);
+ j++;
+ }
+
+ if (c->disable_display_align == FALSE)
+ monitors_align(mon->monitors, mon->num_of_monitors);
+
+ agent_msg_queue(channel, VD_AGENT_MONITORS_CONFIG, size, mon);
+ g_free(mon);
+
+ spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
+ if (c->timer_id != 0) {
+ g_source_remove(c->timer_id);
+ c->timer_id = 0;
+ }
+
+ return TRUE;
+}
+
+static SpiceAudio *spice_main_get_audio(const SpiceMainChannel *channel)
+{
+ return spice_audio_get(spice_channel_get_session(SPICE_CHANNEL(channel)), NULL);
+}
+
+static void audio_playback_volume_info_cb(GObject *object, GAsyncResult *res, gpointer user_data)
+{
+ SpiceMainChannel *main_channel = user_data;
+ SpiceAudio *audio = spice_main_get_audio(main_channel);
+ VDAgentAudioVolumeSync *avs;
+ guint16 *volume;
+ guint8 nchannels;
+ gboolean mute, ret;
+ gsize array_size;
+ GError *error = NULL;
+
+ ret = spice_audio_get_playback_volume_info_finish(audio, res, &mute, &nchannels,
+ &volume, &error);
+ if (ret == FALSE || volume == NULL || nchannels == 0) {
+ if (error != NULL) {
+ g_warning("Failed to get playback async volume info: %s", error->message);
+ g_error_free(error);
+ } else {
+ SPICE_DEBUG("Failed to get playback async volume info");
+ }
+ main_channel->priv->agent_volume_playback_sync = FALSE;
+ return;
+ }
+
+ array_size = sizeof(uint16_t) * nchannels;
+ avs = g_malloc0(sizeof(VDAgentAudioVolumeSync) + array_size);
+ avs->is_playback = TRUE;
+ avs->mute = mute;
+ avs->nchannels = nchannels;
+ memcpy(avs->volume, volume, array_size);
+
+ SPICE_DEBUG("%s mute=%s nchannels=%u volume[0]=%u",
+ __func__, spice_yes_no(mute), nchannels, volume[0]);
+ g_free(volume);
+ agent_msg_queue(main_channel, VD_AGENT_AUDIO_VOLUME_SYNC,
+ sizeof(VDAgentAudioVolumeSync) + array_size, avs);
+ g_free (avs);
+}
+
+static void agent_sync_audio_playback(SpiceMainChannel *main_channel)
+{
+ SpiceAudio *audio = spice_main_get_audio(main_channel);
+ SpiceMainChannelPrivate *c = main_channel->priv;
+
+ if (audio == NULL ||
+ !test_agent_cap(main_channel, VD_AGENT_CAP_AUDIO_VOLUME_SYNC) ||
+ c->agent_volume_playback_sync == TRUE) {
+ SPICE_DEBUG("%s - is not going to sync audio with guest", __func__);
+ return;
+ }
+ /* only one per connection */
+ g_cancellable_reset(c->cancellable_volume_info);
+ c->agent_volume_playback_sync = TRUE;
+ spice_audio_get_playback_volume_info_async(audio, c->cancellable_volume_info, main_channel,
+ audio_playback_volume_info_cb, main_channel);
+}
+
+static void audio_record_volume_info_cb(GObject *object, GAsyncResult *res, gpointer user_data)
+{
+ SpiceMainChannel *main_channel = user_data;
+ SpiceAudio *audio = spice_main_get_audio(main_channel);
+ VDAgentAudioVolumeSync *avs;
+ guint16 *volume;
+ guint8 nchannels;
+ gboolean ret, mute;
+ gsize array_size;
+ GError *error = NULL;
+
+ ret = spice_audio_get_record_volume_info_finish(audio, res, &mute, &nchannels, &volume, &error);
+ if (ret == FALSE || volume == NULL || nchannels == 0) {
+ if (error != NULL) {
+ g_warning("Failed to get record async volume info: %s", error->message);
+ g_error_free(error);
+ } else {
+ SPICE_DEBUG("Failed to get record async volume info");
+ }
+ main_channel->priv->agent_volume_record_sync = FALSE;
+ return;
+ }
+
+ array_size = sizeof(uint16_t) * nchannels;
+ avs = g_malloc0(sizeof(VDAgentAudioVolumeSync) + array_size);
+ avs->is_playback = FALSE;
+ avs->mute = mute;
+ avs->nchannels = nchannels;
+ memcpy(avs->volume, volume, array_size);
+
+ SPICE_DEBUG("%s mute=%s nchannels=%u volume[0]=%u",
+ __func__, spice_yes_no(mute), nchannels, volume[0]);
+ g_free(volume);
+ agent_msg_queue(main_channel, VD_AGENT_AUDIO_VOLUME_SYNC,
+ sizeof(VDAgentAudioVolumeSync) + array_size, avs);
+ g_free (avs);
+}
+
+static void agent_sync_audio_record(SpiceMainChannel *main_channel)
+{
+ SpiceAudio *audio = spice_main_get_audio(main_channel);
+ SpiceMainChannelPrivate *c = main_channel->priv;
+
+ if (audio == NULL ||
+ !test_agent_cap(main_channel, VD_AGENT_CAP_AUDIO_VOLUME_SYNC) ||
+ c->agent_volume_record_sync == TRUE) {
+ SPICE_DEBUG("%s - is not going to sync audio with guest", __func__);
+ return;
+ }
+ /* only one per connection */
+ g_cancellable_reset(c->cancellable_volume_info);
+ c->agent_volume_record_sync = TRUE;
+ spice_audio_get_record_volume_info_async(audio, c->cancellable_volume_info, main_channel,
+ audio_record_volume_info_cb, main_channel);
+}
+
+/* any context: the message is not flushed immediately,
+ you can wakeup() the channel coroutine or send_msg_queue() */
+static void agent_display_config(SpiceMainChannel *channel)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+ VDAgentDisplayConfig config = { 0, };
+
+ if (c->display_disable_wallpaper) {
+ config.flags |= VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_WALLPAPER;
+ }
+
+ if (c->display_disable_font_smooth) {
+ config.flags |= VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_FONT_SMOOTH;
+ }
+
+ if (c->display_disable_animation) {
+ config.flags |= VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_ANIMATION;
+ }
+
+ if (c->display_color_depth != 0) {
+ config.flags |= VD_AGENT_DISPLAY_CONFIG_FLAG_SET_COLOR_DEPTH;
+ config.depth = c->display_color_depth;
+ }
+
+ CHANNEL_DEBUG(channel, "display_config: flags: %u, depth: %u", config.flags, config.depth);
+
+ agent_msg_queue(channel, VD_AGENT_DISPLAY_CONFIG, sizeof(VDAgentDisplayConfig), &config);
+}
+
+/* any context: the message is not flushed immediately,
+ you can wakeup() the channel coroutine or send_msg_queue() */
+static void agent_announce_caps(SpiceMainChannel *channel)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+ VDAgentAnnounceCapabilities *caps;
+ size_t size;
+
+ if (!c->agent_connected)
+ return;
+
+ size = sizeof(VDAgentAnnounceCapabilities) + VD_AGENT_CAPS_BYTES;
+ caps = g_malloc0(size);
+ if (!c->agent_caps_received)
+ caps->request = 1;
+ VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MOUSE_STATE);
+ VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MONITORS_CONFIG);
+ VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_REPLY);
+ VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_DISPLAY_CONFIG);
+ VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND);
+ VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_SELECTION);
+ VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MONITORS_CONFIG_POSITION);
+
+ agent_msg_queue(channel, VD_AGENT_ANNOUNCE_CAPABILITIES, size, caps);
+ g_free(caps);
+}
+
+/* any context: the message is not flushed immediately,
+ you can wakeup() the channel coroutine or send_msg_queue() */
+static void agent_clipboard_grab(SpiceMainChannel *channel, guint selection,
+ guint32 *types, int ntypes)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+ guint8 *msg;
+ VDAgentClipboardGrab *grab;
+ size_t size;
+ int i;
+
+ if (!c->agent_connected)
+ return;
+
+ g_return_if_fail(test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND));
+
+ size = sizeof(VDAgentClipboardGrab) + sizeof(uint32_t) * ntypes;
+ if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
+ size += 4;
+ } else if (selection != VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) {
+ CHANNEL_DEBUG(channel, "Ignoring clipboard grab");
+ return;
+ }
+
+ msg = g_alloca(size);
+ memset(msg, 0, size);
+
+ grab = (VDAgentClipboardGrab *)msg;
+
+ if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
+ msg[0] = selection;
+ grab = (VDAgentClipboardGrab *)(msg + 4);
+ }
+
+ for (i = 0; i < ntypes; i++) {
+ grab->types[i] = types[i];
+ }
+
+ agent_msg_queue(channel, VD_AGENT_CLIPBOARD_GRAB, size, msg);
+}
+
+/* any context: the message is not flushed immediately,
+ you can wakeup() the channel coroutine or send_msg_queue() */
+static void agent_clipboard_notify(SpiceMainChannel *self, guint selection,
+ guint32 type, const guchar *data, size_t size)
+{
+ SpiceMainChannelPrivate *c = self->priv;
+ VDAgentClipboard *cb;
+ guint8 *msg;
+ size_t msgsize;
+ gint max_clipboard = spice_main_get_max_clipboard(self);
+
+ g_return_if_fail(c->agent_connected);
+ g_return_if_fail(test_agent_cap(self, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND));
+ g_return_if_fail(max_clipboard == -1 || size < max_clipboard);
+
+ msgsize = sizeof(VDAgentClipboard);
+ if (test_agent_cap(self, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
+ msgsize += 4;
+ } else if (selection != VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) {
+ CHANNEL_DEBUG(self, "Ignoring clipboard notify");
+ return;
+ }
+
+ msg = g_alloca(msgsize);
+ memset(msg, 0, msgsize);
+
+ cb = (VDAgentClipboard *)msg;
+
+ if (test_agent_cap(self, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
+ msg[0] = selection;
+ cb = (VDAgentClipboard *)(msg + 4);
+ }
+
+ cb->type = type;
+ agent_msg_queue_many(self, VD_AGENT_CLIPBOARD, msg, msgsize, data, size, NULL);
+}
+
+/* any context: the message is not flushed immediately,
+ you can wakeup() the channel coroutine or send_msg_queue() */
+static void agent_clipboard_request(SpiceMainChannel *channel, guint selection, guint32 type)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+ VDAgentClipboardRequest *request;
+ guint8 *msg;
+ size_t msgsize;
+
+ g_return_if_fail(c->agent_connected);
+ g_return_if_fail(test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND));
+
+ msgsize = sizeof(VDAgentClipboardRequest);
+ if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
+ msgsize += 4;
+ } else if (selection != VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) {
+ SPICE_DEBUG("Ignoring clipboard request");
+ return;
+ }
+
+ msg = g_alloca(msgsize);
+ memset(msg, 0, msgsize);
+
+ request = (VDAgentClipboardRequest *)msg;
+
+ if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
+ msg[0] = selection;
+ request = (VDAgentClipboardRequest *)(msg + 4);
+ }
+
+ request->type = type;
+
+ agent_msg_queue(channel, VD_AGENT_CLIPBOARD_REQUEST, msgsize, msg);
+}
+
+/* any context: the message is not flushed immediately,
+ you can wakeup() the channel coroutine or send_msg_queue() */
+static void agent_clipboard_release(SpiceMainChannel *channel, guint selection)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+ guint8 msg[4] = { 0, };
+ guint8 msgsize = 0;
+
+ g_return_if_fail(c->agent_connected);
+ g_return_if_fail(test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND));
+
+ if (test_agent_cap(channel, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
+ msg[0] = selection;
+ msgsize += 4;
+ } else if (selection != VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) {
+ SPICE_DEBUG("Ignoring clipboard release");
+ return;
+ }
+
+ agent_msg_queue(channel, VD_AGENT_CLIPBOARD_RELEASE, msgsize, msg);
+}
+
+static gboolean any_display_has_dimensions(SpiceMainChannel *channel)
+{
+ SpiceMainChannelPrivate *c;
+ guint i;
+
+ g_return_val_if_fail(SPICE_IS_MAIN_CHANNEL(channel), FALSE);
+ c = channel->priv;
+
+ for (i = 0; i < MAX_DISPLAY; i++) {
+ if (c->display[i].width > 0 && c->display[i].height > 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* main context*/
+static gboolean timer_set_display(gpointer data)
+{
+ SpiceMainChannel *channel = data;
+ SpiceMainChannelPrivate *c = channel->priv;
+ SpiceSession *session;
+ gint i;
+
+ c->timer_id = 0;
+ if (!c->agent_connected)
+ return FALSE;
+
+ if (!any_display_has_dimensions(channel)) {
+ SPICE_DEBUG("Not sending monitors config, at least one monitor must have dimensions");
+ return FALSE;
+ }
+
+ session = spice_channel_get_session(SPICE_CHANNEL(channel));
+
+ if (!spice_main_agent_test_capability(channel, VD_AGENT_CAP_SPARSE_MONITORS_CONFIG)) {
+ /* ensure we have an explicit monitor configuration at least for
+ number of display channels */
+ for (i = 0; i < spice_session_get_n_display_channels(session); i++)
+ if (c->display[i].display_state == DISPLAY_UNDEFINED) {
+ SPICE_DEBUG("Not sending monitors config, missing monitors");
+ return FALSE;
+ }
+ }
+ spice_main_send_monitor_config(channel);
+
+ return FALSE;
+}
+
+/* any context */
+static void update_display_timer(SpiceMainChannel *channel, guint seconds)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+
+ if (c->timer_id)
+ g_source_remove(c->timer_id);
+
+ if (seconds != 0) {
+ c->timer_id = g_timeout_add_seconds(seconds, timer_set_display, channel);
+ } else {
+ /* We need to special case 0, as we want the callback to fire as soon
+ * as possible. g_timeout_add_seconds(0) would set up a timer which would fire
+ * at the next second boundary, which might be nearly 1 full second later.
+ */
+ c->timer_id = g_timeout_add(0, timer_set_display, channel);
+ }
+
+}
+
+/* coroutine context */
+static void set_agent_connected(SpiceMainChannel *channel, gboolean connected)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+
+ SPICE_DEBUG("agent connected: %s", spice_yes_no(connected));
+ if (connected != c->agent_connected) {
+ c->agent_connected = connected;
+ g_coroutine_object_notify(G_OBJECT(channel), "agent-connected");
+ }
+ if (!connected)
+ spice_main_channel_reset_agent(SPICE_MAIN_CHANNEL(channel));
+
+ g_coroutine_signal_emit(channel, signals[SPICE_MAIN_AGENT_UPDATE], 0);
+}
+
+/* coroutine context */
+static void agent_start(SpiceMainChannel *channel)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+ SpiceMsgcMainAgentStart agent_start = {
+ .num_tokens = ~0,
+ };
+ SpiceMsgOut *out;
+
+ c->agent_volume_playback_sync = FALSE;
+ c->agent_volume_record_sync = FALSE;
+ c->agent_caps_received = false;
+ set_agent_connected(channel, TRUE);
+
+ out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MAIN_AGENT_START);
+ out->marshallers->msgc_main_agent_start(out->marshaller, &agent_start);
+ spice_msg_out_send_internal(out);
+
+ if (c->agent_connected) {
+ agent_announce_caps(channel);
+ agent_send_msg_queue(channel);
+ }
+}
+
+/* coroutine context */
+static void agent_stopped(SpiceMainChannel *channel)
+{
+ set_agent_connected(channel, FALSE);
+}
+
+/**
+ * spice_main_request_mouse_mode:
+ * @channel: a %SpiceMainChannel
+ * @mode: a SPICE_MOUSE_MODE
+ *
+ * Request a mouse mode to the server. The server may not be able to
+ * change the mouse mode, but spice-gtk will try to request it
+ * when possible.
+ *
+ * Since: 0.32
+ **/
+void spice_main_request_mouse_mode(SpiceMainChannel *channel, int mode)
+{
+ SpiceMsgcMainMouseModeRequest req = {
+ .mode = mode,
+ };
+ SpiceMsgOut *out;
+ SpiceMainChannelPrivate *c;
+
+ g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
+ c = channel->priv;
+
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
+ CHANNEL_DEBUG(channel, "request mouse mode %d", mode);
+ c->requested_mouse_mode = mode;
+
+ out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST);
+ out->marshallers->msgc_main_mouse_mode_request(out->marshaller, &req);
+ spice_msg_out_send(out);
+}
+
+/* coroutine context */
+static void set_mouse_mode(SpiceMainChannel *channel, uint32_t supported, uint32_t current)
+{
+ SpiceMainChannelPrivate *c = channel->priv;
+
+ if (c->mouse_mode != current) {
+ c->mouse_mode = current;
+ g_coroutine_signal_emit(channel, signals[SPICE_MAIN_MOUSE_UPDATE], 0);
+ g_coroutine_object_notify(G_OBJECT(channel), "mouse-mode");
+ }
+
+ if (c->requested_mouse_mode != c->mouse_mode &&
+ c->requested_mouse_mode & supported) {
+ spice_main_request_mouse_mode(SPICE_MAIN_CHANNEL(channel), c->requested_mouse_mode);
+ }
+}
+
+/* coroutine context */
+static void main_handle_init(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
+ SpiceMsgMainInit *init = spice_msg_in_parsed(in);
+ SpiceSession *session;
+ SpiceMsgOut *out;
+
+ session = spice_channel_get_session(channel);
+ spice_session_set_connection_id(session, init->session_id);
+
+ set_mouse_mode(SPICE_MAIN_CHANNEL(channel), init->supported_mouse_modes,
+ init->current_mouse_mode);
+
+ spice_session_set_mm_time(session, init->multi_media_time);
+ spice_session_set_caches_hints(session, init->ram_hint, init->display_channels_hint);
+
+ c->agent_tokens = init->agent_tokens;
+ if (init->agent_connected)
+ agent_start(SPICE_MAIN_CHANNEL(channel));
+
+ if (spice_session_migrate_after_main_init(session))
+ return;
+
+ out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MAIN_ATTACH_CHANNELS);
+ spice_msg_out_send_internal(out);
+}
+
+/* coroutine context */
+static void main_handle_name(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgMainName *name = spice_msg_in_parsed(in);
+ SpiceSession *session = spice_channel_get_session(channel);
+
+ SPICE_DEBUG("server name: %s", name->name);
+ spice_session_set_name(session, (const gchar *)name->name);
+}
+
+/* coroutine context */
+static void main_handle_uuid(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgMainUuid *uuid = spice_msg_in_parsed(in);
+ SpiceSession *session = spice_channel_get_session(channel);
+ gchar *uuid_str = spice_uuid_to_string(uuid->uuid);
+
+ SPICE_DEBUG("server uuid: %s", uuid_str);
+ spice_session_set_uuid(session, uuid->uuid);
+
+ g_free(uuid_str);
+}
+
+/* coroutine context */
+static void main_handle_mm_time(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceSession *session;
+ SpiceMsgMainMultiMediaTime *msg = spice_msg_in_parsed(in);
+
+ session = spice_channel_get_session(channel);
+ spice_session_set_mm_time(session, msg->time);
+}
+
+typedef struct channel_new {
+ SpiceSession *session;
+ int type;
+ int id;
+} channel_new_t;
+
+/* main context */
+static gboolean _channel_new(channel_new_t *c)
+{
+ g_return_val_if_fail(c != NULL, FALSE);
+
+ spice_channel_new(c->session, c->type, c->id);
+
+ g_object_unref(c->session);
+ g_free(c);
+
+ return FALSE;
+}
+
+/* coroutine context */
+static void main_handle_channels_list(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgChannels *msg = spice_msg_in_parsed(in);
+ SpiceSession *session;
+ int i;
+
+ session = spice_channel_get_session(channel);
+
+ /* guarantee that uuid is notified before setting up the channels, even if
+ * the server is older and doesn't actually send the uuid */
+ g_coroutine_object_notify(G_OBJECT(session), "uuid");
+
+ for (i = 0; i < msg->num_of_channels; i++) {
+ channel_new_t *c;
+
+ c = g_new(channel_new_t, 1);
+ c->session = g_object_ref(session);
+ c->type = msg->channels[i].type;
+ c->id = msg->channels[i].id;
+ /* no need to explicitely switch to main context, since
+ synchronous call is not needed. */
+ /* no need to track idle, session is refed */
+ g_idle_add((GSourceFunc)_channel_new, c);
+ }
+}
+
+/* coroutine context */
+static void main_handle_mouse_mode(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgMainMouseMode *msg = spice_msg_in_parsed(in);
+ set_mouse_mode(SPICE_MAIN_CHANNEL(channel), msg->supported_modes, msg->current_mode);
+}
+
+/* coroutine context */
+static void main_handle_agent_connected(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ agent_start(SPICE_MAIN_CHANNEL(channel));
+}
+
+/* coroutine context */
+static void main_handle_agent_connected_tokens(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
+ SpiceMsgMainAgentConnectedTokens *msg = spice_msg_in_parsed(in);
+
+ c->agent_tokens = msg->num_tokens;
+ agent_start(SPICE_MAIN_CHANNEL(channel));
+}
+
+/* coroutine context */
+static void main_handle_agent_disconnected(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ agent_stopped(SPICE_MAIN_CHANNEL(channel));
+}
+
+static void file_xfer_data_flushed_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceFileTransferTask *xfer_task = SPICE_FILE_TRANSFER_TASK(source_object);
+ GError *error = NULL;
+
+ file_xfer_flush_finish(xfer_task, res, &error);
+ if (error) {
+ spice_file_transfer_task_completed(xfer_task, error);
+ return;
+ }
+
+ /* task might be completed while on idle */
+ if (!spice_file_transfer_task_is_completed(xfer_task)) {
+ file_transfer_operation_send_progress(xfer_task);
+ /* Read more data */
+ spice_file_transfer_task_read_async(xfer_task, file_xfer_read_async_cb, user_data);
+ }
+}
+
+static void file_xfer_queue_msg_to_agent(SpiceMainChannel *channel,
+ guint32 task_id,
+ gchar *buffer,
+ gint data_size)
+{
+ VDAgentFileXferDataMessage msg;
+
+ g_return_if_fail(channel != NULL);
+
+ msg.id = task_id;
+ msg.size = data_size;
+ agent_msg_queue_many(channel, VD_AGENT_FILE_XFER_DATA,
+ &msg, sizeof(msg),
+ buffer, data_size, NULL);
+ spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
+}
+
+/* main context */
+static void file_xfer_read_async_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ FileTransferOperation *xfer_op;
+ SpiceFileTransferTask *xfer_task;
+ SpiceMainChannel *channel;
+ gssize count;
+ char *buffer;
+ GError *error = NULL;
+
+ xfer_task = SPICE_FILE_TRANSFER_TASK(source_object);
+ xfer_op = user_data;
+
+ channel = spice_file_transfer_task_get_channel(xfer_task);
+ count = spice_file_transfer_task_read_finish(xfer_task, res, &buffer, &error);
+ if (count < 0) {
+ spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
+ spice_file_transfer_task_completed(xfer_task, error);
+ return;
+ }
+
+ file_xfer_queue_msg_to_agent(channel, spice_file_transfer_task_get_id(xfer_task), buffer, count);
+ if (count == 0 || spice_file_transfer_task_is_completed(xfer_task)) {
+ /* on EOF just wait for VD_AGENT_FILE_XFER_STATUS from agent
+ * in case the task was completed, nothing to do. */
+ return;
+ }
+
+ xfer_op->stats.total_sent += count;
+
+ file_xfer_flush_async(xfer_task, file_xfer_data_flushed_cb, xfer_op);
+}
+
+/* coroutine context */
+static void main_agent_handle_xfer_status(SpiceMainChannel *channel,
+ VDAgentFileXferStatusMessage *msg)
+{
+ SpiceFileTransferTask *xfer_task;
+ FileTransferOperation *xfer_op;
+ GError *error = NULL;
+
+ SPICE_DEBUG("xfer-task %u received response %u", msg->id, msg->result);
+
+ xfer_task = spice_main_channel_find_xfer_task_by_task_id(channel, msg->id);
+ g_return_if_fail(xfer_task != NULL);
+ xfer_op = g_hash_table_lookup(channel->priv->file_xfer_tasks, GUINT_TO_POINTER(msg->id));
+
+ switch (msg->result) {
+ case VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA:
+ g_return_if_fail(spice_file_transfer_task_is_completed(xfer_task) == FALSE);
+ spice_file_transfer_task_read_async(xfer_task, file_xfer_read_async_cb, xfer_op);
+ return;
+ case VD_AGENT_FILE_XFER_STATUS_CANCELLED:
+ error = g_error_new_literal(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("The spice agent cancelled the file transfer"));
+ break;
+ case VD_AGENT_FILE_XFER_STATUS_ERROR:
+ error = g_error_new_literal(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("The spice agent reported an error during the file transfer"));
+ break;
+ case VD_AGENT_FILE_XFER_STATUS_SUCCESS:
+ break;
+ default:
+ g_warn_if_reached();
+ error = g_error_new(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "unhandled status type: %u", msg->result);
+ break;
+ }
+
+ spice_file_transfer_task_completed(xfer_task, error);
+}
+
+
+/* any context: the message is not flushed immediately,
+ you can wakeup() the channel coroutine or send_msg_queue() */
+static void agent_max_clipboard(SpiceMainChannel *self)
+{
+ VDAgentMaxClipboard msg = { .max = spice_main_get_max_clipboard(self) };
+
+ if (!test_agent_cap(self, VD_AGENT_CAP_MAX_CLIPBOARD))
+ return;
+
+ agent_msg_queue(self, VD_AGENT_MAX_CLIPBOARD, sizeof(VDAgentMaxClipboard), &msg);
+}
+
+static void spice_main_set_max_clipboard(SpiceMainChannel *self, gint max)
+{
+ SpiceMainChannelPrivate *c;
+
+ g_return_if_fail(SPICE_IS_MAIN_CHANNEL(self));
+ g_return_if_fail(max >= -1);
+
+ c = self->priv;
+ if (max == spice_main_get_max_clipboard(self))
+ return;
+
+ c->max_clipboard = max;
+ agent_max_clipboard(self);
+ spice_channel_wakeup(SPICE_CHANNEL(self), FALSE);
+}
+
+/* coroutine context */
+static void main_agent_handle_msg(SpiceChannel *channel,
+ VDAgentMessage *msg, gpointer payload)
+{
+ SpiceMainChannel *self = SPICE_MAIN_CHANNEL(channel);
+ SpiceMainChannelPrivate *c = self->priv;
+ guint8 selection = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
+
+ g_return_if_fail(msg->protocol == VD_AGENT_PROTOCOL);
+
+ switch (msg->type) {
+ case VD_AGENT_CLIPBOARD_RELEASE:
+ case VD_AGENT_CLIPBOARD_REQUEST:
+ case VD_AGENT_CLIPBOARD_GRAB:
+ case VD_AGENT_CLIPBOARD:
+ if (test_agent_cap(self, VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
+ selection = *((guint8*)payload);
+ payload = ((guint8*)payload) + 4;
+ msg->size -= 4;
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (msg->type) {
+ case VD_AGENT_ANNOUNCE_CAPABILITIES:
+ {
+ VDAgentAnnounceCapabilities *caps = payload;
+ int i, size;
+
+ size = VD_AGENT_CAPS_SIZE_FROM_MSG_SIZE(msg->size);
+ if (size > VD_AGENT_CAPS_SIZE)
+ size = VD_AGENT_CAPS_SIZE;
+ memset(c->agent_caps, 0, sizeof(c->agent_caps));
+ for (i = 0; i < size * 32; i++) {
+ if (!VD_AGENT_HAS_CAPABILITY(caps->caps, size, i))
+ continue;
+ SPICE_DEBUG("%s: cap: %d (%s)", __FUNCTION__,
+ i, NAME(agent_caps, i));
+ VD_AGENT_SET_CAPABILITY(c->agent_caps, i);
+ }
+ c->agent_caps_received = true;
+ g_coroutine_signal_emit(self, signals[SPICE_MAIN_AGENT_UPDATE], 0);
+ update_display_timer(SPICE_MAIN_CHANNEL(channel), 0);
+
+ if (caps->request)
+ agent_announce_caps(self);
+
+ if (test_agent_cap(self, VD_AGENT_CAP_DISPLAY_CONFIG) &&
+ !c->agent_display_config_sent) {
+ agent_display_config(self);
+ c->agent_display_config_sent = true;
+ }
+
+ agent_sync_audio_playback(self);
+ agent_sync_audio_record(self);
+
+ agent_max_clipboard(self);
+
+ agent_send_msg_queue(self);
+
+ break;
+ }
+ case VD_AGENT_CLIPBOARD:
+ {
+ VDAgentClipboard *cb = payload;
+ g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_SELECTION], 0, selection,
+ cb->type, cb->data, msg->size - sizeof(VDAgentClipboard));
+
+ if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD)
+ g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD], 0,
+ cb->type, cb->data, msg->size - sizeof(VDAgentClipboard));
+ break;
+ }
+ case VD_AGENT_CLIPBOARD_GRAB:
+ {
+ gboolean ret;
+ g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_SELECTION_GRAB], 0, selection,
+ (guint8*)payload, msg->size / sizeof(uint32_t), &ret);
+ if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD)
+ g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_GRAB], 0,
+ payload, msg->size / sizeof(uint32_t), &ret);
+ break;
+ }
+ case VD_AGENT_CLIPBOARD_REQUEST:
+ {
+ gboolean ret;
+ VDAgentClipboardRequest *req = payload;
+ g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_SELECTION_REQUEST], 0, selection,
+ req->type, &ret);
+
+ if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD)
+ g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_REQUEST], 0,
+ req->type, &ret);
+ break;
+ }
+ case VD_AGENT_CLIPBOARD_RELEASE:
+ {
+ g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_SELECTION_RELEASE], 0, selection);
+
+ if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD)
+ g_coroutine_signal_emit(self, signals[SPICE_MAIN_CLIPBOARD_RELEASE], 0);
+ break;
+ }
+ case VD_AGENT_REPLY:
+ {
+ VDAgentReply *reply = payload;
+ SPICE_DEBUG("%s: reply: type %u, %s", __FUNCTION__, reply->type,
+ reply->error == VD_AGENT_SUCCESS ? "success" : "error");
+ break;
+ }
+ case VD_AGENT_FILE_XFER_STATUS:
+ main_agent_handle_xfer_status(self, payload);
+ break;
+ default:
+ g_warning("unhandled agent message type: %u (%s), size %u",
+ msg->type, NAME(agent_msg_types, msg->type), msg->size);
+ }
+}
+
+/* coroutine context */
+static void main_handle_agent_data_msg(SpiceChannel* channel, int* msg_size, guchar** msg_pos)
+{
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
+ int n;
+
+ if (c->agent_msg_pos < sizeof(VDAgentMessage)) {
+ n = MIN(sizeof(VDAgentMessage) - c->agent_msg_pos, *msg_size);
+ memcpy((uint8_t*)&c->agent_msg + c->agent_msg_pos, *msg_pos, n);
+ c->agent_msg_pos += n;
+ *msg_size -= n;
+ *msg_pos += n;
+ if (c->agent_msg_pos == sizeof(VDAgentMessage)) {
+ SPICE_DEBUG("agent msg start: msg_size=%u, protocol=%u, type=%u",
+ c->agent_msg.size, c->agent_msg.protocol, c->agent_msg.type);
+ g_return_if_fail(c->agent_msg_data == NULL);
+ c->agent_msg_data = g_malloc0(c->agent_msg.size);
+ }
+ }
+
+ if (c->agent_msg_pos >= sizeof(VDAgentMessage)) {
+ n = MIN(sizeof(VDAgentMessage) + c->agent_msg.size - c->agent_msg_pos, *msg_size);
+ memcpy(c->agent_msg_data + c->agent_msg_pos - sizeof(VDAgentMessage), *msg_pos, n);
+ c->agent_msg_pos += n;
+ *msg_size -= n;
+ *msg_pos += n;
+ }
+
+ if (c->agent_msg_pos == sizeof(VDAgentMessage) + c->agent_msg.size) {
+ main_agent_handle_msg(channel, &c->agent_msg, c->agent_msg_data);
+ g_free(c->agent_msg_data);
+ c->agent_msg_data = NULL;
+ c->agent_msg_pos = 0;
+ }
+}
+
+/* coroutine context */
+static void main_handle_agent_data(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
+ guint8 *data;
+ int len;
+
+ g_warn_if_fail(c->agent_connected);
+
+ /* shortcut to avoid extra message allocation & copy if possible */
+ if (c->agent_msg_pos == 0) {
+ VDAgentMessage *msg;
+ guint msg_size;
+
+ msg = spice_msg_in_raw(in, &len);
+ msg_size = msg->size;
+
+ if (msg_size + sizeof(VDAgentMessage) == len) {
+ main_agent_handle_msg(channel, msg, msg->data);
+ return;
+ }
+ }
+
+ data = spice_msg_in_raw(in, &len);
+ while (len > 0) {
+ main_handle_agent_data_msg(channel, &len, &data);
+ }
+}
+
+/* coroutine context */
+static void main_handle_agent_token(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgMainAgentTokens *tokens = spice_msg_in_parsed(in);
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
+
+ c->agent_tokens += tokens->num_tokens;
+
+ agent_send_msg_queue(SPICE_MAIN_CHANNEL(channel));
+}
+
+/* main context */
+static void migrate_channel_new_cb(SpiceSession *s, SpiceChannel *channel, gpointer data)
+{
+ g_signal_connect(channel, "channel-event",
+ G_CALLBACK(migrate_channel_event_cb), data);
+}
+
+static SpiceChannel* migrate_channel_connect(spice_migrate *mig, int type, int id)
+{
+ SPICE_DEBUG("migrate_channel_connect %d:%d", type, id);
+
+ SpiceChannel *newc = spice_channel_new(mig->session, type, id);
+ spice_channel_connect(newc);
+ mig->nchannels++;
+
+ return newc;
+}
+
+/* coroutine context */
+static void spice_main_channel_send_migration_handshake(SpiceChannel *channel)
+{
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
+
+ if (!spice_channel_test_capability(channel, SPICE_MAIN_CAP_SEAMLESS_MIGRATE)) {
+ c->migrate_data->do_seamless = false;
+ g_idle_add(main_migrate_handshake_done, c->migrate_data);
+ } else {
+ SpiceMsgcMainMigrateDstDoSeamless msg_data;
+ SpiceMsgOut *msg_out;
+
+ msg_data.src_version = c->migrate_data->src_mig_version;
+
+ msg_out = spice_msg_out_new(channel, SPICE_MSGC_MAIN_MIGRATE_DST_DO_SEAMLESS);
+ msg_out->marshallers->msgc_main_migrate_dst_do_seamless(msg_out->marshaller, &msg_data);
+ spice_msg_out_send_internal(msg_out);
+ }
+}
+
+/* main context */
+static void migrate_channel_event_cb(SpiceChannel *channel, SpiceChannelEvent event,
+ gpointer data)
+{
+ spice_migrate *mig = data;
+ SpiceChannelPrivate *c = SPICE_CHANNEL(channel)->priv;
+
+ g_return_if_fail(mig->nchannels > 0);
+ g_signal_handlers_disconnect_by_func(channel, migrate_channel_event_cb, data);
+
+ switch (event) {
+ case SPICE_CHANNEL_OPENED:
+ if (c->channel_type == SPICE_CHANNEL_MAIN) {
+ SpiceSession *session = spice_channel_get_session(mig->src_channel);
+ if (mig->do_seamless) {
+ SpiceMainChannelPrivate *main_priv = SPICE_MAIN_CHANNEL(channel)->priv;
+
+ c->state = SPICE_CHANNEL_STATE_MIGRATION_HANDSHAKE;
+ mig->dst_channel = channel;
+ main_priv->migrate_data = mig;
+ } else {
+ c->state = SPICE_CHANNEL_STATE_MIGRATING;
+ mig->nchannels--;
+ }
+ /* now connect the rest of the channels */
+ GList *channels, *l;
+ l = channels = spice_session_get_channels(session);
+ while (l != NULL) {
+ SpiceChannelPrivate *curc = SPICE_CHANNEL(l->data)->priv;
+ l = l->next;
+ if (curc->channel_type == SPICE_CHANNEL_MAIN)
+ continue;
+ migrate_channel_connect(mig, curc->channel_type, curc->channel_id);
+ }
+ g_list_free(channels);
+ } else {
+ c->state = SPICE_CHANNEL_STATE_MIGRATING;
+ mig->nchannels--;
+ }
+
+ SPICE_DEBUG("migration: channel opened chan:%p, left %u", channel, mig->nchannels);
+ if (mig->nchannels == 0)
+ coroutine_yieldto(mig->from, NULL);
+ break;
+ default:
+ CHANNEL_DEBUG(channel, "error or unhandled channel event during migration: %u", event);
+ /* go back to main channel to report error */
+ coroutine_yieldto(mig->from, NULL);
+ }
+}
+
+/* main context */
+static gboolean main_migrate_handshake_done(gpointer data)
+{
+ spice_migrate *mig = data;
+ SpiceChannelPrivate *c = SPICE_CHANNEL(mig->dst_channel)->priv;
+
+ g_return_val_if_fail(c->channel_type == SPICE_CHANNEL_MAIN, FALSE);
+ g_return_val_if_fail(c->state == SPICE_CHANNEL_STATE_MIGRATION_HANDSHAKE, FALSE);
+
+ c->state = SPICE_CHANNEL_STATE_MIGRATING;
+ mig->nchannels--;
+ if (mig->nchannels == 0)
+ coroutine_yieldto(mig->from, NULL);
+ return FALSE;
+}
+
+#ifdef __GNUC__
+typedef struct __attribute__ ((__packed__)) OldRedMigrationBegin {
+#else
+typedef struct __declspec(align(1)) OldRedMigrationBegin {
+#endif
+ uint16_t port;
+ uint16_t sport;
+ char host[0];
+} OldRedMigrationBegin;
+
+/* main context */
+static gboolean migrate_connect(gpointer data)
+{
+ spice_migrate *mig = data;
+ SpiceChannelPrivate *c;
+ int port, sport;
+ const char *host;
+
+ g_return_val_if_fail(mig != NULL, FALSE);
+ g_return_val_if_fail(mig->info != NULL, FALSE);
+ g_return_val_if_fail(mig->nchannels == 0, FALSE);
+ c = SPICE_CHANNEL(mig->src_channel)->priv;
+ g_return_val_if_fail(c != NULL, FALSE);
+ g_return_val_if_fail(mig->session != NULL, FALSE);
+
+ spice_session_set_migration_state(mig->session, SPICE_SESSION_MIGRATION_CONNECTING);
+
+ if ((c->peer_hdr.major_version == 1) &&
+ (c->peer_hdr.minor_version < 1)) {
+ OldRedMigrationBegin *info = (OldRedMigrationBegin *)mig->info;
+ SPICE_DEBUG("migrate_begin old %s %d %d",
+ info->host, info->port, info->sport);
+ port = info->port;
+ sport = info->sport;
+ host = info->host;
+ } else {
+ SpiceMigrationDstInfo *info = mig->info;
+ SPICE_DEBUG("migrate_begin %u %s %d %d",
+ info->host_size, info->host_data, info->port, info->sport);
+ port = info->port;
+ sport = info->sport;
+ host = (char*)info->host_data;
+
+ if ((c->peer_hdr.major_version == 1) ||
+ (c->peer_hdr.major_version == 2 && c->peer_hdr.minor_version < 1)) {
+ GByteArray *pubkey = g_byte_array_new();
+
+ g_byte_array_append(pubkey, info->pub_key_data, info->pub_key_size);
+ g_object_set(mig->session,
+ "pubkey", pubkey,
+ "verify", SPICE_SESSION_VERIFY_PUBKEY,
+ NULL);
+ g_byte_array_unref(pubkey);
+ } else if (info->cert_subject_size == 0 ||
+ strlen((const char*)info->cert_subject_data) == 0) {
+ /* only verify hostname if no cert subject */
+ g_object_set(mig->session, "verify", SPICE_SESSION_VERIFY_HOSTNAME, NULL);
+ } else {
+ gchar *subject = g_alloca(info->cert_subject_size + 1);
+ strncpy(subject, (const char*)info->cert_subject_data, info->cert_subject_size);
+ subject[info->cert_subject_size] = '\0';
+
+ // session data are already copied
+ g_object_set(mig->session,
+ "cert-subject", subject,
+ "verify", SPICE_SESSION_VERIFY_SUBJECT,
+ NULL);
+ }
+ }
+
+ if (g_getenv("SPICE_MIG_HOST"))
+ host = g_getenv("SPICE_MIG_HOST");
+
+ g_object_set(mig->session, "host", host, NULL);
+ spice_session_set_port(mig->session, port, FALSE);
+ spice_session_set_port(mig->session, sport, TRUE);
+ g_signal_connect(mig->session, "channel-new",
+ G_CALLBACK(migrate_channel_new_cb), mig);
+
+ g_signal_emit(mig->src_channel, signals[SPICE_MIGRATION_STARTED], 0,
+ mig->session);
+
+ /* the migration process is in 2 steps, first the main channel and
+ then the rest of the channels */
+ migrate_channel_connect(mig, SPICE_CHANNEL_MAIN, 0);
+
+ return FALSE;
+}
+
+/* coroutine context */
+static void main_migrate_connect(SpiceChannel *channel,
+ SpiceMigrationDstInfo *dst_info, bool do_seamless,
+ uint32_t src_mig_version)
+{
+ SpiceMainChannelPrivate *main_priv = SPICE_MAIN_CHANNEL(channel)->priv;
+ int reply_type = SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR;
+ spice_migrate mig = { 0, };
+ SpiceMsgOut *out;
+ SpiceSession *session;
+
+ mig.src_channel = channel;
+ mig.info = dst_info;
+ mig.from = coroutine_self();
+ mig.do_seamless = do_seamless;
+ mig.src_mig_version = src_mig_version;
+
+ CHANNEL_DEBUG(channel, "migrate connect");
+ session = spice_channel_get_session(channel);
+ mig.session = spice_session_new_from_session(session);
+ if (mig.session == NULL)
+ goto end;
+ if (!spice_session_set_migration_session(session, mig.session))
+ goto end;
+
+ main_priv->migrate_data = &mig;
+
+ /* no need to track idle, call is sync for this coroutine */
+ g_idle_add(migrate_connect, &mig);
+
+ /* switch to main loop and wait for connections */
+ coroutine_yield(NULL);
+
+ if (mig.nchannels != 0) {
+ CHANNEL_DEBUG(channel, "migrate failed: some channels failed to connect");
+ spice_session_abort_migration(session);
+ } else {
+ if (mig.do_seamless) {
+ SPICE_DEBUG("migration (seamless): connections all ok");
+ reply_type = SPICE_MSGC_MAIN_MIGRATE_CONNECTED_SEAMLESS;
+ } else {
+ SPICE_DEBUG("migration (semi-seamless): connections all ok");
+ reply_type = SPICE_MSGC_MAIN_MIGRATE_CONNECTED;
+ }
+ spice_session_start_migrating(spice_channel_get_session(channel),
+ mig.do_seamless);
+ }
+
+end:
+ CHANNEL_DEBUG(channel, "migrate connect reply %d", reply_type);
+ out = spice_msg_out_new(SPICE_CHANNEL(channel), reply_type);
+ spice_msg_out_send(out);
+}
+
+/* coroutine context */
+static void main_handle_migrate_begin(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgMainMigrationBegin *msg = spice_msg_in_parsed(in);
+
+ main_migrate_connect(channel, &msg->dst_info, false, 0);
+}
+
+/* coroutine context */
+static void main_handle_migrate_begin_seamless(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgMainMigrateBeginSeamless *msg = spice_msg_in_parsed(in);
+
+ main_migrate_connect(channel, &msg->dst_info, true, msg->src_mig_version);
+}
+
+static void main_handle_migrate_dst_seamless_ack(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceChannelPrivate *c = SPICE_CHANNEL(channel)->priv;
+ SpiceMainChannelPrivate *main_priv = SPICE_MAIN_CHANNEL(channel)->priv;
+
+ g_return_if_fail(c->state == SPICE_CHANNEL_STATE_MIGRATION_HANDSHAKE);
+ main_priv->migrate_data->do_seamless = true;
+ g_idle_add(main_migrate_handshake_done, main_priv->migrate_data);
+}
+
+static void main_handle_migrate_dst_seamless_nack(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceChannelPrivate *c = SPICE_CHANNEL(channel)->priv;
+ SpiceMainChannelPrivate *main_priv = SPICE_MAIN_CHANNEL(channel)->priv;
+
+ g_return_if_fail(c->state == SPICE_CHANNEL_STATE_MIGRATION_HANDSHAKE);
+ main_priv->migrate_data->do_seamless = false;
+ g_idle_add(main_migrate_handshake_done, main_priv->migrate_data);
+}
+
+/* main context */
+static gboolean migrate_delayed(gpointer data)
+{
+ SpiceChannel *channel = data;
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
+
+ g_warn_if_fail(c->migrate_delayed_id != 0);
+ c->migrate_delayed_id = 0;
+
+ spice_session_migrate_end(channel->priv->session);
+
+ return FALSE;
+}
+
+/* coroutine context */
+static void main_handle_migrate_end(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
+
+ SPICE_DEBUG("migrate end");
+
+ g_return_if_fail(c->migrate_delayed_id == 0);
+ g_return_if_fail(spice_channel_test_capability(channel, SPICE_MAIN_CAP_SEMI_SEAMLESS_MIGRATE));
+
+ c->migrate_delayed_id = g_idle_add(migrate_delayed, channel);
+}
+
+/* main context */
+static gboolean switch_host_delayed(gpointer data)
+{
+ SpiceChannel *channel = data;
+ SpiceSession *session;
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
+
+ g_warn_if_fail(c->switch_host_delayed_id != 0);
+ c->switch_host_delayed_id = 0;
+
+ session = spice_channel_get_session(channel);
+
+ spice_channel_disconnect(channel, SPICE_CHANNEL_SWITCHING);
+ spice_session_switching_disconnect(session);
+
+ return FALSE;
+}
+
+/* coroutine context */
+static void main_handle_migrate_switch_host(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceMsgMainMigrationSwitchHost *mig = spice_msg_in_parsed(in);
+ SpiceSession *session;
+ char *host = (char *)mig->host_data;
+ char *subject = NULL;
+ SpiceMainChannelPrivate *c = SPICE_MAIN_CHANNEL(channel)->priv;
+
+ g_return_if_fail(host[mig->host_size - 1] == '\0');
+
+ if (mig->cert_subject_size) {
+ subject = (char *)mig->cert_subject_data;
+ g_return_if_fail(subject[mig->cert_subject_size - 1] == '\0');
+ }
+
+ SPICE_DEBUG("migrate_switch %s %d %d %s",
+ host, mig->port, mig->sport, subject);
+
+ if (c->switch_host_delayed_id != 0) {
+ g_warning("Switching host already in progress, aborting it");
+ g_warn_if_fail(g_source_remove(c->switch_host_delayed_id));
+ c->switch_host_delayed_id = 0;
+ }
+
+ session = spice_channel_get_session(channel);
+ spice_session_set_migration_state(session, SPICE_SESSION_MIGRATION_SWITCHING);
+ g_object_set(session,
+ "host", host,
+ "cert-subject", subject,
+ NULL);
+ spice_session_set_port(session, mig->port, FALSE);
+ spice_session_set_port(session, mig->sport, TRUE);
+
+ c->switch_host_delayed_id = g_idle_add(switch_host_delayed, channel);
+}
+
+/* coroutine context */
+static void main_handle_migrate_cancel(SpiceChannel *channel,
+ SpiceMsgIn *in G_GNUC_UNUSED)
+{
+ SpiceSession *session;
+
+ SPICE_DEBUG("migrate_cancel");
+ session = spice_channel_get_session(channel);
+ spice_session_abort_migration(session);
+}
+
+static void channel_set_handlers(SpiceChannelClass *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_MAIN_INIT ] = main_handle_init,
+ [ SPICE_MSG_MAIN_NAME ] = main_handle_name,
+ [ SPICE_MSG_MAIN_UUID ] = main_handle_uuid,
+ [ SPICE_MSG_MAIN_CHANNELS_LIST ] = main_handle_channels_list,
+ [ SPICE_MSG_MAIN_MOUSE_MODE ] = main_handle_mouse_mode,
+ [ SPICE_MSG_MAIN_MULTI_MEDIA_TIME ] = main_handle_mm_time,
+
+ [ SPICE_MSG_MAIN_AGENT_CONNECTED ] = main_handle_agent_connected,
+ [ SPICE_MSG_MAIN_AGENT_DISCONNECTED ] = main_handle_agent_disconnected,
+ [ SPICE_MSG_MAIN_AGENT_DATA ] = main_handle_agent_data,
+ [ SPICE_MSG_MAIN_AGENT_TOKEN ] = main_handle_agent_token,
+
+ [ SPICE_MSG_MAIN_MIGRATE_BEGIN ] = main_handle_migrate_begin,
+ [ SPICE_MSG_MAIN_MIGRATE_END ] = main_handle_migrate_end,
+ [ SPICE_MSG_MAIN_MIGRATE_CANCEL ] = main_handle_migrate_cancel,
+ [ SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST ] = main_handle_migrate_switch_host,
+ [ SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS ] = main_handle_agent_connected_tokens,
+ [ SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS ] = main_handle_migrate_begin_seamless,
+ [ SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK] = main_handle_migrate_dst_seamless_ack,
+ [ SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK] = main_handle_migrate_dst_seamless_nack,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
+}
+
+/* coroutine context */
+static void spice_main_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
+{
+ int type = spice_msg_in_type(msg);
+ SpiceChannelClass *parent_class;
+ SpiceChannelPrivate *c = SPICE_CHANNEL(channel)->priv;
+
+ parent_class = SPICE_CHANNEL_CLASS(spice_main_channel_parent_class);
+
+ if (c->state == SPICE_CHANNEL_STATE_MIGRATION_HANDSHAKE) {
+ if (type != SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK &&
+ type != SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK) {
+ g_critical("unexpected msg (%d)."
+ "Only MIGRATE_DST_SEAMLESS_ACK/NACK are allowed", type);
+ return;
+ }
+ }
+
+ parent_class->handle_msg(channel, msg);
+}
+
+/**
+ * spice_main_agent_test_capability:
+ * @channel: a #SpiceMainChannel
+ * @cap: an agent capability identifier
+ *
+ * Test capability of a remote agent.
+ *
+ * Returns: %TRUE if @cap (channel kind capability) is available.
+ **/
+gboolean spice_main_agent_test_capability(SpiceMainChannel *channel, guint32 cap)
+{
+ g_return_val_if_fail(SPICE_IS_MAIN_CHANNEL(channel), FALSE);
+
+ return test_agent_cap(channel, cap);
+}
+
+/**
+ * spice_main_update_display:
+ * @channel: a #SpiceMainChannel
+ * @id: display ID
+ * @x: x position
+ * @y: y position
+ * @width: display width
+ * @height: display height
+ * @update: if %TRUE, update guest resolution after 1sec.
+ *
+ * Update the display @id resolution.
+ *
+ * If @update is %TRUE, the remote configuration will be updated too
+ * after 1 second without further changes. You can send when you want
+ * without delay the new configuration to the remote with
+ * spice_main_send_monitor_config()
+ **/
+void spice_main_update_display(SpiceMainChannel *channel, int id,
+ int x, int y, int width, int height,
+ gboolean update)
+{
+ SpiceMainChannelPrivate *c;
+
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
+ g_return_if_fail(x >= 0);
+ g_return_if_fail(y >= 0);
+ g_return_if_fail(width >= 0);
+ g_return_if_fail(height >= 0);
+
+ c = SPICE_MAIN_CHANNEL(channel)->priv;
+
+ g_return_if_fail(id < SPICE_N_ELEMENTS(c->display));
+
+ SpiceDisplayConfig display = {
+ .x = x, .y = y, .width = width, .height = height,
+ .display_state = c->display[id].display_state
+ };
+
+ if (memcmp(&display, &c->display[id], sizeof(SpiceDisplayConfig)) == 0)
+ return;
+
+ c->display[id] = display;
+
+ if (update)
+ update_display_timer(channel, 1);
+}
+
+/**
+ * spice_main_set_display:
+ * @channel: a #SpiceMainChannel
+ * @id: display ID
+ * @x: x position
+ * @y: y position
+ * @width: display width
+ * @height: display height
+ *
+ * Notify the guest of screen resolution change. The notification is
+ * sent 1 second later, if no further changes happen.
+ **/
+void spice_main_set_display(SpiceMainChannel *channel, int id,
+ int x, int y, int width, int height)
+{
+ spice_main_update_display(channel, id, x, y, width, height, TRUE);
+}
+
+/**
+ * spice_main_clipboard_grab:
+ * @channel: a #SpiceMainChannel
+ * @types: an array of #VD_AGENT_CLIPBOARD types available in the clipboard
+ * @ntypes: the number of @types
+ *
+ * Grab the guest clipboard, with #VD_AGENT_CLIPBOARD @types.
+ *
+ * Deprecated: 0.6: use spice_main_clipboard_selection_grab() instead.
+ **/
+void spice_main_clipboard_grab(SpiceMainChannel *channel, guint32 *types, int ntypes)
+{
+ spice_main_clipboard_selection_grab(channel, VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD, types, ntypes);
+}
+
+/**
+ * spice_main_clipboard_selection_grab:
+ * @channel: a #SpiceMainChannel
+ * @selection: one of the clipboard #VD_AGENT_CLIPBOARD_SELECTION_*
+ * @types: an array of #VD_AGENT_CLIPBOARD types available in the clipboard
+ * @ntypes: the number of @types
+ *
+ * Grab the guest clipboard, with #VD_AGENT_CLIPBOARD @types.
+ *
+ * Since: 0.6
+ **/
+void spice_main_clipboard_selection_grab(SpiceMainChannel *channel, guint selection,
+ guint32 *types, int ntypes)
+{
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
+
+ agent_clipboard_grab(channel, selection, types, ntypes);
+ spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
+}
+
+/**
+ * spice_main_clipboard_release:
+ * @channel: a #SpiceMainChannel
+ *
+ * Release the clipboard (for example, when the client loses the
+ * clipboard grab): Inform the guest no clipboard data is available.
+ *
+ * Deprecated: 0.6: use spice_main_clipboard_selection_release() instead.
+ **/
+void spice_main_clipboard_release(SpiceMainChannel *channel)
+{
+ spice_main_clipboard_selection_release(channel, VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD);
+}
+
+/**
+ * spice_main_clipboard_selection_release:
+ * @channel: a #SpiceMainChannel
+ * @selection: one of the clipboard #VD_AGENT_CLIPBOARD_SELECTION_*
+ *
+ * Release the clipboard (for example, when the client loses the
+ * clipboard grab): Inform the guest no clipboard data is available.
+ *
+ * Since: 0.6
+ **/
+void spice_main_clipboard_selection_release(SpiceMainChannel *channel, guint selection)
+{
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
+
+ SpiceMainChannelPrivate *c = channel->priv;
+
+ if (!c->agent_connected)
+ return;
+
+ agent_clipboard_release(channel, selection);
+ spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
+}
+
+/**
+ * spice_main_clipboard_notify:
+ * @channel: a #SpiceMainChannel
+ * @type: a #VD_AGENT_CLIPBOARD type
+ * @data: clipboard data
+ * @size: data length in bytes
+ *
+ * Send the clipboard data to the guest.
+ *
+ * Deprecated: 0.6: use spice_main_clipboard_selection_notify() instead.
+ **/
+void spice_main_clipboard_notify(SpiceMainChannel *channel,
+ guint32 type, const guchar *data, size_t size)
+{
+ spice_main_clipboard_selection_notify(channel, VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD,
+ type, data, size);
+}
+
+/**
+ * spice_main_clipboard_selection_notify:
+ * @channel: a #SpiceMainChannel
+ * @selection: one of the clipboard #VD_AGENT_CLIPBOARD_SELECTION_*
+ * @type: a #VD_AGENT_CLIPBOARD type
+ * @data: clipboard data
+ * @size: data length in bytes
+ *
+ * Send the clipboard data to the guest.
+ *
+ * Since: 0.6
+ **/
+void spice_main_clipboard_selection_notify(SpiceMainChannel *channel, guint selection,
+ guint32 type, const guchar *data, size_t size)
+{
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
+
+ agent_clipboard_notify(channel, selection, type, data, size);
+ spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
+}
+
+/**
+ * spice_main_clipboard_request:
+ * @channel: a #SpiceMainChannel
+ * @type: a #VD_AGENT_CLIPBOARD type
+ *
+ * Request clipboard data of @type from the guest. The reply is sent
+ * through the #SpiceMainChannel::main-clipboard signal.
+ *
+ * Deprecated: 0.6: use spice_main_clipboard_selection_request() instead.
+ **/
+void spice_main_clipboard_request(SpiceMainChannel *channel, guint32 type)
+{
+ spice_main_clipboard_selection_request(channel, VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD, type);
+}
+
+/**
+ * spice_main_clipboard_selection_request:
+ * @channel: a #SpiceMainChannel
+ * @selection: one of the clipboard #VD_AGENT_CLIPBOARD_SELECTION_*
+ * @type: a #VD_AGENT_CLIPBOARD type
+ *
+ * Request clipboard data of @type from the guest. The reply is sent
+ * through the #SpiceMainChannel::main-clipboard-selection signal.
+ *
+ * Since: 0.6
+ **/
+void spice_main_clipboard_selection_request(SpiceMainChannel *channel, guint selection, guint32 type)
+{
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
+
+ agent_clipboard_request(channel, selection, type);
+ spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
+}
+
+/**
+ * spice_main_update_display_enabled:
+ * @channel: a #SpiceMainChannel
+ * @id: display ID (if -1: set all displays)
+ * @enabled: wether display @id is enabled
+ * @update: if %TRUE, update guest display state after 1sec.
+ *
+ * When sending monitor configuration to agent guest, if @enabled is %FALSE,
+ * don't set display @id, which the agent translates to disabling the display
+ * id. If @enabled is %TRUE, the monitor will be included in the next monitor
+ * update. Note: this will take effect next time the monitor configuration is
+ * sent.
+ *
+ * If @update is %FALSE, no server update will be triggered by this call, but
+ * the value will be saved and used in the next configuration update.
+ *
+ * Since: 0.30
+ **/
+void spice_main_update_display_enabled(SpiceMainChannel *channel, int id, gboolean enabled, gboolean update)
+{
+ SpiceDisplayState display_state = enabled ? DISPLAY_ENABLED : DISPLAY_DISABLED;
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
+ g_return_if_fail(id >= -1);
+
+ SpiceMainChannelPrivate *c = channel->priv;
+
+ if (id == -1) {
+ gint i;
+ for (i = 0; i < G_N_ELEMENTS(c->display); i++) {
+ c->display[i].display_state = display_state;
+ }
+ } else {
+ g_return_if_fail(id < G_N_ELEMENTS(c->display));
+ if (c->display[id].display_state == display_state)
+ return;
+ c->display[id].display_state = display_state;
+ }
+
+ if (update)
+ update_display_timer(channel, 1);
+}
+
+/**
+ * spice_main_set_display_enabled:
+ * @channel: a #SpiceMainChannel
+ * @id: display ID (if -1: set all displays)
+ * @enabled: wether display @id is enabled
+ *
+ * When sending monitor configuration to agent guest, don't set
+ * display @id, which the agent translates to disabling the display
+ * id. Note: this will take effect next time the monitor
+ * configuration is sent.
+ *
+ * Since: 0.6
+ **/
+void spice_main_set_display_enabled(SpiceMainChannel *channel, int id, gboolean enabled)
+{
+ spice_main_update_display_enabled(channel, id, enabled, TRUE);
+}
+
+static void file_xfer_init_task_async_cb(GObject *obj, GAsyncResult *res, gpointer data)
+{
+ GFileInfo *info;
+ SpiceFileTransferTask *xfer_task;
+ SpiceMainChannel *channel;
+ gchar *string, *basename;
+ GKeyFile *keyfile;
+ VDAgentFileXferStartMessage msg;
+ guint64 file_size;
+ gsize data_len;
+ FileTransferOperation *xfer_op;
+ GError *error = NULL;
+
+ xfer_task = SPICE_FILE_TRANSFER_TASK(obj);
+
+ info = spice_file_transfer_task_init_task_finish(xfer_task, res, &error);
+ if (info == NULL)
+ goto failed;
+
+ channel = spice_file_transfer_task_get_channel(xfer_task);
+ basename = g_file_info_get_attribute_as_string(info, G_FILE_ATTRIBUTE_STANDARD_NAME);
+ file_size = g_file_info_get_attribute_uint64(info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
+
+ xfer_op = data;
+ xfer_op->stats.transfer_size += file_size;
+
+ keyfile = g_key_file_new();
+ g_key_file_set_string(keyfile, "vdagent-file-xfer", "name", basename);
+ g_key_file_set_uint64(keyfile, "vdagent-file-xfer", "size", file_size);
+ g_free(basename);
+
+ /* Save keyfile content to memory. TODO: more file attributions
+ need to be sent to guest */
+ string = g_key_file_to_data(keyfile, &data_len, &error);
+ g_key_file_free(keyfile);
+ if (error)
+ goto failed;
+
+ /* Create file-xfer start message */
+ msg.id = spice_file_transfer_task_get_id(xfer_task);
+ agent_msg_queue_many(channel, VD_AGENT_FILE_XFER_START,
+ &msg, sizeof(msg),
+ string, data_len + 1, NULL);
+ g_free(string);
+ spice_channel_wakeup(SPICE_CHANNEL(channel), FALSE);
+ g_object_unref(info);
+ return;
+
+failed:
+ g_clear_object(&info);
+ spice_file_transfer_task_completed(xfer_task, error);
+}
+
+static void file_transfer_operation_free(FileTransferOperation *xfer_op)
+{
+ g_return_if_fail(xfer_op != NULL);
+
+ if (xfer_op->stats.failed != 0) {
+ GError *error = g_error_new(SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED,
+ "Transferring %u files: %u succeed, %u cancelled, %u failed",
+ xfer_op->stats.num_files,
+ xfer_op->stats.succeed,
+ xfer_op->stats.cancelled,
+ xfer_op->stats.failed);
+ SPICE_DEBUG("Transfer failed (%p) %s", xfer_op, error->message);
+ g_task_return_error(xfer_op->task, error);
+ } else if (xfer_op->stats.cancelled != 0 && xfer_op->stats.succeed == 0) {
+ GError *error = g_error_new(G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ "Transferring %u files: %u succeed, %u cancelled, %u failed",
+ xfer_op->stats.num_files,
+ xfer_op->stats.succeed,
+ xfer_op->stats.cancelled,
+ xfer_op->stats.failed);
+ SPICE_DEBUG("Transfer cancelled (%p) %s", xfer_op, error->message);
+ g_task_return_error(xfer_op->task, error);
+ } else {
+ SPICE_DEBUG("Transfer successful (%p)", xfer_op);
+ g_task_return_boolean(xfer_op->task, TRUE);
+ }
+ g_object_unref(xfer_op->task);
+ g_hash_table_unref(xfer_op->xfer_task);
+
+ spice_debug("Freeing file-transfer-operation %p", xfer_op);
+ g_free(xfer_op);
+}
+
+static void spice_main_channel_reset_all_xfer_operations(SpiceMainChannel *channel)
+{
+ GHashTableIter iter_all_xfer_tasks;
+ gpointer key, value;
+
+ /* Mark each of SpiceFileTransferTask as completed due error */
+ g_hash_table_iter_init(&iter_all_xfer_tasks, channel->priv->file_xfer_tasks);
+ while (g_hash_table_iter_next(&iter_all_xfer_tasks, &key, &value)) {
+ FileTransferOperation *xfer_op = value;
+ SpiceFileTransferTask *xfer_task = g_hash_table_lookup(xfer_op->xfer_task, key);
+ GError *error;
+
+ if (xfer_task == NULL) {
+ spice_warning("(reset-all) can't complete task %u - completed already?",
+ GPOINTER_TO_UINT(key));
+ continue;
+ }
+
+ error = g_error_new(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Agent connection closed");
+ spice_file_transfer_task_completed(xfer_task, error);
+ }
+}
+
+static SpiceFileTransferTask *spice_main_channel_find_xfer_task_by_task_id(SpiceMainChannel *channel,
+ guint32 task_id)
+{
+ FileTransferOperation *xfer_op;
+
+ xfer_op = g_hash_table_lookup(channel->priv->file_xfer_tasks, GUINT_TO_POINTER(task_id));
+ g_return_val_if_fail(xfer_op != NULL, NULL);
+ return g_hash_table_lookup(xfer_op->xfer_task, GUINT_TO_POINTER(task_id));
+}
+
+static void file_transfer_operation_task_finished(SpiceFileTransferTask *xfer_task,
+ GError *error,
+ gpointer userdata)
+{
+ SpiceMainChannel *channel;
+ FileTransferOperation *xfer_op;
+ guint32 task_id;
+
+ channel = spice_file_transfer_task_get_channel(xfer_task);
+ g_return_if_fail(channel != NULL);
+ task_id = spice_file_transfer_task_get_id(xfer_task);
+ g_return_if_fail(task_id != 0);
+
+ if (error) {
+ VDAgentFileXferStatusMessage msg;
+ msg.id = task_id;
+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ msg.result = VD_AGENT_FILE_XFER_STATUS_CANCELLED;
+ } else {
+ msg.result = VD_AGENT_FILE_XFER_STATUS_ERROR;
+ }
+ agent_msg_queue_many(channel, VD_AGENT_FILE_XFER_STATUS,
+ &msg, sizeof(msg), NULL);
+ }
+
+ xfer_op = g_hash_table_lookup(channel->priv->file_xfer_tasks, GUINT_TO_POINTER(task_id));
+ if (xfer_op == NULL) {
+ /* Likely the operation has ended before the remove-task was called. One
+ * situation that this can easily happen is if the agent is disconnected
+ * while there are pending files. */
+ return;
+ }
+
+ if (error) {
+ /* On error or cancellation of a SpiceFileTransferTask we remove the
+ * remaining bytes from transfer-size in order to keep the coherence of
+ * the information we provide to the user (total-sent and transfer-size)
+ * in the progress-callback */
+ guint64 file_size = spice_file_transfer_task_get_total_bytes(xfer_task);
+ guint64 bytes_read = spice_file_transfer_task_get_transferred_bytes(xfer_task);
+ xfer_op->stats.transfer_size -= (file_size - bytes_read);
+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ xfer_op->stats.cancelled++;
+ } else {
+ xfer_op->stats.failed++;
+ }
+ } else {
+ xfer_op->stats.succeed++;
+ }
+
+ /* Remove and free SpiceFileTransferTask */
+ g_hash_table_remove(xfer_op->xfer_task, GUINT_TO_POINTER(task_id));
+
+ /* Keep file_xfer_tasks up to date. If no more elements, operation is over */
+ g_hash_table_remove(channel->priv->file_xfer_tasks, GUINT_TO_POINTER(task_id));
+
+ /* No more pending operations */
+ if (g_hash_table_size(xfer_op->xfer_task) == 0)
+ file_transfer_operation_free(xfer_op);
+}
+
+static void file_transfer_operation_send_progress(SpiceFileTransferTask *xfer_task)
+{
+ FileTransferOperation *xfer_op;
+ SpiceMainChannel *channel;
+ guint32 task_id;
+
+ channel = spice_file_transfer_task_get_channel(xfer_task);
+ task_id = spice_file_transfer_task_get_id(xfer_task);
+ xfer_op = g_hash_table_lookup(channel->priv->file_xfer_tasks, GUINT_TO_POINTER(task_id));
+ g_return_if_fail(xfer_op != NULL);
+
+ if (xfer_op->progress_callback)
+ xfer_op->progress_callback(xfer_op->stats.total_sent,
+ xfer_op->stats.transfer_size,
+ xfer_op->progress_callback_data);
+}
+
+/**
+ * spice_main_file_copy_async:
+ * @channel: a #SpiceMainChannel
+ * @sources: (array zero-terminated=1): a %NULL-terminated array of #GFile objects to be transferred
+ * @flags: set of #GFileCopyFlags
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
+ * @progress_callback: (allow-none) (scope call): function to callback with
+ * progress information, or %NULL if progress information is not needed
+ * @progress_callback_data: (closure): user data to pass to @progress_callback
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: the data to pass to callback function
+ *
+ * Copies the file @sources to guest
+ *
+ * If @cancellable is not %NULL, then the operation can be cancelled by
+ * triggering the cancellable object from another thread. If the operation
+ * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
+ *
+ * If @progress_callback is not %NULL, then the operation can be monitored by
+ * setting this to a #GFileProgressCallback function. @progress_callback_data
+ * will be passed to this function. It is guaranteed that this callback will
+ * be called after all data has been transferred with the total number of bytes
+ * copied during the operation. Note that before release 0.31, progress_callback
+ * was broken since it only provided status for a single file transfer, but did
+ * not provide a way to determine which file it referred to. In release 0.31,
+ * this behavior was changed so that progress_callback provides the status of
+ * all ongoing file transfers. If you need to monitor the status of individual
+ * files, please connect to the #SpiceMainChannel::new-file-transfer signal.
+ *
+ * When the operation is finished, callback will be called. You can then call
+ * spice_main_file_copy_finish() to get the result of the operation. Note that
+ * before release 0.33 the callback was called for each file in multiple file
+ * transfer. This behavior was changed for the same reason as the
+ * progress_callback (above). If you need to monitor the ending of individual
+ * files, you can connect to "finished" signal from each SpiceFileTransferTask.
+ *
+ **/
+void spice_main_file_copy_async(SpiceMainChannel *channel,
+ GFile **sources,
+ GFileCopyFlags flags,
+ GCancellable *cancellable,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SpiceMainChannelPrivate *c;
+ GHashTableIter iter;
+ gpointer key, value;
+ FileTransferOperation *xfer_op;
+
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(SPICE_IS_MAIN_CHANNEL(channel));
+ g_return_if_fail(sources != NULL);
+
+ c = channel->priv;
+ if (!c->agent_connected) {
+ g_task_report_new_error(channel,
+ callback,
+ user_data,
+ spice_main_file_copy_async,
+ SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED,
+ "The agent is not connected");
+ return;
+ }
+
+ xfer_op = g_new0(FileTransferOperation, 1);
+ xfer_op->channel = channel;
+ xfer_op->progress_callback = progress_callback;
+ xfer_op->progress_callback_data = progress_callback_data;
+ xfer_op->task = g_task_new(channel, cancellable, callback, user_data);
+ xfer_op->xfer_task = spice_file_transfer_task_create_tasks(sources,
+ channel,
+ flags,
+ cancellable);
+ xfer_op->stats.num_files = g_hash_table_size(xfer_op->xfer_task);
+ g_hash_table_iter_init(&iter, xfer_op->xfer_task);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ guint32 task_id;
+ SpiceFileTransferTask *xfer_task = value;
+
+ task_id = spice_file_transfer_task_get_id(xfer_task);
+
+ SPICE_DEBUG("Insert a xfer task:%u to task list", task_id);
+
+ g_hash_table_insert(c->file_xfer_tasks, key, xfer_op);
+ g_signal_connect(xfer_task, "finished", G_CALLBACK(file_transfer_operation_task_finished), NULL);
+ g_signal_emit(channel, signals[SPICE_MAIN_NEW_FILE_TRANSFER], 0, xfer_task);
+
+ spice_file_transfer_task_init_task_async(xfer_task,
+ file_xfer_init_task_async_cb,
+ xfer_op);
+ }
+}
+
+/**
+ * spice_main_file_copy_finish:
+ * @channel: a #SpiceMainChannel
+ * @result: a #GAsyncResult.
+ * @error: a #GError, or %NULL
+ *
+ * Finishes copying the file started with
+ * spice_main_file_copy_async().
+ *
+ * Returns: a %TRUE on success, %FALSE on error.
+ **/
+gboolean spice_main_file_copy_finish(SpiceMainChannel *channel,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = G_TASK(result);
+
+ g_return_val_if_fail(SPICE_IS_MAIN_CHANNEL(channel), FALSE);
+ g_return_val_if_fail(g_task_is_valid(task, channel), FALSE);
+
+ return g_task_propagate_boolean(task, error);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_MAIN_CHANNEL_H__
+#define __SPICE_CLIENT_MAIN_CHANNEL_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_MAIN_CHANNEL (spice_main_channel_get_type())
+#define SPICE_MAIN_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_MAIN_CHANNEL, SpiceMainChannel))
+#define SPICE_MAIN_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_MAIN_CHANNEL, SpiceMainChannelClass))
+#define SPICE_IS_MAIN_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_MAIN_CHANNEL))
+#define SPICE_IS_MAIN_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_MAIN_CHANNEL))
+#define SPICE_MAIN_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_MAIN_CHANNEL, SpiceMainChannelClass))
+
+typedef struct _SpiceMainChannel SpiceMainChannel;
+typedef struct _SpiceMainChannelClass SpiceMainChannelClass;
+typedef struct _SpiceMainChannelPrivate SpiceMainChannelPrivate;
+
+/**
+ * SpiceMainChannel:
+ *
+ * The #SpiceMainChannel struct is opaque and should not be accessed directly.
+ */
+struct _SpiceMainChannel {
+ SpiceChannel parent;
+
+ /*< private >*/
+ SpiceMainChannelPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpiceMainChannelClass:
+ * @parent_class: Parent class.
+ * @mouse_update: Signal class handler for the #SpiceMainChannel::mouse-update signal.
+ * @agent_update: Signal class handler for the #SpiceMainChannel::agent-update signal.
+ *
+ * Class structure for #SpiceMainChannel.
+ */
+struct _SpiceMainChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*mouse_update)(SpiceChannel *channel);
+ void (*agent_update)(SpiceChannel *channel);
+
+ /*< private >*/
+ /* Do not add fields to this struct */
+};
+
+GType spice_main_channel_get_type(void);
+
+void spice_main_set_display(SpiceMainChannel *channel, int id,
+ int x, int y, int width, int height);
+void spice_main_update_display(SpiceMainChannel *channel, int id,
+ int x, int y, int width, int height, gboolean update);
+void spice_main_set_display_enabled(SpiceMainChannel *channel, int id, gboolean enabled);
+void spice_main_update_display_enabled(SpiceMainChannel *channel, int id, gboolean enabled, gboolean update);
+gboolean spice_main_send_monitor_config(SpiceMainChannel *channel);
+
+void spice_main_clipboard_selection_grab(SpiceMainChannel *channel, guint selection, guint32 *types, int ntypes);
+void spice_main_clipboard_selection_release(SpiceMainChannel *channel, guint selection);
+void spice_main_clipboard_selection_notify(SpiceMainChannel *channel, guint selection, guint32 type, const guchar *data, size_t size);
+void spice_main_clipboard_selection_request(SpiceMainChannel *channel, guint selection, guint32 type);
+
+gboolean spice_main_agent_test_capability(SpiceMainChannel *channel, guint32 cap);
+void spice_main_file_copy_async(SpiceMainChannel *channel,
+ GFile **sources,
+ GFileCopyFlags flags,
+ GCancellable *cancellable,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean spice_main_file_copy_finish(SpiceMainChannel *channel,
+ GAsyncResult *result,
+ GError **error);
+
+void spice_main_request_mouse_mode(SpiceMainChannel *channel, int mode);
+
+#ifndef SPICE_DISABLE_DEPRECATED
+SPICE_DEPRECATED_FOR(spice_main_clipboard_selection_grab)
+void spice_main_clipboard_grab(SpiceMainChannel *channel, guint32 *types, int ntypes);
+SPICE_DEPRECATED_FOR(spice_main_clipboard_selection_release)
+void spice_main_clipboard_release(SpiceMainChannel *channel);
+SPICE_DEPRECATED_FOR(spice_main_clipboard_selection_notify)
+void spice_main_clipboard_notify(SpiceMainChannel *channel, guint32 type, const guchar *data, size_t size);
+SPICE_DEPRECATED_FOR(spice_main_clipboard_selection_request)
+void spice_main_clipboard_request(SpiceMainChannel *channel, guint32 type);
+#endif
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_MAIN_CHANNEL_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_PLAYBACK_CHANNEL_PRIV_H__
+#define __SPICE_CLIENT_PLAYBACK_CHANNEL_PRIV_H__
+
+gboolean spice_playback_channel_is_active(SpicePlaybackChannel *channel);
+guint32 spice_playback_channel_get_latency(SpicePlaybackChannel *channel);
+void spice_playback_channel_sync_latency(SpicePlaybackChannel *channel);
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+#include "spice-channel-priv.h"
+#include "spice-session-priv.h"
+
+#include "spice-marshal.h"
+
+#include "common/snd_codec.h"
+#include "channel-playback-priv.h"
+
+/**
+ * SECTION:channel-playback
+ * @short_description: audio stream for playback
+ * @title: Playback Channel
+ * @section_id:
+ * @see_also: #SpiceChannel, and #SpiceAudio
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * #SpicePlaybackChannel class handles an audio playback stream. The
+ * audio data is received via #SpicePlaybackChannel::playback-data
+ * signal, and is controlled by the guest with
+ * #SpicePlaybackChannel::playback-stop and
+ * #SpicePlaybackChannel::playback-start signal events.
+ *
+ * Note: You may be interested to let the #SpiceAudio class play and
+ * record audio channels for your application.
+ */
+
+#define SPICE_PLAYBACK_CHANNEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_PLAYBACK_CHANNEL, SpicePlaybackChannelPrivate))
+
+struct _SpicePlaybackChannelPrivate {
+ int mode;
+ SndCodec codec;
+ guint32 frame_count;
+ guint32 last_time;
+ guint8 nchannels;
+ guint16 *volume;
+ guint8 mute;
+ gboolean is_active;
+ guint32 latency;
+ guint32 min_latency;
+};
+
+G_DEFINE_TYPE(SpicePlaybackChannel, spice_playback_channel, SPICE_TYPE_CHANNEL)
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_NCHANNELS,
+ PROP_VOLUME,
+ PROP_MUTE,
+ PROP_MIN_LATENCY,
+};
+
+/* Signals */
+enum {
+ SPICE_PLAYBACK_START,
+ SPICE_PLAYBACK_DATA,
+ SPICE_PLAYBACK_STOP,
+ SPICE_PLAYBACK_GET_DELAY,
+
+ SPICE_PLAYBACK_LAST_SIGNAL,
+};
+
+static guint signals[SPICE_PLAYBACK_LAST_SIGNAL];
+static void channel_set_handlers(SpiceChannelClass *klass);
+
+/* ------------------------------------------------------------------ */
+
+#define SPICE_PLAYBACK_DEFAULT_LATENCY_MS 200
+
+static void spice_playback_channel_reset_capabilities(SpiceChannel *channel)
+{
+ if (!g_getenv("SPICE_DISABLE_CELT"))
+ if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY))
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_CELT_0_5_1);
+ if (!g_getenv("SPICE_DISABLE_OPUS"))
+ if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_OPUS, SND_CODEC_ANY_FREQUENCY))
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_OPUS);
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_VOLUME);
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_PLAYBACK_CAP_LATENCY);
+}
+
+static void spice_playback_channel_init(SpicePlaybackChannel *channel)
+{
+ channel->priv = SPICE_PLAYBACK_CHANNEL_GET_PRIVATE(channel);
+
+ spice_playback_channel_reset_capabilities(SPICE_CHANNEL(channel));
+}
+
+static void spice_playback_channel_finalize(GObject *obj)
+{
+ SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(obj)->priv;
+
+ snd_codec_destroy(&c->codec);
+
+ g_clear_pointer(&c->volume, g_free);
+
+ if (G_OBJECT_CLASS(spice_playback_channel_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_playback_channel_parent_class)->finalize(obj);
+}
+
+static void spice_playback_channel_get_property(GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpicePlaybackChannel *channel = SPICE_PLAYBACK_CHANNEL(gobject);
+ SpicePlaybackChannelPrivate *c = channel->priv;
+
+ switch (prop_id) {
+ case PROP_VOLUME:
+ g_value_set_pointer(value, c->volume);
+ break;
+ case PROP_NCHANNELS:
+ g_value_set_uint(value, c->nchannels);
+ break;
+ case PROP_MUTE:
+ g_value_set_boolean(value, c->mute);
+ break;
+ case PROP_MIN_LATENCY:
+ g_value_set_uint(value, c->min_latency);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_playback_channel_set_property(GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_VOLUME:
+ /* TODO: request guest volume change */
+ break;
+ case PROP_MUTE:
+ /* TODO: request guest mute change */
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+/* main or coroutine context */
+static void spice_playback_channel_reset(SpiceChannel *channel, gboolean migrating)
+{
+ SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
+
+ snd_codec_destroy(&c->codec);
+ g_coroutine_signal_emit(channel, signals[SPICE_PLAYBACK_STOP], 0);
+ c->is_active = FALSE;
+
+ SPICE_CHANNEL_CLASS(spice_playback_channel_parent_class)->channel_reset(channel, migrating);
+}
+
+static void spice_playback_channel_class_init(SpicePlaybackChannelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
+
+ gobject_class->finalize = spice_playback_channel_finalize;
+ gobject_class->get_property = spice_playback_channel_get_property;
+ gobject_class->set_property = spice_playback_channel_set_property;
+
+ channel_class->channel_reset = spice_playback_channel_reset;
+ channel_class->channel_reset_capabilities = spice_playback_channel_reset_capabilities;
+
+ g_object_class_install_property
+ (gobject_class, PROP_NCHANNELS,
+ g_param_spec_uint("nchannels",
+ "Number of Channels",
+ "Number of Channels",
+ 0, G_MAXUINT8, 2,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_VOLUME,
+ g_param_spec_pointer("volume",
+ "Playback volume",
+ "Playback volume",
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_MUTE,
+ g_param_spec_boolean("mute",
+ "Mute",
+ "Mute",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property
+ (gobject_class, PROP_MIN_LATENCY,
+ g_param_spec_uint("min-latency",
+ "Playback min buffer size (ms)",
+ "Playback min buffer size (ms)",
+ 0, G_MAXUINT32, SPICE_PLAYBACK_DEFAULT_LATENCY_MS,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+ /**
+ * SpicePlaybackChannel::playback-start:
+ * @channel: the #SpicePlaybackChannel that emitted the signal
+ * @format: a #SPICE_AUDIO_FMT
+ * @channels: number of channels
+ * @rate: audio rate
+ * @latency: minimum playback latency in ms
+ *
+ * Notify when the playback should start, and provide audio format
+ * characteristics.
+ **/
+ signals[SPICE_PLAYBACK_START] =
+ g_signal_new("playback-start",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpicePlaybackChannelClass, playback_start),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__INT_INT_INT,
+ G_TYPE_NONE,
+ 3,
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+
+ /**
+ * SpicePlaybackChannel::playback-data:
+ * @channel: the #SpicePlaybackChannel that emitted the signal
+ * @data: pointer to audio data
+ * @data_size: size in byte of @data
+ *
+ * Provide audio data to be played.
+ **/
+ signals[SPICE_PLAYBACK_DATA] =
+ g_signal_new("playback-data",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpicePlaybackChannelClass, playback_data),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__POINTER_INT,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_POINTER, G_TYPE_INT);
+
+ /**
+ * SpicePlaybackChannel::playback-stop:
+ * @channel: the #SpicePlaybackChannel that emitted the signal
+ *
+ * Notify when the playback should stop.
+ **/
+ signals[SPICE_PLAYBACK_STOP] =
+ g_signal_new("playback-stop",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpicePlaybackChannelClass, playback_stop),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ /**
+ * SpicePlaybackChannel::playback-get-delay:
+ * @channel: the #SpicePlaybackChannel that emitted the signal
+ *
+ * Notify when the current playback delay is requested
+ **/
+ signals[SPICE_PLAYBACK_GET_DELAY] =
+ g_signal_new("playback-get-delay",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_class_add_private(klass, sizeof(SpicePlaybackChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
+}
+
+/* ------------------------------------------------------------------ */
+
+/* coroutine context */
+static void playback_handle_data(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
+ SpiceMsgPlaybackPacket *packet = spice_msg_in_parsed(in);
+
+#ifdef DEBUG
+ CHANNEL_DEBUG(channel, "%s: time %u data %p size %d", __FUNCTION__,
+ packet->time, packet->data, packet->data_size);
+#endif
+
+ if (c->last_time > packet->time)
+ g_warn_if_reached();
+
+ c->last_time = packet->time;
+
+ uint8_t *data = packet->data;
+ int n = packet->data_size;
+ uint8_t pcm[SND_CODEC_MAX_FRAME_SIZE * 2 * 2];
+
+ if (c->mode != SPICE_AUDIO_DATA_MODE_RAW) {
+ n = sizeof(pcm);
+ data = pcm;
+
+ if (snd_codec_decode(c->codec, packet->data, packet->data_size,
+ pcm, &n) != SND_CODEC_OK) {
+ g_warning("snd_codec_decode() error");
+ return;
+ }
+ }
+
+ g_coroutine_signal_emit(channel, signals[SPICE_PLAYBACK_DATA], 0, data, n);
+
+ if ((c->frame_count++ % 100) == 0) {
+ g_coroutine_signal_emit(channel, signals[SPICE_PLAYBACK_GET_DELAY], 0);
+ }
+}
+
+/* coroutine context */
+static void playback_handle_mode(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
+ SpiceMsgPlaybackMode *mode = spice_msg_in_parsed(in);
+
+ CHANNEL_DEBUG(channel, "%s: time %u mode %u data %p size %u", __FUNCTION__,
+ mode->time, mode->mode, mode->data, mode->data_size);
+
+ c->mode = mode->mode;
+ switch (c->mode) {
+ case SPICE_AUDIO_DATA_MODE_RAW:
+ case SPICE_AUDIO_DATA_MODE_CELT_0_5_1:
+ case SPICE_AUDIO_DATA_MODE_OPUS:
+ break;
+ default:
+ g_warning("%s: unhandled mode", __FUNCTION__);
+ break;
+ }
+}
+
+/* coroutine context */
+static void playback_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
+ SpiceMsgPlaybackStart *start = spice_msg_in_parsed(in);
+
+ CHANNEL_DEBUG(channel, "%s: fmt %u channels %u freq %u time %u", __FUNCTION__,
+ start->format, start->channels, start->frequency, start->time);
+
+ c->frame_count = 0;
+ c->last_time = start->time;
+ c->is_active = TRUE;
+ c->min_latency = SPICE_PLAYBACK_DEFAULT_LATENCY_MS;
+ snd_codec_destroy(&c->codec);
+
+ if (c->mode != SPICE_AUDIO_DATA_MODE_RAW) {
+ if (snd_codec_create(&c->codec, c->mode, start->frequency, SND_CODEC_DECODE) != SND_CODEC_OK) {
+ g_warning("create decoder failed");
+ return;
+ }
+ }
+ g_coroutine_signal_emit(channel, signals[SPICE_PLAYBACK_START], 0,
+ start->format, start->channels, start->frequency);
+}
+
+/* coroutine context */
+static void playback_handle_stop(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
+
+ g_coroutine_signal_emit(channel, signals[SPICE_PLAYBACK_STOP], 0);
+ c->is_active = FALSE;
+}
+
+/* coroutine context */
+static void playback_handle_set_volume(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
+ SpiceMsgAudioVolume *vol = spice_msg_in_parsed(in);
+
+ if (vol->nchannels == 0) {
+ g_warning("spice-server send audio-volume-msg with 0 channels");
+ return;
+ }
+
+ g_free(c->volume);
+ c->nchannels = vol->nchannels;
+ c->volume = g_new(guint16, c->nchannels);
+ memcpy(c->volume, vol->volume, sizeof(guint16) * c->nchannels);
+ g_coroutine_object_notify(G_OBJECT(channel), "volume");
+}
+
+/* coroutine context */
+static void playback_handle_set_mute(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
+ SpiceMsgAudioMute *m = spice_msg_in_parsed(in);
+
+ c->mute = m->mute;
+ g_coroutine_object_notify(G_OBJECT(channel), "mute");
+}
+
+/* coroutine context */
+static void playback_handle_set_latency(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpicePlaybackChannelPrivate *c = SPICE_PLAYBACK_CHANNEL(channel)->priv;
+ SpiceMsgPlaybackLatency *msg = spice_msg_in_parsed(in);
+
+ c->min_latency = msg->latency_ms;
+ SPICE_DEBUG("%s: notify latency update %u", __FUNCTION__, c->min_latency);
+ g_coroutine_object_notify(G_OBJECT(channel), "min-latency");
+}
+
+static void channel_set_handlers(SpiceChannelClass *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_PLAYBACK_DATA ] = playback_handle_data,
+ [ SPICE_MSG_PLAYBACK_MODE ] = playback_handle_mode,
+ [ SPICE_MSG_PLAYBACK_START ] = playback_handle_start,
+ [ SPICE_MSG_PLAYBACK_STOP ] = playback_handle_stop,
+ [ SPICE_MSG_PLAYBACK_VOLUME ] = playback_handle_set_volume,
+ [ SPICE_MSG_PLAYBACK_MUTE ] = playback_handle_set_mute,
+ [ SPICE_MSG_PLAYBACK_LATENCY ] = playback_handle_set_latency,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
+}
+
+/**
+ * spice_playback_channel_set_delay:
+ * @channel: a #SpicePlaybackChannel
+ * @delay_ms: the delay in ms
+ *
+ * Adjust the multimedia time according to the delay.
+ **/
+void spice_playback_channel_set_delay(SpicePlaybackChannel *channel, guint32 delay_ms)
+{
+ SpicePlaybackChannelPrivate *c;
+ SpiceSession *session;
+
+ g_return_if_fail(SPICE_IS_PLAYBACK_CHANNEL(channel));
+
+ CHANNEL_DEBUG(channel, "playback set_delay %u ms", delay_ms);
+
+ c = channel->priv;
+ c->latency = delay_ms;
+
+ session = spice_channel_get_session(SPICE_CHANNEL(channel));
+ if (session) {
+ spice_session_set_mm_time(session, c->last_time - delay_ms);
+ } else {
+ CHANNEL_DEBUG(channel, "channel detached from session, mm time skipped");
+ }
+}
+
+G_GNUC_INTERNAL
+gboolean spice_playback_channel_is_active(SpicePlaybackChannel *channel)
+{
+ g_return_val_if_fail(SPICE_IS_PLAYBACK_CHANNEL(channel), FALSE);
+ return channel->priv->is_active;
+}
+
+G_GNUC_INTERNAL
+guint32 spice_playback_channel_get_latency(SpicePlaybackChannel *channel)
+{
+ g_return_val_if_fail(SPICE_IS_PLAYBACK_CHANNEL(channel), 0);
+ if (!channel->priv->is_active) {
+ return 0;
+ }
+ return channel->priv->latency;
+}
+
+G_GNUC_INTERNAL
+void spice_playback_channel_sync_latency(SpicePlaybackChannel *channel)
+{
+ g_return_if_fail(SPICE_IS_PLAYBACK_CHANNEL(channel));
+ g_return_if_fail(channel->priv->is_active);
+ SPICE_DEBUG("%s: notify latency update %u", __FUNCTION__, channel->priv->min_latency);
+ g_coroutine_object_notify(G_OBJECT(SPICE_CHANNEL(channel)), "min-latency");
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_PLAYBACK_CHANNEL_H__
+#define __SPICE_CLIENT_PLAYBACK_CHANNEL_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_PLAYBACK_CHANNEL (spice_playback_channel_get_type())
+#define SPICE_PLAYBACK_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_PLAYBACK_CHANNEL, SpicePlaybackChannel))
+#define SPICE_PLAYBACK_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_PLAYBACK_CHANNEL, SpicePlaybackChannelClass))
+#define SPICE_IS_PLAYBACK_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_PLAYBACK_CHANNEL))
+#define SPICE_IS_PLAYBACK_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_PLAYBACK_CHANNEL))
+#define SPICE_PLAYBACK_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_PLAYBACK_CHANNEL, SpicePlaybackChannelClass))
+
+typedef struct _SpicePlaybackChannel SpicePlaybackChannel;
+typedef struct _SpicePlaybackChannelClass SpicePlaybackChannelClass;
+typedef struct _SpicePlaybackChannelPrivate SpicePlaybackChannelPrivate;
+
+/**
+ * SpicePlaybackChannel:
+ *
+ * The #SpicePlaybackChannel struct is opaque and should not be accessed directly.
+ */
+struct _SpicePlaybackChannel {
+ SpiceChannel parent;
+
+ /*< private >*/
+ SpicePlaybackChannelPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpicePlaybackChannelClass:
+ * @parent_class: Parent class.
+ * @playback_start: Signal class handler for the #SpicePlaybackChannel::playback-start signal.
+ * @playback_data: Signal class handler for the #SpicePlaybackChannel::playback-data signal.
+ * @playback_stop: Signal class handler for the #SpicePlaybackChannel::playback-stop signal.
+ *
+ * Class structure for #SpicePlaybackChannel.
+ */
+struct _SpicePlaybackChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*playback_start)(SpicePlaybackChannel *channel,
+ gint format, gint channels, gint freq);
+ void (*playback_data)(SpicePlaybackChannel *channel, gpointer *data, gint size);
+ void (*playback_stop)(SpicePlaybackChannel *channel);
+
+ /*< private >*/
+ /* Do not add fields to this struct */
+};
+
+GType spice_playback_channel_get_type(void);
+void spice_playback_channel_set_delay(SpicePlaybackChannel *channel, guint32 delay_ms);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_PLAYBACK_CHANNEL_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+#include "spice-channel-priv.h"
+#include "spice-marshal.h"
+
+/**
+ * SECTION:channel-port
+ * @short_description: private communication channel
+ * @title: Port Channel
+ * @section_id:
+ * @see_also: #SpiceChannel
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * A Spice port channel carry arbitrary data between the Spice client
+ * and the Spice server. It may be used to provide additional
+ * services on top of a Spice connection. For example, a channel can
+ * be associated with the qemu monitor for the client to interact
+ * with it, just like any qemu chardev. Or it may be used with
+ * various protocols, such as the Spice Controller.
+ *
+ * A port kind is identified simply by a fqdn, such as
+ * org.qemu.monitor, org.spice.spicy.test or org.ovirt.controller...
+ *
+ * Once connected and initialized, the client may read the name of the
+ * port via SpicePortChannel:port-name.
+
+ * When the other end of the port is ready,
+ * SpicePortChannel:port-opened is set to %TRUE and you can start
+ * receiving data via the signal SpicePortChannel::port-data, or
+ * sending data via spice_port_write_async().
+ *
+ * Since: 0.15
+ */
+
+#define SPICE_PORT_CHANNEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_PORT_CHANNEL, SpicePortChannelPrivate))
+
+struct _SpicePortChannelPrivate {
+ gchar *name;
+ gboolean opened;
+};
+
+G_DEFINE_TYPE(SpicePortChannel, spice_port_channel, SPICE_TYPE_CHANNEL)
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_PORT_NAME,
+ PROP_PORT_OPENED,
+};
+
+/* Signals */
+enum {
+ SPICE_PORT_DATA,
+ SPICE_PORT_EVENT,
+ LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL];
+static void channel_set_handlers(SpiceChannelClass *klass);
+
+static void spice_port_channel_init(SpicePortChannel *channel)
+{
+ channel->priv = SPICE_PORT_CHANNEL_GET_PRIVATE(channel);
+}
+
+static void spice_port_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpicePortChannelPrivate *c = SPICE_PORT_CHANNEL(object)->priv;
+
+ switch (prop_id) {
+ case PROP_PORT_NAME:
+ g_value_set_string(value, c->name);
+ break;
+ case PROP_PORT_OPENED:
+ g_value_set_boolean(value, c->opened);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_port_channel_finalize(GObject *object)
+{
+ SpicePortChannelPrivate *c = SPICE_PORT_CHANNEL(object)->priv;
+
+ g_free(c->name);
+
+ if (G_OBJECT_CLASS(spice_port_channel_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_port_channel_parent_class)->finalize(object);
+}
+
+static void spice_port_channel_reset(SpiceChannel *channel, gboolean migrating)
+{
+ SpicePortChannelPrivate *c = SPICE_PORT_CHANNEL(channel)->priv;
+
+ g_clear_pointer(&c->name, g_free);
+ c->opened = FALSE;
+
+ SPICE_CHANNEL_CLASS(spice_port_channel_parent_class)->channel_reset(channel, migrating);
+}
+
+static void spice_port_channel_class_init(SpicePortChannelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
+
+ gobject_class->finalize = spice_port_channel_finalize;
+ gobject_class->get_property = spice_port_get_property;
+ channel_class->channel_reset = spice_port_channel_reset;
+
+ g_object_class_install_property
+ (gobject_class, PROP_PORT_NAME,
+ g_param_spec_string("port-name",
+ "Port name",
+ "Port name",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_PORT_OPENED,
+ g_param_spec_boolean("port-opened",
+ "Port opened",
+ "Port opened",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpicePortChannel::port-data:
+ * @channel: the channel that emitted the signal
+ * @data: the data received
+ * @size: number of bytes read
+ *
+ * The #SpicePortChannel::port-data signal is emitted when new
+ * port data is received.
+ * Since: 0.15
+ **/
+ signals[SPICE_PORT_DATA] =
+ g_signal_new("port-data",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__POINTER_INT,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_POINTER, G_TYPE_INT);
+
+
+ /**
+ * SpicePortChannel::port-event:
+ * @channel: the channel that emitted the signal
+ * @event: the event received
+ * @size: number of bytes read
+ *
+ * The #SpicePortChannel::port-event signal is emitted when new
+ * port event is received.
+ * Since: 0.15
+ **/
+ signals[SPICE_PORT_EVENT] =
+ g_signal_new("port-event",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+
+ g_type_class_add_private(klass, sizeof(SpicePortChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
+}
+
+
+/* coroutine context */
+static void port_set_opened(SpicePortChannel *self, gboolean opened)
+{
+ SpicePortChannelPrivate *c = self->priv;
+
+ if (c->opened == opened)
+ return;
+
+ c->opened = opened;
+ g_coroutine_object_notify(G_OBJECT(self), "port-opened");
+}
+
+/* coroutine context */
+static void port_handle_init(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpicePortChannel *self = SPICE_PORT_CHANNEL(channel);
+ SpicePortChannelPrivate *c = self->priv;
+ SpiceMsgPortInit *init = spice_msg_in_parsed(in);
+
+ CHANNEL_DEBUG(channel, "init: %s %d", init->name, init->opened);
+ g_return_if_fail(init->name != NULL && *init->name != '\0');
+ g_return_if_fail(c->name == NULL);
+
+ c->name = g_strdup((gchar*)init->name);
+
+ port_set_opened(self, init->opened);
+ if (init->opened)
+ g_coroutine_signal_emit(channel, signals[SPICE_PORT_EVENT], 0, SPICE_PORT_EVENT_OPENED);
+
+ g_coroutine_object_notify(G_OBJECT(channel), "port-name");
+}
+
+/* coroutine context */
+static void port_handle_event(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpicePortChannel *self = SPICE_PORT_CHANNEL(channel);
+ SpiceMsgPortEvent *event = spice_msg_in_parsed(in);
+
+ CHANNEL_DEBUG(channel, "port event: %d", event->event);
+ switch (event->event) {
+ case SPICE_PORT_EVENT_OPENED:
+ port_set_opened(self, true);
+ break;
+ case SPICE_PORT_EVENT_CLOSED:
+ port_set_opened(self, false);
+ break;
+ }
+
+ g_coroutine_signal_emit(channel, signals[SPICE_PORT_EVENT], 0, event->event);
+}
+
+/* coroutine context */
+static void port_handle_msg(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpicePortChannel *self = SPICE_PORT_CHANNEL(channel);
+ int size;
+ uint8_t *buf;
+
+ buf = spice_msg_in_raw(in, &size);
+ CHANNEL_DEBUG(channel, "port %p got %d %p", channel, size, buf);
+ port_set_opened(self, true);
+ g_coroutine_signal_emit(channel, signals[SPICE_PORT_DATA], 0, buf, size);
+}
+
+/**
+ * spice_port_write_async:
+ * @port: A #SpicePortChannel
+ * @buffer: (array length=count) (element-type guint8): the buffer
+ * containing the data to write
+ * @count: the number of bytes to write
+ * @cancellable: (allow-none): optional GCancellable object, NULL to ignore
+ * @callback: (scope async): callback to call when the request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Request an asynchronous write of count bytes from @buffer into the
+ * @port. When the operation is finished @callback will be called. You
+ * can then call spice_port_write_finish() to get the result of
+ * the operation.
+ *
+ * Since: 0.15
+ **/
+void spice_port_write_async(SpicePortChannel *self,
+ const void *buffer, gsize count,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SpicePortChannelPrivate *c;
+
+ g_return_if_fail(SPICE_IS_PORT_CHANNEL(self));
+ g_return_if_fail(buffer != NULL);
+ c = self->priv;
+
+ if (!c->opened) {
+ g_task_report_new_error(self, callback,
+ user_data, spice_port_write_async,
+ SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "The port is not opened");
+ return;
+ }
+
+ spice_vmc_write_async(SPICE_CHANNEL(self), buffer, count,
+ cancellable, callback, user_data);
+}
+
+/**
+ * spice_port_write_finish:
+ * @port: a #SpicePortChannel
+ * @result: a #GAsyncResult
+ * @error: a #GError location to store the error occurring, or %NULL
+ * to ignore
+ *
+ * Finishes a port write operation.
+ *
+ * Returns: a #gssize containing the number of bytes written to the stream.
+ * Since: 0.15
+ **/
+gssize spice_port_write_finish(SpicePortChannel *self,
+ GAsyncResult *result, GError **error)
+{
+ g_return_val_if_fail(SPICE_IS_PORT_CHANNEL(self), -1);
+
+ return spice_vmc_write_finish(SPICE_CHANNEL(self), result, error);
+}
+
+/**
+ * spice_port_event:
+ * @port: a #SpicePortChannel
+ * @event: a SPICE_PORT_EVENT value
+ *
+ * Send an event to the port.
+ *
+ * Note: The values SPICE_PORT_EVENT_CLOSED and
+ * SPICE_PORT_EVENT_OPENED are managed by the channel connection
+ * state.
+ *
+ * Since: 0.15
+ **/
+void spice_port_event(SpicePortChannel *self, guint8 event)
+{
+ SpiceMsgcPortEvent e;
+ SpiceMsgOut *msg;
+
+ g_return_if_fail(SPICE_IS_PORT_CHANNEL(self));
+ g_return_if_fail(event > SPICE_PORT_EVENT_CLOSED);
+
+ msg = spice_msg_out_new(SPICE_CHANNEL(self), SPICE_MSGC_PORT_EVENT);
+ e.event = event;
+ msg->marshallers->msgc_port_event(msg->marshaller, &e);
+ spice_msg_out_send(msg);
+}
+
+static void channel_set_handlers(SpiceChannelClass *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_PORT_INIT ] = port_handle_init,
+ [ SPICE_MSG_PORT_EVENT ] = port_handle_event,
+ [ SPICE_MSG_SPICEVMC_DATA ] = port_handle_msg,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_PORT_CHANNEL_H__
+#define __SPICE_CLIENT_PORT_CHANNEL_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include <gio/gio.h>
+#include "spice-channel.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_PORT_CHANNEL (spice_port_channel_get_type())
+#define SPICE_PORT_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_PORT_CHANNEL, SpicePortChannel))
+#define SPICE_PORT_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_PORT_CHANNEL, SpicePortChannelClass))
+#define SPICE_IS_PORT_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_PORT_CHANNEL))
+#define SPICE_IS_PORT_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_PORT_CHANNEL))
+#define SPICE_PORT_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_PORT_CHANNEL, SpicePortChannelClass))
+
+typedef struct _SpicePortChannel SpicePortChannel;
+typedef struct _SpicePortChannelClass SpicePortChannelClass;
+typedef struct _SpicePortChannelPrivate SpicePortChannelPrivate;
+
+/**
+ * SpicePortChannel:
+ *
+ * The #SpicePortChannel struct is opaque and should not be accessed directly.
+ */
+struct _SpicePortChannel {
+ SpiceChannel parent;
+
+ /*< private >*/
+ SpicePortChannelPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpicePortChannelClass:
+ * @parent_class: Parent class.
+ *
+ * Class structure for #SpicePortChannel.
+ */
+struct _SpicePortChannelClass {
+ SpiceChannelClass parent_class;
+
+ /*< private >*/
+ /* Do not add fields to this struct */
+};
+
+GType spice_port_channel_get_type(void);
+
+void spice_port_write_async(SpicePortChannel *port,
+ const void *buffer, gsize count,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gssize spice_port_write_finish(SpicePortChannel *port,
+ GAsyncResult *result, GError **error);
+void spice_port_event(SpicePortChannel *port, guint8 event);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_PORT_CHANNEL_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+#include "spice-channel-priv.h"
+
+#include "spice-marshal.h"
+#include "spice-session-priv.h"
+
+#include "common/snd_codec.h"
+
+/**
+ * SECTION:channel-record
+ * @short_description: audio stream for recording
+ * @title: Record Channel
+ * @section_id:
+ * @see_also: #SpiceChannel, and #SpiceAudio
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * #SpiceRecordChannel class handles an audio recording stream. The
+ * audio stream should start when #SpiceRecordChannel::record-start is
+ * emitted and should be stopped when #SpiceRecordChannel::record-stop
+ * is received.
+ *
+ * The audio is sent to the guest by calling spice_record_send_data()
+ * with the recorded PCM data.
+ *
+ * Note: You may be interested to let the #SpiceAudio class play and
+ * record audio channels for your application.
+ */
+
+#define SPICE_RECORD_CHANNEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_RECORD_CHANNEL, SpiceRecordChannelPrivate))
+
+struct _SpiceRecordChannelPrivate {
+ int mode;
+ gboolean started;
+ SndCodec codec;
+ gsize frame_bytes;
+ guint8 *last_frame;
+ gsize last_frame_current;
+ guint8 nchannels;
+ guint16 *volume;
+ guint8 mute;
+};
+
+G_DEFINE_TYPE(SpiceRecordChannel, spice_record_channel, SPICE_TYPE_CHANNEL)
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_NCHANNELS,
+ PROP_VOLUME,
+ PROP_MUTE,
+};
+
+/* Signals */
+enum {
+ SPICE_RECORD_START,
+ SPICE_RECORD_STOP,
+
+ SPICE_RECORD_LAST_SIGNAL,
+};
+
+static guint signals[SPICE_RECORD_LAST_SIGNAL];
+
+static void channel_set_handlers(SpiceChannelClass *klass);
+
+/* ------------------------------------------------------------------ */
+
+static void spice_record_channel_reset_capabilities(SpiceChannel *channel)
+{
+ if (!g_getenv("SPICE_DISABLE_CELT"))
+ if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, SND_CODEC_ANY_FREQUENCY))
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_RECORD_CAP_CELT_0_5_1);
+ if (!g_getenv("SPICE_DISABLE_OPUS"))
+ if (snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_OPUS, SND_CODEC_ANY_FREQUENCY))
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_RECORD_CAP_OPUS);
+ spice_channel_set_capability(SPICE_CHANNEL(channel), SPICE_RECORD_CAP_VOLUME);
+}
+
+static void spice_record_channel_init(SpiceRecordChannel *channel)
+{
+ channel->priv = SPICE_RECORD_CHANNEL_GET_PRIVATE(channel);
+
+ spice_record_channel_reset_capabilities(SPICE_CHANNEL(channel));
+}
+
+static void spice_record_channel_finalize(GObject *obj)
+{
+ SpiceRecordChannelPrivate *c = SPICE_RECORD_CHANNEL(obj)->priv;
+
+ g_clear_pointer(&c->last_frame, g_free);
+
+ snd_codec_destroy(&c->codec);
+
+ g_clear_pointer(&c->volume, g_free);
+
+ if (G_OBJECT_CLASS(spice_record_channel_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_record_channel_parent_class)->finalize(obj);
+}
+
+static void spice_record_channel_get_property(GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceRecordChannel *channel = SPICE_RECORD_CHANNEL(gobject);
+ SpiceRecordChannelPrivate *c = channel->priv;
+
+ switch (prop_id) {
+ case PROP_VOLUME:
+ g_value_set_pointer(value, c->volume);
+ break;
+ case PROP_NCHANNELS:
+ g_value_set_uint(value, c->nchannels);
+ break;
+ case PROP_MUTE:
+ g_value_set_boolean(value, c->mute);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_record_channel_set_property(GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_VOLUME:
+ /* TODO: request guest volume change */
+ break;
+ case PROP_MUTE:
+ /* TODO: request guest mute change */
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void channel_reset(SpiceChannel *channel, gboolean migrating)
+{
+ SpiceRecordChannelPrivate *c = SPICE_RECORD_CHANNEL(channel)->priv;
+
+ g_clear_pointer(&c->last_frame, g_free);
+
+ g_coroutine_signal_emit(channel, signals[SPICE_RECORD_STOP], 0);
+ c->started = FALSE;
+
+ snd_codec_destroy(&c->codec);
+
+ SPICE_CHANNEL_CLASS(spice_record_channel_parent_class)->channel_reset(channel, migrating);
+}
+
+static void spice_record_channel_class_init(SpiceRecordChannelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
+
+ gobject_class->finalize = spice_record_channel_finalize;
+ gobject_class->get_property = spice_record_channel_get_property;
+ gobject_class->set_property = spice_record_channel_set_property;
+ channel_class->channel_reset = channel_reset;
+ channel_class->channel_reset_capabilities = spice_record_channel_reset_capabilities;
+
+ g_object_class_install_property
+ (gobject_class, PROP_NCHANNELS,
+ g_param_spec_uint("nchannels",
+ "Number of Channels",
+ "Number of Channels",
+ 0, G_MAXUINT8, 2,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_VOLUME,
+ g_param_spec_pointer("volume",
+ "Record volume",
+ "Record volume",
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_MUTE,
+ g_param_spec_boolean("mute",
+ "Mute",
+ "Mute",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+ /**
+ * SpiceRecordChannel::record-start:
+ * @channel: the #SpiceRecordChannel that emitted the signal
+ * @format: a #SPICE_AUDIO_FMT
+ * @channels: number of channels
+ * @rate: audio rate
+ *
+ * Notify when the recording should start, and provide audio format
+ * characteristics.
+ **/
+ signals[SPICE_RECORD_START] =
+ g_signal_new("record-start",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceRecordChannelClass, record_start),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__INT_INT_INT,
+ G_TYPE_NONE,
+ 3,
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+
+ /**
+ * SpiceRecordChannel::record-stop:
+ * @channel: the #SpiceRecordChannel that emitted the signal
+ *
+ * Notify when the recording should stop.
+ **/
+ signals[SPICE_RECORD_STOP] =
+ g_signal_new("record-stop",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceRecordChannelClass, record_stop),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_class_add_private(klass, sizeof(SpiceRecordChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
+}
+
+/* main context */
+static void spice_record_mode(SpiceRecordChannel *channel, uint32_t time,
+ uint32_t mode, uint8_t *data, uint32_t data_size)
+{
+ SpiceMsgcRecordMode m = {0, };
+ SpiceMsgOut *msg;
+
+ g_return_if_fail(channel != NULL);
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
+ m.mode = mode;
+ m.time = time;
+ m.data = data;
+ m.data_size = data_size;
+
+ msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_RECORD_MODE);
+ msg->marshallers->msgc_record_mode(msg->marshaller, &m);
+ spice_msg_out_send(msg);
+}
+
+static int spice_record_desired_mode(SpiceChannel *channel, int frequency)
+{
+ if (!g_getenv("SPICE_DISABLE_OPUS") &&
+ snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_OPUS, frequency) &&
+ spice_channel_test_capability(channel, SPICE_RECORD_CAP_OPUS)) {
+ return SPICE_AUDIO_DATA_MODE_OPUS;
+ } else if (!g_getenv("SPICE_DISABLE_CELT") &&
+ snd_codec_is_capable(SPICE_AUDIO_DATA_MODE_CELT_0_5_1, frequency) &&
+ spice_channel_test_capability(channel, SPICE_RECORD_CAP_CELT_0_5_1)) {
+ return SPICE_AUDIO_DATA_MODE_CELT_0_5_1;
+ } else {
+ return SPICE_AUDIO_DATA_MODE_RAW;
+ }
+}
+
+/* main context */
+static void spice_record_start_mark(SpiceRecordChannel *channel, uint32_t time)
+{
+ SpiceMsgcRecordStartMark m = {0, };
+ SpiceMsgOut *msg;
+
+ g_return_if_fail(channel != NULL);
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
+ m.time = time;
+
+ msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_RECORD_START_MARK);
+ msg->marshallers->msgc_record_start_mark(msg->marshaller, &m);
+ spice_msg_out_send(msg);
+}
+
+/**
+ * spice_record_send_data:
+ * @channel: a #SpiceRecordChannel
+ * @data: PCM data
+ * @bytes: size of @data
+ * @time: stream timestamp
+ *
+ * Send recorded PCM data to the guest.
+ **/
+void spice_record_send_data(SpiceRecordChannel *channel, gpointer data,
+ gsize bytes, uint32_t time)
+{
+ SpiceRecordChannelPrivate *rc;
+ SpiceMsgcRecordPacket p = {0, };
+
+ g_return_if_fail(SPICE_IS_RECORD_CHANNEL(channel));
+ rc = channel->priv;
+ if (rc->last_frame == NULL) {
+ CHANNEL_DEBUG(channel, "recording didn't start or was reset");
+ return;
+ }
+
+ g_return_if_fail(spice_channel_get_read_only(SPICE_CHANNEL(channel)) == FALSE);
+
+ uint8_t *encode_buf = NULL;
+
+ if (!rc->started) {
+ spice_record_mode(channel, time, rc->mode, NULL, 0);
+ spice_record_start_mark(channel, time);
+ rc->started = TRUE;
+ }
+
+ if (rc->mode != SPICE_AUDIO_DATA_MODE_RAW)
+ encode_buf = g_alloca(SND_CODEC_MAX_COMPRESSED_BYTES);
+
+ p.time = time;
+
+ while (bytes > 0) {
+ gsize n;
+ int frame_size;
+ SpiceMsgOut *msg;
+ uint8_t *frame;
+
+ if (rc->last_frame_current > 0) {
+ /* complete previous frame */
+ n = MIN(bytes, rc->frame_bytes - rc->last_frame_current);
+ memcpy(rc->last_frame + rc->last_frame_current, data, n);
+ rc->last_frame_current += n;
+ if (rc->last_frame_current < rc->frame_bytes)
+ /* if the frame is still incomplete, return */
+ break;
+ frame = rc->last_frame;
+ frame_size = rc->frame_bytes;
+ } else {
+ n = MIN(bytes, rc->frame_bytes);
+ frame_size = n;
+ frame = data;
+ }
+
+ if (rc->last_frame_current == 0 &&
+ n < rc->frame_bytes) {
+ /* start a new frame */
+ memcpy(rc->last_frame, data, n);
+ rc->last_frame_current = n;
+ break;
+ }
+
+ if (rc->mode != SPICE_AUDIO_DATA_MODE_RAW) {
+ int len = SND_CODEC_MAX_COMPRESSED_BYTES;
+ if (snd_codec_encode(rc->codec, frame, frame_size, encode_buf, &len) != SND_CODEC_OK) {
+ g_warning("encode failed");
+ return;
+ }
+ frame = encode_buf;
+ frame_size = len;
+ }
+
+ msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_RECORD_DATA);
+ msg->marshallers->msgc_record_data(msg->marshaller, &p);
+ spice_marshaller_add(msg->marshaller, frame, frame_size);
+ spice_msg_out_send(msg);
+
+ if (rc->last_frame_current == rc->frame_bytes)
+ rc->last_frame_current = 0;
+
+ bytes -= n;
+ data = (guint8*)data + n;
+ }
+}
+
+/* ------------------------------------------------------------------ */
+
+/* coroutine context */
+static void record_handle_start(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceRecordChannelPrivate *c = SPICE_RECORD_CHANNEL(channel)->priv;
+ SpiceMsgRecordStart *start = spice_msg_in_parsed(in);
+ int frame_size = SND_CODEC_MAX_FRAME_SIZE;
+
+ c->mode = spice_record_desired_mode(channel, start->frequency);
+
+ CHANNEL_DEBUG(channel, "%s: fmt %u channels %u freq %u", __FUNCTION__,
+ start->format, start->channels, start->frequency);
+
+ g_return_if_fail(start->format == SPICE_AUDIO_FMT_S16);
+
+ snd_codec_destroy(&c->codec);
+
+ if (c->mode != SPICE_AUDIO_DATA_MODE_RAW) {
+ if (snd_codec_create(&c->codec, c->mode, start->frequency, SND_CODEC_ENCODE) != SND_CODEC_OK) {
+ g_warning("Failed to create encoder");
+ return;
+ }
+ frame_size = snd_codec_frame_size(c->codec);
+ }
+
+ g_free(c->last_frame);
+ c->frame_bytes = frame_size * 16 * start->channels / 8;
+ c->last_frame = g_malloc0(c->frame_bytes);
+ c->last_frame_current = 0;
+
+ g_coroutine_signal_emit(channel, signals[SPICE_RECORD_START], 0,
+ start->format, start->channels, start->frequency);
+}
+
+/* coroutine context */
+static void record_handle_stop(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceRecordChannelPrivate *rc = SPICE_RECORD_CHANNEL(channel)->priv;
+
+ g_coroutine_signal_emit(channel, signals[SPICE_RECORD_STOP], 0);
+ rc->started = FALSE;
+}
+
+/* coroutine context */
+static void record_handle_set_volume(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceRecordChannelPrivate *c = SPICE_RECORD_CHANNEL(channel)->priv;
+ SpiceMsgAudioVolume *vol = spice_msg_in_parsed(in);
+
+ if (vol->nchannels == 0) {
+ g_warning("spice-server send audio-volume-msg with 0 channels");
+ return;
+ }
+
+ g_free(c->volume);
+ c->nchannels = vol->nchannels;
+ c->volume = g_new(guint16, c->nchannels);
+ memcpy(c->volume, vol->volume, sizeof(guint16) * c->nchannels);
+ g_coroutine_object_notify(G_OBJECT(channel), "volume");
+}
+
+/* coroutine context */
+static void record_handle_set_mute(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceRecordChannelPrivate *c = SPICE_RECORD_CHANNEL(channel)->priv;
+ SpiceMsgAudioMute *m = spice_msg_in_parsed(in);
+
+ c->mute = m->mute;
+ g_coroutine_object_notify(G_OBJECT(channel), "mute");
+}
+
+static void channel_set_handlers(SpiceChannelClass *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_RECORD_START ] = record_handle_start,
+ [ SPICE_MSG_RECORD_STOP ] = record_handle_stop,
+ [ SPICE_MSG_RECORD_VOLUME ] = record_handle_set_volume,
+ [ SPICE_MSG_RECORD_MUTE ] = record_handle_set_mute,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_RECORD_CHANNEL_H__
+#define __SPICE_CLIENT_RECORD_CHANNEL_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_RECORD_CHANNEL (spice_record_channel_get_type())
+#define SPICE_RECORD_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_RECORD_CHANNEL, SpiceRecordChannel))
+#define SPICE_RECORD_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_RECORD_CHANNEL, SpiceRecordChannelClass))
+#define SPICE_IS_RECORD_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_RECORD_CHANNEL))
+#define SPICE_IS_RECORD_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_RECORD_CHANNEL))
+#define SPICE_RECORD_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_RECORD_CHANNEL, SpiceRecordChannelClass))
+
+typedef struct _SpiceRecordChannel SpiceRecordChannel;
+typedef struct _SpiceRecordChannelClass SpiceRecordChannelClass;
+typedef struct _SpiceRecordChannelPrivate SpiceRecordChannelPrivate;
+
+/**
+ * SpiceRecordChannel:
+ *
+ * The #SpiceRecordChannel struct is opaque and should not be accessed directly.
+ */
+struct _SpiceRecordChannel {
+ SpiceChannel parent;
+
+ /*< private >*/
+ SpiceRecordChannelPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpiceRecordChannelClass:
+ * @parent_class: Parent class.
+ * @record_start: Signal class handler for the #SpiceRecordChannel::record-start signal.
+ * @record_stop: Signal class handler for the #SpiceRecordChannel::record-stop signal.
+ * @record_data: Unused (deprecated).
+ *
+ * Class structure for #SpiceRecordChannel.
+ */
+struct _SpiceRecordChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+ void (*record_start)(SpiceRecordChannel *channel,
+ gint format, gint channels, gint freq);
+ void (*record_data)(SpiceRecordChannel *channel, gpointer *data, gint size);
+ void (*record_stop)(SpiceRecordChannel *channel);
+
+ /*< private >*/
+ /* Do not add fields to this struct */
+};
+
+GType spice_record_channel_get_type(void);
+void spice_record_send_data(SpiceRecordChannel *channel, gpointer data,
+ gsize bytes, guint32 time);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_RECORD_CHANNEL_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#ifdef USE_SMARTCARD_012
+#include <vreader.h>
+#endif
+
+#include "spice-client.h"
+#include "spice-common.h"
+
+#include "spice-channel-priv.h"
+#include "smartcard-manager.h"
+#include "smartcard-manager-priv.h"
+#include "spice-session-priv.h"
+
+/**
+ * SECTION:channel-smartcard
+ * @short_description: smartcard authentication
+ * @title: Smartcard Channel
+ * @section_id:
+ * @see_also: #SpiceSmartcardManager, #SpiceSession
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * The Spice protocol defines a set of messages to forward smartcard
+ * information from the Spice client to the VM. This channel handles
+ * these messages. While it's mainly focus on smartcard readers and
+ * smartcards, it's also possible to use it with a software smartcard
+ * (ie a set of 3 certificates from the client machine).
+ * This class doesn't provide useful methods, see #SpiceSession properties
+ * for a way to enable/disable this channel, and #SpiceSmartcardManager
+ * if you want to detect smartcard reader hotplug/unplug, and smartcard
+ * insertion/removal.
+ */
+
+#define SPICE_SMARTCARD_CHANNEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_SMARTCARD_CHANNEL, SpiceSmartcardChannelPrivate))
+
+struct _SpiceSmartcardChannelMessage {
+#ifdef USE_SMARTCARD
+ VSCMsgType message_type;
+#endif
+ SpiceMsgOut *message;
+};
+typedef struct _SpiceSmartcardChannelMessage SpiceSmartcardChannelMessage;
+
+
+struct _SpiceSmartcardChannelPrivate {
+ /* track readers that have been added but for which we didn't receive
+ * an ack from the spice server yet. We rely on the fact that the
+ * readers in this list are ordered by the time we sent the request to
+ * the server. When we get an ack from the server for a reader addition,
+ * we can pop the 1st entry to get the reader the ack corresponds to. */
+ GList *pending_reader_additions;
+
+ /* used to removals of readers that were not ack'ed yet by the spice
+ * server */
+ GHashTable *pending_reader_removals;
+
+ /* used to track card insertions on readers that were not ack'ed yet
+ * by the spice server */
+ GHashTable *pending_card_insertions;
+
+ /* next commands to be sent to the spice server. This is needed since
+ * we have to wait for a command answer before sending the next one
+ */
+ GQueue *message_queue;
+
+ /* message that is currently being processed by the spice server (ie last
+ * message that was sent to the server)
+ */
+ SpiceSmartcardChannelMessage *in_flight_message;
+};
+
+G_DEFINE_TYPE(SpiceSmartcardChannel, spice_smartcard_channel, SPICE_TYPE_CHANNEL)
+
+enum {
+
+ SPICE_SMARTCARD_LAST_SIGNAL,
+};
+
+static void spice_smartcard_channel_up(SpiceChannel *channel);
+static void handle_smartcard_msg(SpiceChannel *channel, SpiceMsgIn *in);
+static void smartcard_message_free(SpiceSmartcardChannelMessage *message);
+
+/* ------------------------------------------------------------------ */
+#ifdef USE_SMARTCARD
+static void reader_added_cb(SpiceSmartcardManager *manager, VReader *reader,
+ gpointer user_data);
+static void reader_removed_cb(SpiceSmartcardManager *manager, VReader *reader,
+ gpointer user_data);
+static void card_inserted_cb(SpiceSmartcardManager *manager, VReader *reader,
+ gpointer user_data);
+static void card_removed_cb(SpiceSmartcardManager *manager, VReader *reader,
+ gpointer user_data);
+#endif
+
+static void spice_smartcard_channel_init(SpiceSmartcardChannel *channel)
+{
+ SpiceSmartcardChannelPrivate *priv;
+
+ channel->priv = SPICE_SMARTCARD_CHANNEL_GET_PRIVATE(channel);
+ priv = channel->priv;
+ priv->message_queue = g_queue_new();
+
+#ifdef USE_SMARTCARD
+ priv->pending_card_insertions =
+ g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ (GDestroyNotify)vreader_free, NULL);
+ priv->pending_reader_removals =
+ g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ (GDestroyNotify)vreader_free, NULL);
+#endif
+}
+
+static void spice_smartcard_channel_constructed(GObject *object)
+{
+ SpiceSession *s = spice_channel_get_session(SPICE_CHANNEL(object));
+
+ g_return_if_fail(s != NULL);
+
+#ifdef USE_SMARTCARD
+ if (!spice_session_is_for_migration(s)) {
+ SpiceSmartcardChannel *channel = SPICE_SMARTCARD_CHANNEL(object);
+ SpiceSmartcardManager *manager = spice_smartcard_manager_get();
+
+ spice_g_signal_connect_object(G_OBJECT(manager), "reader-added",
+ (GCallback)reader_added_cb, channel, 0);
+ spice_g_signal_connect_object(G_OBJECT(manager), "reader-removed",
+ (GCallback)reader_removed_cb, channel, 0);
+ spice_g_signal_connect_object(G_OBJECT(manager), "card-inserted",
+ (GCallback)card_inserted_cb, channel, 0);
+ spice_g_signal_connect_object(G_OBJECT(manager), "card-removed",
+ (GCallback)card_removed_cb, channel, 0);
+ }
+#endif
+
+ if (G_OBJECT_CLASS(spice_smartcard_channel_parent_class)->constructed)
+ G_OBJECT_CLASS(spice_smartcard_channel_parent_class)->constructed(object);
+
+}
+
+static void spice_smartcard_channel_finalize(GObject *obj)
+{
+ SpiceSmartcardChannel *channel = SPICE_SMARTCARD_CHANNEL(obj);
+ SpiceSmartcardChannelPrivate *c = channel->priv;
+
+ g_clear_pointer(&c->pending_card_insertions, g_hash_table_destroy);
+ g_clear_pointer(&c->pending_reader_removals, g_hash_table_destroy);
+ if (c->message_queue != NULL) {
+ g_queue_foreach(c->message_queue, (GFunc)smartcard_message_free, NULL);
+ g_queue_free(c->message_queue);
+ c->message_queue = NULL;
+ }
+ g_clear_pointer(&c->in_flight_message, smartcard_message_free);
+ g_clear_pointer(&c->pending_reader_additions, g_list_free);
+
+ if (G_OBJECT_CLASS(spice_smartcard_channel_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_smartcard_channel_parent_class)->finalize(obj);
+}
+
+static void spice_smartcard_channel_reset(SpiceChannel *channel, gboolean migrating)
+{
+ SpiceSmartcardChannel *smartcard_channel = SPICE_SMARTCARD_CHANNEL(channel);
+ SpiceSmartcardChannelPrivate *c = smartcard_channel->priv;
+
+ g_hash_table_remove_all(c->pending_card_insertions);
+ g_hash_table_remove_all(c->pending_reader_removals);
+
+ if (c->message_queue != NULL) {
+ g_queue_foreach(c->message_queue, (GFunc)smartcard_message_free, NULL);
+ g_queue_clear(c->message_queue);
+ }
+
+ g_clear_pointer(&c->in_flight_message, smartcard_message_free);
+ g_clear_pointer(&c->pending_reader_additions, g_list_free);
+
+ SPICE_CHANNEL_CLASS(spice_smartcard_channel_parent_class)->channel_reset(channel, migrating);
+}
+
+static void channel_set_handlers(SpiceChannelClass *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_SMARTCARD_DATA ] = handle_smartcard_msg,
+ };
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
+}
+
+static void spice_smartcard_channel_class_init(SpiceSmartcardChannelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
+
+ gobject_class->finalize = spice_smartcard_channel_finalize;
+ gobject_class->constructed = spice_smartcard_channel_constructed;
+
+ channel_class->channel_up = spice_smartcard_channel_up;
+ channel_class->channel_reset = spice_smartcard_channel_reset;
+
+ g_type_class_add_private(klass, sizeof(SpiceSmartcardChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
+}
+
+/* ------------------------------------------------------------------ */
+/* private api */
+
+static void
+smartcard_message_free(SpiceSmartcardChannelMessage *message)
+{
+ if (message->message)
+ spice_msg_out_unref(message->message);
+ g_free(message);
+}
+
+#ifdef USE_SMARTCARD
+static gboolean is_attached_to_server(VReader *reader)
+{
+ return (vreader_get_id(reader) != (vreader_id_t)-1);
+}
+
+static gboolean
+spice_channel_has_pending_card_insertion(SpiceSmartcardChannel *channel,
+ VReader *reader)
+{
+ return (g_hash_table_lookup(channel->priv->pending_card_insertions, reader) != NULL);
+}
+
+static void
+spice_channel_queue_card_insertion(SpiceSmartcardChannel *channel,
+ VReader *reader)
+{
+ vreader_reference(reader);
+ g_hash_table_insert(channel->priv->pending_card_insertions,
+ reader, reader);
+}
+
+static void
+spice_channel_drop_pending_card_insertion(SpiceSmartcardChannel *channel,
+ VReader *reader)
+{
+ g_hash_table_remove(channel->priv->pending_card_insertions, reader);
+}
+
+static gboolean
+spice_channel_has_pending_reader_removal(SpiceSmartcardChannel *channel,
+ VReader *reader)
+{
+ return (g_hash_table_lookup(channel->priv->pending_reader_removals, reader) != NULL);
+}
+
+static void
+spice_channel_queue_reader_removal(SpiceSmartcardChannel *channel,
+ VReader *reader)
+{
+ vreader_reference(reader);
+ g_hash_table_insert(channel->priv->pending_reader_removals,
+ reader, reader);
+}
+
+static void
+spice_channel_drop_pending_reader_removal(SpiceSmartcardChannel *channel,
+ VReader *reader)
+{
+ g_hash_table_remove(channel->priv->pending_reader_removals, reader);
+}
+
+static SpiceSmartcardChannelMessage *
+smartcard_message_new(VSCMsgType msg_type, SpiceMsgOut *msg_out)
+{
+ SpiceSmartcardChannelMessage *message;
+
+ message = g_new0(SpiceSmartcardChannelMessage, 1);
+ message->message = msg_out;
+ message->message_type = msg_type;
+
+ return message;
+}
+
+/* Indicates that handling of the message that is currently in flight has
+ * been completed. If needed, sends the next queued command to the server. */
+static void
+smartcard_message_complete_in_flight(SpiceSmartcardChannel *channel)
+{
+ g_return_if_fail(channel->priv->in_flight_message != NULL);
+
+ smartcard_message_free(channel->priv->in_flight_message);
+ channel->priv->in_flight_message = g_queue_pop_head(channel->priv->message_queue);
+ if (channel->priv->in_flight_message != NULL) {
+ spice_msg_out_send(channel->priv->in_flight_message->message);
+ channel->priv->in_flight_message->message = NULL;
+ }
+}
+
+static void smartcard_message_send(SpiceSmartcardChannel *channel,
+ VSCMsgType msg_type,
+ SpiceMsgOut *msg_out, gboolean queue)
+{
+ SpiceSmartcardChannelMessage *message;
+
+ if (spice_channel_get_read_only(SPICE_CHANNEL(channel)))
+ return;
+
+ CHANNEL_DEBUG(channel, "send message %u, %s",
+ msg_type, queue ? "queued" : "now");
+ if (!queue) {
+ spice_msg_out_send(msg_out);
+ return;
+ }
+
+ message = smartcard_message_new(msg_type, msg_out);
+ if (channel->priv->in_flight_message == NULL) {
+ g_return_if_fail(g_queue_is_empty(channel->priv->message_queue));
+ channel->priv->in_flight_message = message;
+ spice_msg_out_send(channel->priv->in_flight_message->message);
+ channel->priv->in_flight_message->message = NULL;
+ } else {
+ g_queue_push_tail(channel->priv->message_queue, message);
+ }
+}
+
+static void
+send_msg_generic_with_data(SpiceSmartcardChannel *channel, VReader *reader,
+ VSCMsgType msg_type,
+ const uint8_t *data, gsize data_len,
+ gboolean serialize_msg)
+{
+ SpiceMsgOut *msg_out;
+ VSCMsgHeader header = {
+ .type = msg_type,
+ .length = data_len
+ };
+
+ if(vreader_get_id(reader) == -1)
+ header.reader_id = VSCARD_UNDEFINED_READER_ID;
+ else
+ header.reader_id = vreader_get_id(reader);
+
+ msg_out = spice_msg_out_new(SPICE_CHANNEL(channel),
+ SPICE_MSGC_SMARTCARD_DATA);
+ msg_out->marshallers->msgc_smartcard_header(msg_out->marshaller, &header);
+ if ((data != NULL) && (data_len != 0)) {
+ spice_marshaller_add(msg_out->marshaller, data, data_len);
+ }
+
+ smartcard_message_send(channel, msg_type, msg_out, serialize_msg);
+}
+
+static void send_msg_generic(SpiceSmartcardChannel *channel, VReader *reader,
+ VSCMsgType msg_type)
+{
+ send_msg_generic_with_data(channel, reader, msg_type, NULL, 0, TRUE);
+}
+
+static void send_msg_atr(SpiceSmartcardChannel *channel, VReader *reader)
+{
+#define MAX_ATR_LEN 40 //this should be defined in libcacard
+ uint8_t atr[MAX_ATR_LEN];
+ int atr_len = MAX_ATR_LEN;
+
+ g_return_if_fail(vreader_get_id(reader) != VSCARD_UNDEFINED_READER_ID);
+ vreader_power_on(reader, atr, &atr_len);
+ send_msg_generic_with_data(channel, reader, VSC_ATR, atr, atr_len, TRUE);
+}
+
+static void reader_added_cb(SpiceSmartcardManager *manager, VReader *reader,
+ gpointer user_data)
+{
+ SpiceSmartcardChannel *channel = SPICE_SMARTCARD_CHANNEL(user_data);
+ const char *reader_name = vreader_get_name(reader);
+
+ if (vreader_get_id(reader) != -1 ||
+ g_list_find(channel->priv->pending_reader_additions, reader))
+ return;
+
+ channel->priv->pending_reader_additions =
+ g_list_append(channel->priv->pending_reader_additions, reader);
+
+ send_msg_generic_with_data(channel, reader, VSC_ReaderAdd,
+ (uint8_t*)reader_name, strlen(reader_name), TRUE);
+}
+
+static void reader_removed_cb(SpiceSmartcardManager *manager, VReader *reader,
+ gpointer user_data)
+{
+ SpiceSmartcardChannel *channel = SPICE_SMARTCARD_CHANNEL(user_data);
+
+ if (is_attached_to_server(reader)) {
+ send_msg_generic(channel, reader, VSC_ReaderRemove);
+ } else {
+ spice_channel_queue_reader_removal(channel, reader);
+ }
+}
+
+/* ------------------------------------------------------------------ */
+/* callbacks */
+static void card_inserted_cb(SpiceSmartcardManager *manager, VReader *reader,
+ gpointer user_data)
+{
+ SpiceSmartcardChannel *channel = SPICE_SMARTCARD_CHANNEL(user_data);
+
+ if (is_attached_to_server(reader)) {
+ send_msg_atr(channel, reader);
+ } else {
+ spice_channel_queue_card_insertion(channel, reader);
+ }
+}
+
+static void card_removed_cb(SpiceSmartcardManager *manager, VReader *reader,
+ gpointer user_data)
+{
+ SpiceSmartcardChannel *channel = SPICE_SMARTCARD_CHANNEL(user_data);
+
+ if (is_attached_to_server(reader)) {
+ send_msg_generic(channel, reader, VSC_CardRemove);
+ } else {
+ /* this does nothing when reader has no card insertion pending */
+ spice_channel_drop_pending_card_insertion(channel, reader);
+ }
+}
+#endif /* USE_SMARTCARD */
+
+static void spice_smartcard_channel_up_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceChannel *channel = SPICE_CHANNEL(user_data);
+#ifdef USE_SMARTCARD
+ SpiceSmartcardManager *manager = spice_smartcard_manager_get();
+ GList *l, *list = NULL;
+#endif
+ GError *error = NULL;
+
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(SPICE_IS_SESSION(source_object));
+
+ spice_smartcard_manager_init_finish(SPICE_SESSION(source_object),
+ res, &error);
+ if (error) {
+ g_warning("%s", error->message);
+ goto end;
+ }
+
+#ifdef USE_SMARTCARD
+ list = spice_smartcard_manager_get_readers(manager);
+ for (l = list; l != NULL; l = l->next) {
+ VReader *reader = l->data;
+ gboolean has_card = vreader_card_is_present(reader) == VREADER_OK;
+
+ reader_added_cb(manager, reader, channel);
+ if (has_card)
+ card_inserted_cb(manager, reader, channel);
+
+ g_boxed_free(SPICE_TYPE_SMARTCARD_READER, reader);
+ }
+#endif
+
+end:
+#ifdef USE_SMARTCARD
+ g_list_free(list);
+#endif
+ g_clear_error(&error);
+}
+
+static void spice_smartcard_channel_up(SpiceChannel *channel)
+{
+ if (spice_session_is_for_migration(spice_channel_get_session(channel)))
+ return;
+
+ spice_smartcard_manager_init_async(spice_channel_get_session(channel),
+ g_cancellable_new(),
+ spice_smartcard_channel_up_cb,
+ channel);
+}
+
+static void handle_smartcard_msg(SpiceChannel *channel, SpiceMsgIn *in)
+{
+#ifdef USE_SMARTCARD
+ SpiceSmartcardChannel *smartcard_channel = SPICE_SMARTCARD_CHANNEL(channel);
+ SpiceSmartcardChannelPrivate *priv = smartcard_channel->priv;
+ SpiceMsgSmartcard *msg = spice_msg_in_parsed(in);
+ VReader *reader;
+
+ CHANNEL_DEBUG(channel, "handle msg %u", msg->type);
+ switch (msg->type) {
+ case VSC_Error:
+ g_return_if_fail(priv->in_flight_message != NULL);
+ CHANNEL_DEBUG(channel, "in flight %u", priv->in_flight_message->message_type);
+ switch (priv->in_flight_message->message_type) {
+ case VSC_ReaderAdd:
+ g_return_if_fail(priv->pending_reader_additions != NULL);
+ reader = priv->pending_reader_additions->data;
+ g_return_if_fail(reader != NULL);
+ g_return_if_fail(vreader_get_id(reader) == -1);
+ priv->pending_reader_additions =
+ g_list_delete_link(priv->pending_reader_additions,
+ priv->pending_reader_additions);
+ vreader_set_id(reader, msg->reader_id);
+
+ if (spice_channel_has_pending_card_insertion(smartcard_channel, reader)) {
+ send_msg_atr(smartcard_channel, reader);
+ spice_channel_drop_pending_card_insertion(smartcard_channel, reader);
+ }
+
+ if (spice_channel_has_pending_reader_removal(smartcard_channel, reader)) {
+ send_msg_generic(smartcard_channel, reader, VSC_CardRemove);
+ spice_channel_drop_pending_reader_removal(smartcard_channel, reader);
+ }
+ break;
+ case VSC_APDU:
+ case VSC_ATR:
+ case VSC_CardRemove:
+ case VSC_Error:
+ case VSC_ReaderRemove:
+ break;
+ default:
+ g_warning("Unexpected message: %u", priv->in_flight_message->message_type);
+ break;
+ }
+ smartcard_message_complete_in_flight(smartcard_channel);
+
+ break;
+
+ case VSC_APDU:
+ case VSC_Init: {
+ const unsigned int APDU_BUFFER_SIZE = 270;
+ VReaderStatus reader_status;
+ uint8_t data_out[APDU_BUFFER_SIZE + sizeof(uint32_t)];
+ int data_out_len = sizeof(data_out);
+
+ g_return_if_fail(msg->reader_id != VSCARD_UNDEFINED_READER_ID);
+ reader = vreader_get_reader_by_id(msg->reader_id);
+ g_return_if_fail(reader != NULL); //FIXME: add log message
+
+ reader_status = vreader_xfr_bytes(reader,
+ msg->data, msg->length,
+ data_out, &data_out_len);
+ if (reader_status == VREADER_OK) {
+ send_msg_generic_with_data(smartcard_channel,
+ reader, VSC_APDU,
+ data_out, data_out_len, FALSE);
+ } else {
+ uint32_t error_code;
+ error_code = GUINT32_TO_LE(reader_status);
+ send_msg_generic_with_data(smartcard_channel,
+ reader, VSC_Error,
+ (uint8_t*)&error_code,
+ sizeof (error_code), FALSE);
+ }
+ break;
+ }
+ default:
+ g_return_if_reached();
+ }
+#endif
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_SMARTCARD_CHANNEL_H__
+#define __SPICE_CLIENT_SMARTCARD_CHANNEL_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_SMARTCARD_CHANNEL (spice_smartcard_channel_get_type())
+#define SPICE_SMARTCARD_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_SMARTCARD_CHANNEL, SpiceSmartcardChannel))
+#define SPICE_SMARTCARD_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_SMARTCARD_CHANNEL, SpiceSmartcardChannelClass))
+#define SPICE_IS_SMARTCARD_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_SMARTCARD_CHANNEL))
+#define SPICE_IS_SMARTCARD_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_SMARTCARD_CHANNEL))
+#define SPICE_SMARTCARD_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_SMARTCARD_CHANNEL, SpiceSmartcardChannelClass))
+
+typedef struct _SpiceSmartcardChannel SpiceSmartcardChannel;
+typedef struct _SpiceSmartcardChannelClass SpiceSmartcardChannelClass;
+typedef struct _SpiceSmartcardChannelPrivate SpiceSmartcardChannelPrivate;
+
+/**
+ * SpiceSmartcardChannel:
+ *
+ * The #SpiceSmartcardChannel struct is opaque and should not be accessed directly.
+ */
+struct _SpiceSmartcardChannel {
+ SpiceChannel parent;
+
+ /*< private >*/
+ SpiceSmartcardChannelPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpiceSmartcardChannelClass:
+ * @parent_class: Parent class.
+ *
+ * Class structure for #SpiceSmartcardChannel.
+ */
+struct _SpiceSmartcardChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+
+ /*< private >*/
+ /* Do not add fields to this struct */
+};
+
+GType spice_smartcard_channel_get_type(void);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_SMARTCARD_CHANNEL_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__
+#define __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__
+
+#include <libusb.h>
+#include <usbredirfilter.h>
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+/* Note: this must be called before calling any other functions, and the
+ context should not be destroyed before the last device has been
+ disconnected */
+void spice_usbredir_channel_set_context(SpiceUsbredirChannel *channel,
+ libusb_context *context);
+
+void spice_usbredir_channel_disconnect_device_async(SpiceUsbredirChannel *channel,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean spice_usbredir_channel_disconnect_device_finish(SpiceUsbredirChannel *channel,
+ GAsyncResult *res,
+ GError **err);
+
+/* Note the context must be set, and the channel must be brought up
+ (through spice_channel_connect()), before calling this. */
+void spice_usbredir_channel_connect_device_async(
+ SpiceUsbredirChannel *channel,
+ libusb_device *device,
+ SpiceUsbDevice *spice_device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean spice_usbredir_channel_connect_device_finish(
+ SpiceUsbredirChannel *channel,
+ GAsyncResult *res,
+ GError **err);
+
+void spice_usbredir_channel_disconnect_device(SpiceUsbredirChannel *channel);
+
+libusb_device *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel);
+
+void spice_usbredir_channel_lock(SpiceUsbredirChannel *channel);
+
+void spice_usbredir_channel_unlock(SpiceUsbredirChannel *channel);
+
+void spice_usbredir_channel_get_guest_filter(
+ SpiceUsbredirChannel *channel,
+ const struct usbredirfilter_rule **rules_ret,
+ int *rules_count_ret);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_USBREDIR_CHANNEL_PRIV_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010-2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+ Richard Hughes <rhughes@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#ifdef USE_USBREDIR
+#include <glib/gi18n-lib.h>
+#include <usbredirhost.h>
+#ifdef USE_LZ4
+#include <lz4.h>
+#endif
+#ifdef USE_POLKIT
+#include "usb-acl-helper.h"
+#endif
+#include "channel-usbredir-priv.h"
+#include "usb-device-manager-priv.h"
+#include "usbutil.h"
+#endif
+
+#include "common/log.h"
+#include "spice-client.h"
+#include "spice-common.h"
+
+#include "spice-channel-priv.h"
+
+/**
+ * SECTION:channel-usbredir
+ * @short_description: usb redirection
+ * @title: USB Redirection Channel
+ * @section_id:
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * The Spice protocol defines a set of messages to redirect USB devices
+ * from the Spice client to the VM. This channel handles these messages.
+ */
+
+#ifdef USE_USBREDIR
+
+#define COMPRESS_THRESHOLD 1000
+#define SPICE_USBREDIR_CHANNEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_USBREDIR_CHANNEL, SpiceUsbredirChannelPrivate))
+
+enum SpiceUsbredirChannelState {
+ STATE_DISCONNECTED,
+#ifdef USE_POLKIT
+ STATE_WAITING_FOR_ACL_HELPER,
+#endif
+ STATE_CONNECTED,
+ STATE_DISCONNECTING,
+};
+
+struct _SpiceUsbredirChannelPrivate {
+ libusb_device *device;
+ SpiceUsbDevice *spice_device;
+ libusb_context *context;
+ struct usbredirhost *host;
+ /* To catch usbredirhost error messages and report them as a GError */
+ GError **catch_error;
+ /* Data passed from channel handle msg to the usbredirhost read cb */
+ const uint8_t *read_buf;
+ int read_buf_size;
+ enum SpiceUsbredirChannelState state;
+#ifdef USE_POLKIT
+ GTask *task;
+ SpiceUsbAclHelper *acl_helper;
+#endif
+ GMutex device_connect_mutex;
+ SpiceUsbDeviceManager *usb_device_manager;
+};
+
+static void channel_set_handlers(SpiceChannelClass *klass);
+static void spice_usbredir_channel_up(SpiceChannel *channel);
+static void spice_usbredir_channel_dispose(GObject *obj);
+static void spice_usbredir_channel_finalize(GObject *obj);
+static void usbredir_handle_msg(SpiceChannel *channel, SpiceMsgIn *in);
+
+static void usbredir_log(void *user_data, int level, const char *msg);
+static int usbredir_read_callback(void *user_data, uint8_t *data, int count);
+static int usbredir_write_callback(void *user_data, uint8_t *data, int count);
+static void usbredir_write_flush_callback(void *user_data);
+#if USBREDIR_VERSION >= 0x000701
+static uint64_t usbredir_buffered_output_size_callback(void *user_data);
+#endif
+
+static void *usbredir_alloc_lock(void);
+static void usbredir_lock_lock(void *user_data);
+static void usbredir_unlock_lock(void *user_data);
+static void usbredir_free_lock(void *user_data);
+
+#endif
+
+G_DEFINE_TYPE(SpiceUsbredirChannel, spice_usbredir_channel, SPICE_TYPE_CHANNEL)
+
+/* ------------------------------------------------------------------ */
+
+static void spice_usbredir_channel_init(SpiceUsbredirChannel *channel)
+{
+#ifdef USE_USBREDIR
+ channel->priv = SPICE_USBREDIR_CHANNEL_GET_PRIVATE(channel);
+ g_mutex_init(&channel->priv->device_connect_mutex);
+#endif
+}
+
+#ifdef USE_USBREDIR
+
+static void _channel_reset_finish(SpiceUsbredirChannel *channel)
+{
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+ spice_usbredir_channel_lock(channel);
+
+ usbredirhost_close(priv->host);
+ priv->host = NULL;
+
+ /* Call set_context to re-create the host */
+ spice_usbredir_channel_set_context(channel, priv->context);
+
+ spice_usbredir_channel_unlock(channel);
+}
+
+static void _channel_reset_cb(GObject *gobject,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ SpiceChannel *spice_channel = SPICE_CHANNEL(gobject);
+ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(spice_channel);
+ gboolean migrating = GPOINTER_TO_UINT(user_data);
+ GError *err = NULL;
+
+ _channel_reset_finish(channel);
+
+ SPICE_CHANNEL_CLASS(spice_usbredir_channel_parent_class)->channel_reset(spice_channel, migrating);
+
+ spice_usbredir_channel_disconnect_device_finish(channel, result, &err);
+ g_object_unref(result);
+}
+
+static void spice_usbredir_channel_reset(SpiceChannel *c, gboolean migrating)
+{
+ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(c);
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+ if (priv->host) {
+ if (priv->state == STATE_CONNECTED) {
+ spice_usbredir_channel_disconnect_device_async(channel, NULL,
+ _channel_reset_cb, GUINT_TO_POINTER(migrating));
+ } else {
+ _channel_reset_finish(channel);
+ }
+ } else {
+ SPICE_CHANNEL_CLASS(spice_usbredir_channel_parent_class)->channel_reset(c, migrating);
+ }
+}
+#endif
+
+static void spice_usbredir_channel_class_init(SpiceUsbredirChannelClass *klass)
+{
+#ifdef USE_USBREDIR
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
+
+ gobject_class->dispose = spice_usbredir_channel_dispose;
+ gobject_class->finalize = spice_usbredir_channel_finalize;
+ channel_class->channel_up = spice_usbredir_channel_up;
+ channel_class->channel_reset = spice_usbredir_channel_reset;
+
+ g_type_class_add_private(klass, sizeof(SpiceUsbredirChannelPrivate));
+ channel_set_handlers(SPICE_CHANNEL_CLASS(klass));
+#endif
+}
+
+#ifdef USE_USBREDIR
+static void spice_usbredir_channel_dispose(GObject *obj)
+{
+ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(obj);
+
+ spice_usbredir_channel_disconnect_device(channel);
+ /* This should have been set to NULL during device disconnection,
+ * but better not to leak it if this does not happen for some reason
+ */
+ g_warn_if_fail(channel->priv->usb_device_manager == NULL);
+ g_clear_object(&channel->priv->usb_device_manager);
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_usbredir_channel_parent_class)->dispose)
+ G_OBJECT_CLASS(spice_usbredir_channel_parent_class)->dispose(obj);
+}
+
+/*
+ * Note we don't unref our device / acl_helper / result references in our
+ * finalize. The reason for this is that depending on our state at dispose
+ * time they are either:
+ * 1) Already unreferenced
+ * 2) Will be unreferenced by the disconnect_device call from dispose
+ * 3) Will be unreferenced by spice_usbredir_channel_open_acl_cb
+ *
+ * Now the last one may seem like an issue, since what will happen if
+ * spice_usbredir_channel_open_acl_cb will run after finalization?
+ *
+ * This will never happens since the GTask created before we
+ * get into the STATE_WAITING_FOR_ACL_HELPER takes a reference to its
+ * source object, which is our SpiceUsbredirChannel object, so
+ * the finalize won't hapen until spice_usbredir_channel_open_acl_cb runs,
+ * and unrefs priv->result which will in turn unref ourselve once the
+ * complete_in_idle call it does has completed. And once
+ * spice_usbredir_channel_open_acl_cb has run, all references we hold have
+ * been released even in the 3th scenario.
+ */
+static void spice_usbredir_channel_finalize(GObject *obj)
+{
+ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(obj);
+
+ if (channel->priv->host)
+ usbredirhost_close(channel->priv->host);
+#ifdef USE_USBREDIR
+ g_mutex_clear(&channel->priv->device_connect_mutex);
+#endif
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_usbredir_channel_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_usbredir_channel_parent_class)->finalize(obj);
+}
+
+static void channel_set_handlers(SpiceChannelClass *klass)
+{
+ static const spice_msg_handler handlers[] = {
+ [ SPICE_MSG_SPICEVMC_DATA ] = usbredir_handle_msg,
+ [ SPICE_MSG_SPICEVMC_COMPRESSED_DATA ] = usbredir_handle_msg,
+ };
+
+ spice_channel_set_handlers(klass, handlers, G_N_ELEMENTS(handlers));
+}
+
+/* ------------------------------------------------------------------ */
+/* private api */
+
+G_GNUC_INTERNAL
+void spice_usbredir_channel_set_context(SpiceUsbredirChannel *channel,
+ libusb_context *context)
+{
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+ g_return_if_fail(priv->host == NULL);
+
+ priv->context = context;
+ priv->host = usbredirhost_open_full(
+ context, NULL,
+ usbredir_log,
+ usbredir_read_callback,
+ usbredir_write_callback,
+ usbredir_write_flush_callback,
+ usbredir_alloc_lock,
+ usbredir_lock_lock,
+ usbredir_unlock_lock,
+ usbredir_free_lock,
+ channel, PACKAGE_STRING,
+ spice_util_get_debug() ? usbredirparser_debug : usbredirparser_warning,
+ usbredirhost_fl_write_cb_owns_buffer);
+ if (!priv->host)
+ g_error("Out of memory allocating usbredirhost");
+
+#if USBREDIR_VERSION >= 0x000701
+ usbredirhost_set_buffered_output_size_cb(priv->host, usbredir_buffered_output_size_callback);
+#endif
+#ifdef USE_LZ4
+ spice_channel_set_capability(channel, SPICE_SPICEVMC_CAP_DATA_COMPRESS_LZ4);
+#endif
+}
+
+static gboolean spice_usbredir_channel_open_device(
+ SpiceUsbredirChannel *channel, GError **err)
+{
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+ SpiceSession *session;
+ libusb_device_handle *handle = NULL;
+ int rc, status;
+
+ g_return_val_if_fail(priv->state == STATE_DISCONNECTED
+#ifdef USE_POLKIT
+ || priv->state == STATE_WAITING_FOR_ACL_HELPER
+#endif
+ , FALSE);
+
+ rc = libusb_open(priv->device, &handle);
+ if (rc != 0) {
+ g_set_error(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Could not open usb device: %s [%i]",
+ spice_usbutil_libusb_strerror(rc), rc);
+ return FALSE;
+ }
+
+ priv->catch_error = err;
+ status = usbredirhost_set_device(priv->host, handle);
+ priv->catch_error = NULL;
+ if (status != usb_redir_success) {
+ g_return_val_if_fail(err == NULL || *err != NULL, FALSE);
+ return FALSE;
+ }
+
+ session = spice_channel_get_session(SPICE_CHANNEL(channel));
+ priv->usb_device_manager = g_object_ref(spice_usb_device_manager_get(session, NULL));
+ if (!spice_usb_device_manager_start_event_listening(priv->usb_device_manager, err)) {
+ usbredirhost_set_device(priv->host, NULL);
+ return FALSE;
+ }
+
+ priv->state = STATE_CONNECTED;
+
+ return TRUE;
+}
+
+#ifdef USE_POLKIT
+static void spice_usbredir_channel_open_acl_cb(
+ GObject *gobject, GAsyncResult *acl_res, gpointer user_data)
+{
+ SpiceUsbAclHelper *acl_helper = SPICE_USB_ACL_HELPER(gobject);
+ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(user_data);
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+ GError *err = NULL;
+
+ g_return_if_fail(acl_helper == priv->acl_helper);
+ g_return_if_fail(priv->state == STATE_WAITING_FOR_ACL_HELPER ||
+ priv->state == STATE_DISCONNECTING);
+
+ spice_usb_acl_helper_open_acl_finish(acl_helper, acl_res, &err);
+ if (!err && priv->state == STATE_DISCONNECTING) {
+ err = g_error_new_literal(G_IO_ERROR, G_IO_ERROR_CANCELLED,
+ "USB redirection channel connect cancelled");
+ }
+ if (!err) {
+ spice_usbredir_channel_open_device(channel, &err);
+ }
+ if (err) {
+ g_clear_pointer(&priv->device, libusb_unref_device);
+ g_boxed_free(spice_usb_device_get_type(), priv->spice_device);
+ priv->spice_device = NULL;
+ priv->state = STATE_DISCONNECTED;
+ g_task_return_error(priv->task, err);
+ } else {
+ g_task_return_boolean(priv->task, TRUE);
+ }
+
+ g_clear_object(&priv->acl_helper);
+ g_object_set(spice_channel_get_session(SPICE_CHANNEL(channel)),
+ "inhibit-keyboard-grab", FALSE, NULL);
+
+ g_clear_object(&priv->task);
+}
+#endif
+
+#ifndef USE_POLKIT
+static void
+_open_device_async_cb(GTask *task,
+ gpointer object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ GError *err = NULL;
+ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(object);
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+ spice_usbredir_channel_lock(channel);
+
+ if (!spice_usbredir_channel_open_device(channel, &err)) {
+ g_clear_pointer(&priv->device, libusb_unref_device);
+ g_boxed_free(spice_usb_device_get_type(), priv->spice_device);
+ priv->spice_device = NULL;
+ }
+
+ spice_usbredir_channel_unlock(channel);
+
+ if (err) {
+ g_task_return_error(task, err);
+ } else {
+ g_task_return_boolean(task, TRUE);
+ }
+}
+#endif
+
+G_GNUC_INTERNAL
+void spice_usbredir_channel_connect_device_async(
+ SpiceUsbredirChannel *channel,
+ libusb_device *device,
+ SpiceUsbDevice *spice_device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+ GTask *task;
+
+ g_return_if_fail(SPICE_IS_USBREDIR_CHANNEL(channel));
+ g_return_if_fail(device != NULL);
+
+ CHANNEL_DEBUG(channel, "connecting device %04x:%04x (%p) to channel %p",
+ spice_usb_device_get_vid(spice_device),
+ spice_usb_device_get_pid(spice_device),
+ spice_device, channel);
+
+ task = g_task_new(channel, cancellable, callback, user_data);
+
+ if (!priv->host) {
+ g_task_return_new_error(task,
+ SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Error libusb context not set");
+ goto done;
+ }
+
+ if (priv->state != STATE_DISCONNECTED) {
+ g_task_return_new_error(task,
+ SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Error channel is busy");
+ goto done;
+ }
+
+ priv->device = libusb_ref_device(device);
+ priv->spice_device = g_boxed_copy(spice_usb_device_get_type(),
+ spice_device);
+#ifdef USE_POLKIT
+ priv->task = task;
+ priv->state = STATE_WAITING_FOR_ACL_HELPER;
+ priv->acl_helper = spice_usb_acl_helper_new();
+ g_object_set(spice_channel_get_session(SPICE_CHANNEL(channel)),
+ "inhibit-keyboard-grab", TRUE, NULL);
+ spice_usb_acl_helper_open_acl_async(priv->acl_helper,
+ libusb_get_bus_number(device),
+ libusb_get_device_address(device),
+ cancellable,
+ spice_usbredir_channel_open_acl_cb,
+ channel);
+ return;
+#else
+ g_task_run_in_thread(task, _open_device_async_cb);
+#endif
+
+done:
+ g_object_unref(task);
+}
+
+G_GNUC_INTERNAL
+gboolean spice_usbredir_channel_connect_device_finish(
+ SpiceUsbredirChannel *channel,
+ GAsyncResult *res,
+ GError **err)
+{
+ GTask *task = G_TASK(res);
+
+ g_return_val_if_fail(g_task_is_valid(task, channel), FALSE);
+
+ return g_task_propagate_boolean(task, err);
+}
+
+G_GNUC_INTERNAL
+void spice_usbredir_channel_disconnect_device(SpiceUsbredirChannel *channel)
+{
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+ CHANNEL_DEBUG(channel, "disconnecting device from usb channel %p", channel);
+
+ spice_usbredir_channel_lock(channel);
+
+ switch (priv->state) {
+ case STATE_DISCONNECTED:
+ case STATE_DISCONNECTING:
+ break;
+#ifdef USE_POLKIT
+ case STATE_WAITING_FOR_ACL_HELPER:
+ priv->state = STATE_DISCONNECTING;
+ /* We're still waiting for the acl helper -> cancel it */
+ spice_usb_acl_helper_cancel(priv->acl_helper);
+ break;
+#endif
+ case STATE_CONNECTED:
+ /*
+ * This sets the usb event thread run condition to FALSE, therefor
+ * it must be done before usbredirhost_set_device NULL, as
+ * usbredirhost_set_device NULL will interrupt the
+ * libusb_handle_events call in the thread.
+ */
+ g_warn_if_fail(priv->usb_device_manager != NULL);
+ spice_usb_device_manager_stop_event_listening(priv->usb_device_manager);
+ g_clear_object(&priv->usb_device_manager);
+
+ /* This also closes the libusb handle we passed from open_device */
+ usbredirhost_set_device(priv->host, NULL);
+ g_clear_pointer(&priv->device, libusb_unref_device);
+ g_boxed_free(spice_usb_device_get_type(), priv->spice_device);
+ priv->spice_device = NULL;
+ priv->state = STATE_DISCONNECTED;
+ break;
+ }
+
+ spice_usbredir_channel_unlock(channel);
+}
+
+static void
+_disconnect_device_thread(GTask *task,
+ gpointer object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ spice_usbredir_channel_disconnect_device(SPICE_USBREDIR_CHANNEL(object));
+ g_task_return_boolean(task, TRUE);
+}
+
+G_GNUC_INTERNAL
+gboolean spice_usbredir_channel_disconnect_device_finish(
+ SpiceUsbredirChannel *channel,
+ GAsyncResult *res,
+ GError **err)
+{
+ return g_task_propagate_boolean(G_TASK(res), err);
+}
+
+G_GNUC_INTERNAL
+void spice_usbredir_channel_disconnect_device_async(SpiceUsbredirChannel *channel,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask* task = g_task_new(channel, cancellable, callback, user_data);
+
+ g_return_if_fail(channel != NULL);
+ g_task_run_in_thread(task, _disconnect_device_thread);
+ g_object_unref(task);
+}
+
+static SpiceUsbDevice *
+spice_usbredir_channel_get_spice_usb_device(SpiceUsbredirChannel *channel)
+{
+ return channel->priv->spice_device;
+}
+
+G_GNUC_INTERNAL
+libusb_device *spice_usbredir_channel_get_device(SpiceUsbredirChannel *channel)
+{
+ return channel->priv->device;
+}
+
+G_GNUC_INTERNAL
+void spice_usbredir_channel_get_guest_filter(
+ SpiceUsbredirChannel *channel,
+ const struct usbredirfilter_rule **rules_ret,
+ int *rules_count_ret)
+{
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+ g_return_if_fail(priv->host != NULL);
+
+ usbredirhost_get_guest_filter(priv->host, rules_ret, rules_count_ret);
+}
+
+/* ------------------------------------------------------------------ */
+/* callbacks (any context) */
+
+#if USBREDIR_VERSION >= 0x000701
+static uint64_t usbredir_buffered_output_size_callback(void *user_data)
+{
+ g_return_val_if_fail(SPICE_IS_USBREDIR_CHANNEL(user_data), 0);
+ return spice_channel_get_queue_size(SPICE_CHANNEL(user_data));
+}
+#endif
+
+/* Note that this function must be re-entrant safe, as it can get called
+ from both the main thread as well as from the usb event handling thread */
+static void usbredir_write_flush_callback(void *user_data)
+{
+ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(user_data);
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+ if (spice_channel_get_state(SPICE_CHANNEL(channel)) !=
+ SPICE_CHANNEL_STATE_READY)
+ return;
+
+ if (!priv->host)
+ return;
+
+ usbredirhost_write_guest_data(priv->host);
+}
+
+static void usbredir_log(void *user_data, int level, const char *msg)
+{
+ SpiceUsbredirChannel *channel = user_data;
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+ if (priv->catch_error && level == usbredirparser_error) {
+ CHANNEL_DEBUG(channel, "%s", msg);
+ /* Remove "usbredirhost: " prefix from usbredirhost messages */
+ if (strncmp(msg, "usbredirhost: ", 14) == 0)
+ g_set_error_literal(priv->catch_error, SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED, msg + 14);
+ else
+ g_set_error_literal(priv->catch_error, SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED, msg);
+ return;
+ }
+
+ switch (level) {
+ case usbredirparser_error:
+ g_critical("%s", msg); break;
+ case usbredirparser_warning:
+ g_warning("%s", msg); break;
+ default:
+ CHANNEL_DEBUG(channel, "%s", msg); break;
+ }
+}
+
+static int usbredir_read_callback(void *user_data, uint8_t *data, int count)
+{
+ SpiceUsbredirChannel *channel = user_data;
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+ if (priv->read_buf_size < count) {
+ count = priv->read_buf_size;
+ }
+
+ memcpy(data, priv->read_buf, count);
+
+ priv->read_buf_size -= count;
+ if (priv->read_buf_size) {
+ priv->read_buf += count;
+ } else {
+ priv->read_buf = NULL;
+ }
+
+ return count;
+}
+
+static void usbredir_free_write_cb_data(uint8_t *data, void *user_data)
+{
+ SpiceUsbredirChannel *channel = user_data;
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+ usbredirhost_free_write_buffer(priv->host, data);
+}
+
+#ifdef USE_LZ4
+static int try_write_compress_LZ4(SpiceUsbredirChannel *channel, uint8_t *data, int count)
+{
+ SpiceChannelPrivate *c;
+ SpiceMsgOut *msg_out_compressed;
+ int bound, compressed_data_count;
+ uint8_t *compressed_buf;
+ SpiceMsgCompressedData compressed_data_msg = {
+ .type = SPICE_DATA_COMPRESSION_TYPE_LZ4,
+ .uncompressed_size = count
+ };
+
+ c = SPICE_CHANNEL(channel)->priv;
+ if (g_socket_get_family(c->sock) == G_SOCKET_FAMILY_UNIX) {
+ /* AF_LOCAL socket - data will not be compressed */
+ return FALSE;
+ }
+ if (count <= COMPRESS_THRESHOLD) {
+ /* Not enough data to compress */
+ return FALSE;
+ }
+ if (!spice_channel_test_capability(SPICE_CHANNEL(channel),
+ SPICE_SPICEVMC_CAP_DATA_COMPRESS_LZ4)) {
+ /* No server compression capability - data will not be compressed */
+ return FALSE;
+ }
+ if (spice_usb_device_is_isochronous(spice_usbredir_channel_get_spice_usb_device(channel))) {
+ /* Don't compress - one of the device endpoints is isochronous */
+ return FALSE;
+ }
+ bound = LZ4_compressBound(count);
+ if (bound == 0) {
+ /* Invalid bound - data will not be compressed */
+ return FALSE;
+ }
+
+ compressed_buf = g_malloc(bound);
+ compressed_data_count = LZ4_compress_default((char*)data,
+ (char*)compressed_buf,
+ count,
+ bound);
+ if (compressed_data_count > 0 && compressed_data_count < count) {
+ compressed_data_msg.compressed_data = compressed_buf;
+ msg_out_compressed = spice_msg_out_new(SPICE_CHANNEL(channel),
+ SPICE_MSGC_SPICEVMC_COMPRESSED_DATA);
+ msg_out_compressed->marshallers->msg_SpiceMsgCompressedData(msg_out_compressed->marshaller,
+ &compressed_data_msg);
+ spice_marshaller_add_ref_full(msg_out_compressed->marshaller,
+ compressed_data_msg.compressed_data,
+ compressed_data_count,
+ (spice_marshaller_item_free_func)g_free,
+ channel);
+ spice_msg_out_send(msg_out_compressed);
+ return TRUE;
+ }
+
+ /* if not - free & fallback to sending the message uncompressed */
+ g_free(compressed_buf);
+ return FALSE;
+}
+#endif
+
+static int usbredir_write_callback(void *user_data, uint8_t *data, int count)
+{
+ SpiceUsbredirChannel *channel = user_data;
+ SpiceMsgOut *msg_out;
+
+#ifdef USE_LZ4
+ if (try_write_compress_LZ4(channel, data, count)) {
+ usbredirhost_free_write_buffer(channel->priv->host, data);
+ return count;
+ }
+#endif
+ msg_out = spice_msg_out_new(SPICE_CHANNEL(channel),
+ SPICE_MSGC_SPICEVMC_DATA);
+ spice_marshaller_add_ref_full(msg_out->marshaller, data, count,
+ usbredir_free_write_cb_data, channel);
+ spice_msg_out_send(msg_out);
+
+ return count;
+}
+
+static void *usbredir_alloc_lock(void) {
+ GMutex *mutex;
+
+ mutex = g_new0(GMutex, 1);
+ g_mutex_init(mutex);
+
+ return mutex;
+}
+
+G_GNUC_INTERNAL
+void spice_usbredir_channel_lock(SpiceUsbredirChannel *channel)
+{
+ g_mutex_lock(&channel->priv->device_connect_mutex);
+}
+
+G_GNUC_INTERNAL
+void spice_usbredir_channel_unlock(SpiceUsbredirChannel *channel)
+{
+ g_mutex_unlock(&channel->priv->device_connect_mutex);
+}
+
+static void usbredir_lock_lock(void *user_data) {
+ GMutex *mutex = user_data;
+
+ g_mutex_lock(mutex);
+}
+
+static void usbredir_unlock_lock(void *user_data) {
+ GMutex *mutex = user_data;
+
+ g_mutex_unlock(mutex);
+}
+
+static void usbredir_free_lock(void *user_data) {
+ GMutex *mutex = user_data;
+
+ g_mutex_clear(mutex);
+ g_free(mutex);
+}
+
+/* --------------------------------------------------------------------- */
+
+typedef struct device_error_data {
+ SpiceUsbredirChannel *channel;
+ SpiceUsbDevice *spice_device;
+ GError *error;
+ struct coroutine *caller;
+} device_error_data;
+
+/* main context */
+static gboolean device_error(gpointer user_data)
+{
+ device_error_data *data = user_data;
+ SpiceUsbredirChannel *channel = data->channel;
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+ /* Check that the device has not changed before we manage to run */
+ if (data->spice_device == priv->spice_device) {
+ spice_usbredir_channel_disconnect_device(channel);
+ spice_usb_device_manager_device_error(
+ spice_usb_device_manager_get(
+ spice_channel_get_session(SPICE_CHANNEL(channel)), NULL),
+ data->spice_device, data->error);
+ }
+
+ coroutine_yieldto(data->caller, NULL);
+ return FALSE;
+}
+
+/* --------------------------------------------------------------------- */
+/* coroutine context */
+static void spice_usbredir_channel_up(SpiceChannel *c)
+{
+ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(c);
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+
+ /* Flush any pending writes */
+ usbredirhost_write_guest_data(priv->host);
+}
+
+static int try_handle_compressed_msg(SpiceMsgCompressedData *compressed_data_msg,
+ uint8_t **buf,
+ int *size) {
+ int decompressed_size = 0;
+ char *decompressed = NULL;
+
+ if (compressed_data_msg->uncompressed_size == 0) {
+ spice_warning("Invalid uncompressed_size");
+ return FALSE;
+ }
+
+ switch (compressed_data_msg->type) {
+#ifdef USE_LZ4
+ case SPICE_DATA_COMPRESSION_TYPE_LZ4:
+ decompressed = g_malloc(compressed_data_msg->uncompressed_size);
+ decompressed_size = LZ4_decompress_safe ((char*)compressed_data_msg->compressed_data,
+ decompressed,
+ compressed_data_msg->compressed_size,
+ compressed_data_msg->uncompressed_size);
+ break;
+#endif
+ default:
+ spice_warning("Unknown Compression Type");
+ return FALSE;
+ }
+ if (decompressed_size != compressed_data_msg->uncompressed_size) {
+ spice_warning("Decompress Error decompressed_size=%d expected=%u",
+ decompressed_size, compressed_data_msg->uncompressed_size);
+ g_free(decompressed);
+ return FALSE;
+ }
+
+ *size = decompressed_size;
+ *buf = (uint8_t*)decompressed;
+ return TRUE;
+
+}
+
+static void usbredir_handle_msg(SpiceChannel *c, SpiceMsgIn *in)
+{
+ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(c);
+ SpiceUsbredirChannelPrivate *priv = channel->priv;
+ int r = 0, size;
+ uint8_t *buf;
+
+ g_return_if_fail(priv->host != NULL);
+
+ /* No recursion allowed! */
+ g_return_if_fail(priv->read_buf == NULL);
+
+ if (spice_msg_in_type(in) == SPICE_MSG_SPICEVMC_COMPRESSED_DATA) {
+ SpiceMsgCompressedData *compressed_data_msg = spice_msg_in_parsed(in);
+ if (try_handle_compressed_msg(compressed_data_msg, &buf, &size)) {
+ priv->read_buf_size = size;
+ priv->read_buf = buf;
+ } else {
+ r = usbredirhost_read_parse_error;
+ }
+ } else { /* Regular SPICE_MSG_SPICEVMC_DATA msg */
+ buf = spice_msg_in_raw(in, &size);
+ priv->read_buf_size = size;
+ priv->read_buf = buf;
+ }
+
+ spice_usbredir_channel_lock(channel);
+ if (r == 0)
+ r = usbredirhost_read_guest_data(priv->host);
+ if (r != 0) {
+ SpiceUsbDevice *spice_device = priv->spice_device;
+ device_error_data err_data;
+ gchar *desc;
+ GError *err;
+
+ if (spice_device == NULL) {
+ spice_usbredir_channel_unlock(channel);
+ return;
+ }
+
+ desc = spice_usb_device_get_description(spice_device, NULL);
+ switch (r) {
+ case usbredirhost_read_parse_error:
+ err = g_error_new(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("usbredir protocol parse error for %s"), desc);
+ break;
+ case usbredirhost_read_device_rejected:
+ err = g_error_new(SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_USB_DEVICE_REJECTED,
+ _("%s rejected by host"), desc);
+ break;
+ case usbredirhost_read_device_lost:
+ err = g_error_new(SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_USB_DEVICE_LOST,
+ _("%s disconnected (fatal IO error)"), desc);
+ break;
+ default:
+ err = g_error_new(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("Unknown error (%d) for %s"), r, desc);
+ }
+ g_free(desc);
+
+ CHANNEL_DEBUG(c, "%s", err->message);
+
+ err_data.channel = channel;
+ err_data.caller = coroutine_self();
+ err_data.spice_device = g_boxed_copy(spice_usb_device_get_type(), spice_device);
+ err_data.error = err;
+ g_idle_add(device_error, &err_data);
+ coroutine_yield(NULL);
+
+ g_boxed_free(spice_usb_device_get_type(), err_data.spice_device);
+
+ g_error_free(err);
+ }
+
+ spice_usbredir_channel_unlock(channel);
+}
+
+#endif /* USE_USBREDIR */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_USBREDIR_CHANNEL_H__
+#define __SPICE_CLIENT_USBREDIR_CHANNEL_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_USBREDIR_CHANNEL (spice_usbredir_channel_get_type())
+#define SPICE_USBREDIR_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_USBREDIR_CHANNEL, SpiceUsbredirChannel))
+#define SPICE_USBREDIR_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_USBREDIR_CHANNEL, SpiceUsbredirChannelClass))
+#define SPICE_IS_USBREDIR_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_USBREDIR_CHANNEL))
+#define SPICE_IS_USBREDIR_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_USBREDIR_CHANNEL))
+#define SPICE_USBREDIR_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_USBREDIR_CHANNEL, SpiceUsbredirChannelClass))
+
+typedef struct _SpiceUsbredirChannel SpiceUsbredirChannel;
+typedef struct _SpiceUsbredirChannelClass SpiceUsbredirChannelClass;
+typedef struct _SpiceUsbredirChannelPrivate SpiceUsbredirChannelPrivate;
+
+/**
+ * SpiceUsbredirChannel:
+ *
+ * The #SpiceUsbredirChannel struct is opaque and should not be accessed directly.
+ */
+struct _SpiceUsbredirChannel {
+ SpiceChannel parent;
+
+ /*< private >*/
+ SpiceUsbredirChannelPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpiceUsbredirChannelClass:
+ * @parent_class: Parent class.
+ *
+ * Class structure for #SpiceUsbredirChannel.
+ */
+struct _SpiceUsbredirChannelClass {
+ SpiceChannelClass parent_class;
+
+ /* signals */
+
+ /*< private >*/
+ /* Do not add fields to this struct */
+};
+
+GType spice_usbredir_channel_get_type(void);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_USBREDIR_CHANNEL_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+#include "spice-channel-priv.h"
+#include "spice-session-priv.h"
+#include "spice-marshal.h"
+#include "vmcstream.h"
+#include "giopipe.h"
+
+/**
+ * SECTION:channel-webdav
+ * @short_description: exports a directory
+ * @title: WebDAV Channel
+ * @section_id:
+ * @see_also: #SpiceChannel
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * The "webdav" channel exports a directory to the guest for file
+ * manipulation (read/write/copy etc). The underlying protocol is
+ * implemented using WebDAV (RFC 4918).
+ *
+ * By default, the shared directory is the one associated with GLib
+ * %G_USER_DIRECTORY_PUBLIC_SHARE. You can specify a different
+ * directory with #SpiceSession #SpiceSession:shared-dir property.
+ *
+ * Since: 0.24
+ */
+
+#define SPICE_WEBDAV_CHANNEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_WEBDAV_CHANNEL, SpiceWebdavChannelPrivate))
+
+typedef struct _OutputQueue OutputQueue;
+
+struct _SpiceWebdavChannelPrivate {
+ SpiceVmcStream *stream;
+ GCancellable *cancellable;
+ GHashTable *clients;
+ OutputQueue *queue;
+
+ gboolean demuxing;
+ struct _demux {
+ gint64 client;
+ guint16 size;
+ guint8 *buf;
+ } demux;
+};
+
+G_DEFINE_TYPE(SpiceWebdavChannel, spice_webdav_channel, SPICE_TYPE_PORT_CHANNEL)
+
+static void spice_webdav_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
+
+struct _OutputQueue {
+ GOutputStream *output;
+ gboolean flushing;
+ guint idle_id;
+ GQueue *queue;
+};
+
+typedef struct _OutputQueueElem {
+ OutputQueue *queue;
+ const guint8 *buf;
+ gsize size;
+ GFunc pushed_cb;
+ gpointer user_data;
+} OutputQueueElem;
+
+static OutputQueue* output_queue_new(GOutputStream *output)
+{
+ OutputQueue *queue = g_new0(OutputQueue, 1);
+
+ queue->output = g_object_ref(output);
+ queue->queue = g_queue_new();
+
+ return queue;
+}
+
+static void output_queue_free(OutputQueue *queue)
+{
+ g_warn_if_fail(g_queue_get_length(queue->queue) == 0);
+ g_warn_if_fail(!queue->flushing);
+
+ g_queue_free_full(queue->queue, g_free);
+ g_clear_object(&queue->output);
+ if (queue->idle_id)
+ g_source_remove(queue->idle_id);
+ g_free(queue);
+}
+
+static gboolean output_queue_idle(gpointer user_data);
+
+static void output_queue_flush_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ OutputQueueElem *e = user_data;
+ OutputQueue *q = e->queue;
+
+ q->flushing = FALSE;
+ g_output_stream_flush_finish(G_OUTPUT_STREAM(source_object),
+ res, &error);
+ if (error)
+ g_warning("error: %s", error->message);
+
+ g_clear_error(&error);
+
+ if (!q->idle_id)
+ q->idle_id = g_idle_add(output_queue_idle, q);
+
+ g_free(e);
+}
+
+static gboolean output_queue_idle(gpointer user_data)
+{
+ OutputQueue *q = user_data;
+ OutputQueueElem *e;
+ GError *error = NULL;
+
+ if (q->flushing) {
+ q->idle_id = 0;
+ return FALSE;
+ }
+
+ e = g_queue_pop_head(q->queue);
+ if (!e) {
+ q->idle_id = 0;
+ return FALSE;
+ }
+
+ if (!g_output_stream_write_all(q->output, e->buf, e->size, NULL, NULL, &error))
+ goto err;
+ else if (e->pushed_cb)
+ e->pushed_cb(q, e->user_data);
+
+ q->flushing = TRUE;
+ g_output_stream_flush_async(q->output, G_PRIORITY_DEFAULT, NULL, output_queue_flush_cb, e);
+
+ return TRUE;
+
+err:
+ g_warning("failed to write to output stream");
+ if (error)
+ g_warning("error: %s", error->message);
+ g_clear_error(&error);
+
+ q->idle_id = 0;
+ return FALSE;
+}
+
+static void output_queue_push(OutputQueue *q, const guint8 *buf, gsize size,
+ GFunc pushed_cb, gpointer user_data)
+{
+ OutputQueueElem *e = g_new(OutputQueueElem, 1);
+
+ e->buf = buf;
+ e->size = size;
+ e->pushed_cb = pushed_cb;
+ e->user_data = user_data;
+ e->queue = q;
+ g_queue_push_tail(q->queue, e);
+
+ if (!q->idle_id && !q->flushing)
+ q->idle_id = g_idle_add(output_queue_idle, q);
+}
+
+typedef struct Client
+{
+ guint refs;
+ SpiceWebdavChannel *self;
+ GIOStream *pipe;
+ gint64 id;
+ GCancellable *cancellable;
+
+ struct _mux {
+ gint64 id;
+ guint16 size;
+ guint8 *buf;
+ } mux;
+} Client;
+
+static void
+client_unref(Client *client)
+{
+ if (--client->refs > 0)
+ return;
+
+ g_free(client->mux.buf);
+
+ g_object_unref(client->pipe);
+ g_object_unref(client->cancellable);
+
+ g_free(client);
+}
+
+static Client *
+client_ref(Client *client)
+{
+ client->refs++;
+ return client;
+}
+
+static void client_start_read(Client *client);
+
+static void remove_client(Client *client)
+{
+ if (g_cancellable_is_cancelled(client->cancellable))
+ return;
+
+ g_cancellable_cancel(client->cancellable);
+
+ g_hash_table_remove(client->self->priv->clients, &client->id);
+}
+
+static void mux_pushed_cb(OutputQueue *q, gpointer user_data)
+{
+ Client *client = user_data;
+
+ if (client->mux.size == 0) {
+ remove_client(client);
+ } else {
+ client_start_read(client);
+ }
+
+ client_unref(client);
+}
+
+#define MAX_MUX_SIZE G_MAXUINT16
+
+static void server_reply_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ Client *client = user_data;
+ SpiceWebdavChannelPrivate *c = client->self->priv;
+ GError *err = NULL;
+ gssize size;
+
+ size = g_input_stream_read_finish(G_INPUT_STREAM(source_object), res, &err);
+ if (err || g_cancellable_is_cancelled(client->cancellable))
+ goto end;
+
+ g_return_if_fail(size <= MAX_MUX_SIZE);
+ g_return_if_fail(size >= 0);
+ client->mux.size = size;
+
+ output_queue_push(c->queue, (guint8 *)&client->mux.id, sizeof(gint64), NULL, NULL);
+ client->mux.size = GUINT16_TO_LE(client->mux.size);
+ output_queue_push(c->queue, (guint8 *)&client->mux.size, sizeof(guint16), NULL, NULL);
+ output_queue_push(c->queue, (guint8 *)client->mux.buf, size, (GFunc)mux_pushed_cb, client);
+
+ return;
+
+end:
+ if (err) {
+ if (!g_cancellable_is_cancelled(client->cancellable))
+ g_warning("read error: %s", err->message);
+ remove_client(client);
+ g_clear_error(&err);
+ }
+
+ client_unref(client);
+}
+
+static void client_start_read(Client *client)
+{
+ GInputStream *input;
+
+ input = g_io_stream_get_input_stream(G_IO_STREAM(client->pipe));
+ g_input_stream_read_async(input, client->mux.buf, MAX_MUX_SIZE,
+ G_PRIORITY_DEFAULT, client->cancellable, server_reply_cb,
+ client_ref(client));
+}
+
+static void start_demux(SpiceWebdavChannel *self);
+
+#ifdef USE_PHODAV
+static void demux_to_client_finish(Client *client, gboolean fail)
+{
+ SpiceWebdavChannel *self = client->self;
+ SpiceWebdavChannelPrivate *c = self->priv;
+
+ if (fail) {
+ remove_client(client);
+ }
+
+ c->demuxing = FALSE;
+ start_demux(self);
+}
+
+static void demux_to_client_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Client *client = user_data;
+ SpiceWebdavChannelPrivate *c = client->self->priv;
+ GError *error = NULL;
+ gboolean fail;
+ gsize size;
+
+ g_output_stream_write_all_finish(G_OUTPUT_STREAM(source), result, &size, &error);
+
+ if (error) {
+ CHANNEL_DEBUG(client->self, "write failed: %s", error->message);
+ g_clear_error(&error);
+ }
+
+ fail = (size != c->demux.size);
+ g_warn_if_fail(size == c->demux.size);
+ demux_to_client_finish(client, fail);
+}
+#endif
+
+static void demux_to_client(Client *client)
+{
+#ifdef USE_PHODAV
+ SpiceWebdavChannelPrivate *c = client->self->priv;
+ gsize size = c->demux.size;
+
+ CHANNEL_DEBUG(client->self, "pushing %"G_GSIZE_FORMAT" to client %p", size, client);
+
+ if (size > 0) {
+ g_output_stream_write_all_async(g_io_stream_get_output_stream(client->pipe),
+ c->demux.buf, size, G_PRIORITY_DEFAULT,
+ c->cancellable, demux_to_client_cb, client);
+ return;
+ } else {
+ /* Nothing to write */
+ demux_to_client_finish(client, FALSE);
+ }
+#endif
+}
+
+static void start_client(SpiceWebdavChannel *self)
+{
+#ifdef USE_PHODAV
+ SpiceWebdavChannelPrivate *c = self->priv;
+ Client *client;
+ GIOStream *peer = NULL;
+ SpiceSession *session;
+ SoupServer *server;
+ GSocketAddress *addr;
+ GError *error = NULL;
+
+ session = spice_channel_get_session(SPICE_CHANNEL(self));
+ server = phodav_server_get_soup_server(spice_session_get_webdav_server(session));
+
+ CHANNEL_DEBUG(self, "starting client %" G_GINT64_FORMAT, c->demux.client);
+
+ client = g_new0(Client, 1);
+ client->refs = 1;
+ client->id = c->demux.client;
+ client->self = self;
+ client->mux.id = GINT64_TO_LE(client->id);
+ client->mux.buf = g_malloc0(MAX_MUX_SIZE);
+ client->cancellable = g_cancellable_new();
+ spice_make_pipe(&client->pipe, &peer);
+
+ addr = g_inet_socket_address_new_from_string ("127.0.0.1", 0);
+ if (!soup_server_accept_iostream(server, peer, addr, addr, &error))
+ goto fail;
+
+ g_hash_table_insert(c->clients, &client->id, client);
+
+ client_start_read(client);
+ demux_to_client(client);
+
+ g_clear_object(&addr);
+ return;
+
+fail:
+ if (error)
+ CHANNEL_DEBUG(self, "failed to start client: %s", error->message);
+
+ g_clear_object(&addr);
+ g_clear_object(&peer);
+ g_clear_error(&error);
+ client_unref(client);
+#endif
+}
+
+static void data_read_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceWebdavChannel *self = user_data;
+ SpiceWebdavChannelPrivate *c;
+ Client *client;
+ GError *error = NULL;
+ gssize size;
+
+ size = spice_vmc_input_stream_read_all_finish(G_INPUT_STREAM(source_object), res, &error);
+ if (error) {
+ g_warning("error: %s", error->message);
+ g_clear_error(&error);
+ return;
+ }
+
+ c = self->priv;
+ g_return_if_fail(size == c->demux.size);
+
+ client = g_hash_table_lookup(c->clients, &c->demux.client);
+
+ if (client)
+ demux_to_client(client);
+ else
+ start_client(self);
+}
+
+
+static void size_read_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceWebdavChannel *self = user_data;
+ SpiceWebdavChannelPrivate *c;
+ GInputStream *istream = G_INPUT_STREAM(source_object);
+ GError *error = NULL;
+ gssize size;
+
+ size = spice_vmc_input_stream_read_all_finish(G_INPUT_STREAM(source_object), res, &error);
+ if (error || size != sizeof(guint16))
+ goto end;
+
+ c = self->priv;
+ c->demux.size = GUINT16_FROM_LE(c->demux.size);
+ spice_vmc_input_stream_read_all_async(istream,
+ c->demux.buf, c->demux.size,
+ G_PRIORITY_DEFAULT, c->cancellable, data_read_cb, self);
+ return;
+
+end:
+ if (error) {
+ g_warning("error: %s", error->message);
+ g_clear_error(&error);
+ }
+}
+
+static void client_read_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceWebdavChannel *self = user_data;
+ SpiceWebdavChannelPrivate *c = self->priv;
+ GInputStream *istream = G_INPUT_STREAM(source_object);
+ GError *error = NULL;
+ gssize size;
+
+ size = spice_vmc_input_stream_read_all_finish(G_INPUT_STREAM(source_object), res, &error);
+ if (error || size != sizeof(gint64))
+ goto end;
+
+ c->demux.client = GINT64_FROM_LE(c->demux.client);
+ spice_vmc_input_stream_read_all_async(istream,
+ &c->demux.size, sizeof(guint16),
+ G_PRIORITY_DEFAULT, c->cancellable, size_read_cb, self);
+ return;
+
+end:
+ if (error) {
+ g_warning("error: %s", error->message);
+ g_clear_error(&error);
+ }
+}
+
+static void start_demux(SpiceWebdavChannel *self)
+{
+ SpiceWebdavChannelPrivate *c = self->priv;
+ GInputStream *istream = g_io_stream_get_input_stream(G_IO_STREAM(c->stream));
+
+ if (c->demuxing)
+ return;
+
+ c->demuxing = TRUE;
+
+ CHANNEL_DEBUG(self, "start demux");
+ spice_vmc_input_stream_read_all_async(istream, &c->demux.client, sizeof(gint64),
+ G_PRIORITY_DEFAULT, c->cancellable, client_read_cb, self);
+
+}
+
+static void port_event(SpiceWebdavChannel *self, gint event)
+{
+ SpiceWebdavChannelPrivate *c = self->priv;
+
+ CHANNEL_DEBUG(self, "port event:%d", event);
+ if (event == SPICE_PORT_EVENT_OPENED) {
+ g_clear_object(&c->cancellable);
+ c->cancellable = g_cancellable_new();
+ start_demux(self);
+ } else {
+ g_cancellable_cancel(c->cancellable);
+ c->demuxing = FALSE;
+ g_hash_table_remove_all(c->clients);
+ }
+}
+
+static void client_remove_unref(gpointer data)
+{
+ Client *client = data;
+
+ g_cancellable_cancel(client->cancellable);
+ client_unref(client);
+}
+
+static void spice_webdav_channel_init(SpiceWebdavChannel *channel)
+{
+ SpiceWebdavChannelPrivate *c = SPICE_WEBDAV_CHANNEL_GET_PRIVATE(channel);
+
+ channel->priv = c;
+ c->stream = spice_vmc_stream_new(SPICE_CHANNEL(channel));
+ c->clients = g_hash_table_new_full(g_int64_hash, g_int64_equal,
+ NULL, client_remove_unref);
+ c->demux.buf = g_malloc0(MAX_MUX_SIZE);
+
+ GOutputStream *ostream = g_io_stream_get_output_stream(G_IO_STREAM(c->stream));
+ c->queue = output_queue_new(ostream);
+}
+
+static void spice_webdav_channel_finalize(GObject *object)
+{
+ SpiceWebdavChannelPrivate *c = SPICE_WEBDAV_CHANNEL(object)->priv;
+
+ g_free(c->demux.buf);
+
+ G_OBJECT_CLASS(spice_webdav_channel_parent_class)->finalize(object);
+}
+
+static void spice_webdav_channel_dispose(GObject *object)
+{
+ SpiceWebdavChannelPrivate *c = SPICE_WEBDAV_CHANNEL(object)->priv;
+
+ g_cancellable_cancel(c->cancellable);
+ g_clear_object(&c->cancellable);
+ g_clear_pointer(&c->queue, output_queue_free);
+ g_clear_object(&c->stream);
+ g_hash_table_unref(c->clients);
+
+ G_OBJECT_CLASS(spice_webdav_channel_parent_class)->dispose(object);
+}
+
+static void spice_webdav_channel_up(SpiceChannel *channel)
+{
+ CHANNEL_DEBUG(channel, "up");
+}
+
+static void spice_webdav_channel_class_init(SpiceWebdavChannelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceChannelClass *channel_class = SPICE_CHANNEL_CLASS(klass);
+
+ gobject_class->dispose = spice_webdav_channel_dispose;
+ gobject_class->finalize = spice_webdav_channel_finalize;
+ channel_class->handle_msg = spice_webdav_handle_msg;
+ channel_class->channel_up = spice_webdav_channel_up;
+
+ g_signal_override_class_handler("port-event",
+ SPICE_TYPE_WEBDAV_CHANNEL,
+ G_CALLBACK(port_event));
+
+ g_type_class_add_private(klass, sizeof(SpiceWebdavChannelPrivate));
+}
+
+/* coroutine context */
+static void webdav_handle_msg(SpiceChannel *channel, SpiceMsgIn *in)
+{
+ SpiceWebdavChannel *self = SPICE_WEBDAV_CHANNEL(channel);
+ SpiceWebdavChannelPrivate *c = self->priv;
+ int size;
+ uint8_t *buf;
+
+ buf = spice_msg_in_raw(in, &size);
+ CHANNEL_DEBUG(channel, "len:%d buf:%p", size, buf);
+
+ spice_vmc_input_stream_co_data(
+ SPICE_VMC_INPUT_STREAM(g_io_stream_get_input_stream(G_IO_STREAM(c->stream))),
+ buf, size);
+}
+
+
+/* coroutine context */
+static void spice_webdav_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
+{
+ int type = spice_msg_in_type(msg);
+ SpiceChannelClass *parent_class;
+
+ parent_class = SPICE_CHANNEL_CLASS(spice_webdav_channel_parent_class);
+
+ if (type == SPICE_MSG_SPICEVMC_DATA)
+ webdav_handle_msg(channel, msg);
+ else if (parent_class->handle_msg)
+ parent_class->handle_msg(channel, msg);
+ else
+ g_return_if_reached();
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_WEBDAV_CHANNEL_H__
+#define __SPICE_WEBDAV_CHANNEL_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include <gio/gio.h>
+#include "spice-client.h"
+#include "channel-port.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_WEBDAV_CHANNEL (spice_webdav_channel_get_type())
+#define SPICE_WEBDAV_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_WEBDAV_CHANNEL, SpiceWebdavChannel))
+#define SPICE_WEBDAV_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_WEBDAV_CHANNEL, SpiceWebdavChannelClass))
+#define SPICE_IS_WEBDAV_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_WEBDAV_CHANNEL))
+#define SPICE_IS_WEBDAV_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_WEBDAV_CHANNEL))
+#define SPICE_WEBDAV_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_WEBDAV_CHANNEL, SpiceWebdavChannelClass))
+
+typedef struct _SpiceWebdavChannel SpiceWebdavChannel;
+typedef struct _SpiceWebdavChannelClass SpiceWebdavChannelClass;
+typedef struct _SpiceWebdavChannelPrivate SpiceWebdavChannelPrivate;
+
+/**
+ * SpiceWebdavChannel:
+ *
+ * The #SpiceWebdavChannel struct is opaque and should not be accessed directly.
+ */
+struct _SpiceWebdavChannel {
+ SpicePortChannel parent;
+
+ /*< private >*/
+ SpiceWebdavChannelPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpiceWebdavChannelClass:
+ * @parent_class: Parent class.
+ *
+ * Class structure for #SpiceWebdavChannel.
+ */
+struct _SpiceWebdavChannelClass {
+ SpicePortChannelClass parent_class;
+
+ /*< private >*/
+ /* Do not add fields to this struct */
+};
+
+GType spice_webdav_channel_get_type(void);
+
+G_END_DECLS
+
+#endif /* __SPICE_WEBDAV_CHANNEL_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2014 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#define SW_CANVAS_CACHE
+
+#include "common/sw_canvas.c"
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2014 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_SW_CANVAS_H__
+#define __SPICE_CLIENT_SW_CANVAS_H__
+
+#define SW_CANVAS_CACHE
+
+#include <common/sw_canvas.h>
+
+#endif /* __SPICE_CLIENT_SW_CANVAS_H__ */
--- /dev/null
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.0 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "config.h"
+
+/* keep this above system headers, but below config.h */
+#ifdef _FORTIFY_SOURCE
+#undef _FORTIFY_SOURCE
+#endif
+
+#include <errno.h>
+#include <glib.h>
+
+#include "continuation.h"
+
+/*
+ * va_args to makecontext() must be type 'int', so passing
+ * the pointer we need may require several int args. This
+ * union is a quick hack to let us do that
+ */
+union cc_arg {
+ void *p;
+ int i[2];
+};
+
+static void continuation_trampoline(int i0, int i1)
+{
+ union cc_arg arg;
+ struct continuation *cc;
+ arg.i[0] = i0;
+ arg.i[1] = i1;
+ cc = arg.p;
+
+ if (_setjmp(cc->jmp) == 0) {
+ ucontext_t tmp;
+ swapcontext(&tmp, &cc->last);
+ }
+
+ cc->entry(cc);
+}
+
+void cc_init(struct continuation *cc)
+{
+ volatile union cc_arg arg;
+ arg.p = cc;
+ if (getcontext(&cc->uc) == -1)
+ g_error("getcontext() failed: %s", g_strerror(errno));
+ cc->uc.uc_link = &cc->last;
+ cc->uc.uc_stack.ss_sp = cc->stack;
+ cc->uc.uc_stack.ss_size = cc->stack_size;
+ cc->uc.uc_stack.ss_flags = 0;
+
+ makecontext(&cc->uc, (void *)continuation_trampoline, 2, arg.i[0], arg.i[1]);
+ swapcontext(&cc->last, &cc->uc);
+}
+
+int cc_release(struct continuation *cc)
+{
+ if (cc->release)
+ return cc->release(cc);
+
+ return 0;
+}
+
+int cc_swap(struct continuation *from, struct continuation *to)
+{
+ to->exited = 0;
+ if (getcontext(&to->last) == -1)
+ return -1;
+ else if (to->exited == 0)
+ to->exited = 1; // so when coroutine finishes
+ else if (to->exited == 1)
+ return 1; // it ends up here
+
+ if (_setjmp(from->jmp) == 0)
+ _longjmp(to->jmp, 1);
+
+ return 0;
+}
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
--- /dev/null
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.0 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _CONTINUATION_H_
+#define _CONTINUATION_H_
+
+#include <stddef.h>
+#include <ucontext.h>
+#include <setjmp.h>
+
+struct continuation
+{
+ char *stack;
+ size_t stack_size;
+ void (*entry)(struct continuation *cc);
+ int (*release)(struct continuation *cc);
+
+ /* private */
+ ucontext_t uc;
+ ucontext_t last;
+ int exited;
+ jmp_buf jmp;
+};
+
+void cc_init(struct continuation *cc);
+
+int cc_release(struct continuation *cc);
+
+/* you can use an uninitialized struct continuation for from if you do not have
+ the current continuation handy. */
+int cc_swap(struct continuation *from, struct continuation *to);
+
+#define offset_of(type, member) ((unsigned long)(&((type *)0)->member))
+#define container_of(obj, type, member) \
+ (type *)(((char *)obj) - offset_of(type, member))
+
+#endif
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
--- /dev/null
+NULL =
+
+AM_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\"GSpiceController\" \
+ $(GIO_CFLAGS) \
+ $(COMMON_CFLAGS) \
+ -Wno-deprecated-declarations \
+ $(NULL)
+
+# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+AM_LDFLAGS = \
+ -no-undefined \
+ $(GIO_LIBS) \
+ $(NULL)
+
+AM_VALAFLAGS = \
+ --pkg gio-2.0 \
+ --pkg spice-protocol --vapidir=$(top_srcdir)/data \
+ --pkg custom --vapidir=$(srcdir) \
+ -C \
+ $(NULL)
+
+lib_LTLIBRARIES = libspice-controller.la
+noinst_PROGRAMS = test-controller spice-controller-dump
+
+libspice_controller_la_VALASOURCES = \
+ menu.vala \
+ controller.vala \
+ foreign-menu.vala \
+ util.vala \
+ $(NULL)
+
+libspice_controller_la_BUILT_SOURCES = \
+ $(libspice_controller_la_VALASOURCES:.vala=.c) \
+ spice-controller.h \
+ $(NULL)
+
+BUILT_SOURCES = \
+ $(libspice_controller_la_BUILT_SOURCES) \
+ controller.vala.stamp \
+ $(NULL)
+
+libspice_controller_la_SOURCES = \
+ $(libspice_controller_la_BUILT_SOURCES) \
+ custom.h \
+ spice-controller-listener.c \
+ spice-controller-listener.h \
+ spice-foreign-menu-listener.c \
+ spice-foreign-menu-listener.h \
+ $(NULL)
+
+if OS_WIN32
+libspice_controller_la_SOURCES += \
+ namedpipe.c \
+ namedpipe.h \
+ namedpipeconnection.c \
+ namedpipeconnection.h \
+ namedpipelistener.c \
+ namedpipelistener.h \
+ win32-util.c \
+ win32-util.h \
+ $(NULL)
+endif
+libspice_controller_la_LDFLAGS = \
+ $(AM_LDFLAGS) \
+ -version-info 0:0:0 \
+ $(NULL)
+
+libspice_controllerincludedir = $(includedir)/spice-controller
+libspice_controllerinclude_HEADERS = \
+ spice-controller.h
+
+test_controller_SOURCES = test.c
+test_controller_LDADD = libspice-controller.la
+
+spice_controller_dump_SOURCES = dump.c
+spice_controller_dump_LDADD = libspice-controller.la
+
+controller.vala.stamp: $(libspice_controller_la_VALASOURCES) custom.vapi
+ @if test -z "$(VALAC)"; then \
+ echo "" ; \
+ echo " *** Error: missing valac!" ; \
+ echo " *** You must run autogen.sh or configure --enable-vala" ; \
+ echo "" ; \
+ exit 1 ; \
+ fi
+ $(VALA_V)$(VALAC) $(VALAFLAGS) $(AM_VALAFLAGS) \
+ $(addprefix $(srcdir)/,$(libspice_controller_la_VALASOURCES)) \
+ -H spice-controller.h
+ @touch $@
+
+$(libspice_controller_la_BUILT_SOURCES): controller.vala.stamp
+
+EXTRA_DIST = \
+ $(libspice_controller_la_VALASOURCES) \
+ controller.vala.stamp \
+ custom.vapi \
+ gio-windows-2.0.vapi \
+ $(NULL)
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = test-controller$(EXEEXT) \
+ spice-controller-dump$(EXEEXT)
+@OS_WIN32_TRUE@am__append_1 = \
+@OS_WIN32_TRUE@ namedpipe.c \
+@OS_WIN32_TRUE@ namedpipe.h \
+@OS_WIN32_TRUE@ namedpipeconnection.c \
+@OS_WIN32_TRUE@ namedpipeconnection.h \
+@OS_WIN32_TRUE@ namedpipelistener.c \
+@OS_WIN32_TRUE@ namedpipelistener.h \
+@OS_WIN32_TRUE@ win32-util.c \
+@OS_WIN32_TRUE@ win32-util.h \
+@OS_WIN32_TRUE@ $(NULL)
+
+subdir = src/controller
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/ld-version.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/manywarnings.m4 \
+ $(top_srcdir)/m4/spice-compile-warnings.m4 \
+ $(top_srcdir)/m4/warnings.m4 \
+ $(top_srcdir)/spice-common/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am \
+ $(libspice_controllerinclude_HEADERS) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(libdir)" \
+ "$(DESTDIR)$(libspice_controllerincludedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libspice_controller_la_LIBADD =
+am__libspice_controller_la_SOURCES_DIST = menu.c controller.c \
+ foreign-menu.c util.c spice-controller.h custom.h \
+ spice-controller-listener.c spice-controller-listener.h \
+ spice-foreign-menu-listener.c spice-foreign-menu-listener.h \
+ namedpipe.c namedpipe.h namedpipeconnection.c \
+ namedpipeconnection.h namedpipelistener.c namedpipelistener.h \
+ win32-util.c win32-util.h
+am__objects_1 =
+am__objects_2 = menu.lo controller.lo foreign-menu.lo util.lo \
+ $(am__objects_1)
+am__objects_3 = $(am__objects_2) $(am__objects_1)
+@OS_WIN32_TRUE@am__objects_4 = namedpipe.lo namedpipeconnection.lo \
+@OS_WIN32_TRUE@ namedpipelistener.lo win32-util.lo \
+@OS_WIN32_TRUE@ $(am__objects_1)
+am_libspice_controller_la_OBJECTS = $(am__objects_3) \
+ spice-controller-listener.lo spice-foreign-menu-listener.lo \
+ $(am__objects_1) $(am__objects_4)
+libspice_controller_la_OBJECTS = $(am_libspice_controller_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+libspice_controller_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libspice_controller_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+PROGRAMS = $(noinst_PROGRAMS)
+am_spice_controller_dump_OBJECTS = dump.$(OBJEXT)
+spice_controller_dump_OBJECTS = $(am_spice_controller_dump_OBJECTS)
+spice_controller_dump_DEPENDENCIES = libspice-controller.la
+am_test_controller_OBJECTS = test.$(OBJEXT)
+test_controller_OBJECTS = $(am_test_controller_OBJECTS)
+test_controller_DEPENDENCIES = libspice-controller.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libspice_controller_la_SOURCES) \
+ $(spice_controller_dump_SOURCES) $(test_controller_SOURCES)
+DIST_SOURCES = $(am__libspice_controller_la_SOURCES_DIST) \
+ $(spice_controller_dump_SOURCES) $(test_controller_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+HEADERS = $(libspice_controllerinclude_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACL_HELPER_DIR = @ACL_HELPER_DIR@
+ACL_LIBS = @ACL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMMON_CFLAGS = @COMMON_CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GOBJECT2_CFLAGS = @GOBJECT2_CFLAGS@
+GOBJECT2_LIBS = @GOBJECT2_LIBS@
+GREP = @GREP@
+GSTAUDIO_CFLAGS = @GSTAUDIO_CFLAGS@
+GSTAUDIO_LIBS = @GSTAUDIO_LIBS@
+GSTVIDEO_CFLAGS = @GSTVIDEO_CFLAGS@
+GSTVIDEO_LIBS = @GSTVIDEO_LIBS@
+GST_INSPECT_1_0 = @GST_INSPECT_1_0@
+GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
+GTHREAD_LIBS = @GTHREAD_LIBS@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_REQUIRED = @GTK_REQUIRED@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+JPEG_LIBS = @JPEG_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUSB_HOTPLUG_CFLAGS = @LIBUSB_HOTPLUG_CFLAGS@
+LIBUSB_HOTPLUG_LIBS = @LIBUSB_HOTPLUG_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PHODAV_CFLAGS = @PHODAV_CFLAGS@
+PHODAV_LIBS = @PHODAV_LIBS@
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PNP_IDS = @PNP_IDS@
+POFILES = @POFILES@
+POLICYDIR = @POLICYDIR@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PULSE_CFLAGS = @PULSE_CFLAGS@
+PULSE_LIBS = @PULSE_LIBS@
+PYTHON = @PYTHON@
+RANLIB = @RANLIB@
+SASL_CFLAGS = @SASL_CFLAGS@
+SASL_LIBS = @SASL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_CFLAGS = @SPICE_CFLAGS@
+SPICE_GLIB_CFLAGS = @SPICE_GLIB_CFLAGS@
+SPICE_GLIB_REQUIRES = @SPICE_GLIB_REQUIRES@
+SPICE_GTK_CFLAGS = @SPICE_GTK_CFLAGS@
+SPICE_GTK_LOCALEDIR = @SPICE_GTK_LOCALEDIR@
+SPICE_GTK_MAJOR_VERSION = @SPICE_GTK_MAJOR_VERSION@
+SPICE_GTK_MICRO_VERSION = @SPICE_GTK_MICRO_VERSION@
+SPICE_GTK_MINOR_VERSION = @SPICE_GTK_MINOR_VERSION@
+SPICE_GTK_REQUIRES = @SPICE_GTK_REQUIRES@
+SPICE_PROTOCOL_CFLAGS = @SPICE_PROTOCOL_CFLAGS@
+SPICE_PROTOCOL_LIBS = @SPICE_PROTOCOL_LIBS@
+SSL_CFLAGS = @SSL_CFLAGS@
+SSL_LIBS = @SSL_LIBS@
+STOW = @STOW@
+STRIP = @STRIP@
+USBREDIR_CFLAGS = @USBREDIR_CFLAGS@
+USBREDIR_LIBS = @USBREDIR_LIBS@
+USB_IDS = @USB_IDS@
+USE_NLS = @USE_NLS@
+VALAC = @VALAC@
+VAPIDIR = @VAPIDIR@
+VAPIGEN = @VAPIGEN@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_LDFLAGS = @WARN_LDFLAGS@
+WARN_PYFLAGS = @WARN_PYFLAGS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+XGETTEXT = @XGETTEXT@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+AM_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\"GSpiceController\" \
+ $(GIO_CFLAGS) \
+ $(COMMON_CFLAGS) \
+ -Wno-deprecated-declarations \
+ $(NULL)
+
+
+# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+AM_LDFLAGS = \
+ -no-undefined \
+ $(GIO_LIBS) \
+ $(NULL)
+
+AM_VALAFLAGS = \
+ --pkg gio-2.0 \
+ --pkg spice-protocol --vapidir=$(top_srcdir)/data \
+ --pkg custom --vapidir=$(srcdir) \
+ -C \
+ $(NULL)
+
+lib_LTLIBRARIES = libspice-controller.la
+libspice_controller_la_VALASOURCES = \
+ menu.vala \
+ controller.vala \
+ foreign-menu.vala \
+ util.vala \
+ $(NULL)
+
+libspice_controller_la_BUILT_SOURCES = \
+ $(libspice_controller_la_VALASOURCES:.vala=.c) \
+ spice-controller.h \
+ $(NULL)
+
+BUILT_SOURCES = \
+ $(libspice_controller_la_BUILT_SOURCES) \
+ controller.vala.stamp \
+ $(NULL)
+
+libspice_controller_la_SOURCES = \
+ $(libspice_controller_la_BUILT_SOURCES) custom.h \
+ spice-controller-listener.c spice-controller-listener.h \
+ spice-foreign-menu-listener.c spice-foreign-menu-listener.h \
+ $(NULL) $(am__append_1)
+libspice_controller_la_LDFLAGS = \
+ $(AM_LDFLAGS) \
+ -version-info 0:0:0 \
+ $(NULL)
+
+libspice_controllerincludedir = $(includedir)/spice-controller
+libspice_controllerinclude_HEADERS = \
+ spice-controller.h
+
+test_controller_SOURCES = test.c
+test_controller_LDADD = libspice-controller.la
+spice_controller_dump_SOURCES = dump.c
+spice_controller_dump_LDADD = libspice-controller.la
+EXTRA_DIST = \
+ $(libspice_controller_la_VALASOURCES) \
+ controller.vala.stamp \
+ custom.vapi \
+ gio-windows-2.0.vapi \
+ $(NULL)
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/controller/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/controller/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libspice-controller.la: $(libspice_controller_la_OBJECTS) $(libspice_controller_la_DEPENDENCIES) $(EXTRA_libspice_controller_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libspice_controller_la_LINK) -rpath $(libdir) $(libspice_controller_la_OBJECTS) $(libspice_controller_la_LIBADD) $(LIBS)
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+spice-controller-dump$(EXEEXT): $(spice_controller_dump_OBJECTS) $(spice_controller_dump_DEPENDENCIES) $(EXTRA_spice_controller_dump_DEPENDENCIES)
+ @rm -f spice-controller-dump$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(spice_controller_dump_OBJECTS) $(spice_controller_dump_LDADD) $(LIBS)
+
+test-controller$(EXEEXT): $(test_controller_OBJECTS) $(test_controller_DEPENDENCIES) $(EXTRA_test_controller_DEPENDENCIES)
+ @rm -f test-controller$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_controller_OBJECTS) $(test_controller_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/controller.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foreign-menu.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/menu.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/namedpipe.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/namedpipeconnection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/namedpipelistener.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-controller-listener.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spice-foreign-menu-listener.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/win32-util.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-libspice_controllerincludeHEADERS: $(libspice_controllerinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(libspice_controllerinclude_HEADERS)'; test -n "$(libspice_controllerincludedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libspice_controllerincludedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libspice_controllerincludedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libspice_controllerincludedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libspice_controllerincludedir)" || exit $$?; \
+ done
+
+uninstall-libspice_controllerincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libspice_controllerinclude_HEADERS)'; test -n "$(libspice_controllerincludedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(libspice_controllerincludedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libspice_controllerincludedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-libspice_controllerincludeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-libLTLIBRARIES \
+ uninstall-libspice_controllerincludeHEADERS
+
+.MAKE: all check install install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-libLTLIBRARIES \
+ install-libspice_controllerincludeHEADERS install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+ uninstall-libLTLIBRARIES \
+ uninstall-libspice_controllerincludeHEADERS
+
+.PRECIOUS: Makefile
+
+
+controller.vala.stamp: $(libspice_controller_la_VALASOURCES) custom.vapi
+ @if test -z "$(VALAC)"; then \
+ echo "" ; \
+ echo " *** Error: missing valac!" ; \
+ echo " *** You must run autogen.sh or configure --enable-vala" ; \
+ echo "" ; \
+ exit 1 ; \
+ fi
+ $(VALA_V)$(VALAC) $(VALAFLAGS) $(AM_VALAFLAGS) \
+ $(addprefix $(srcdir)/,$(libspice_controller_la_VALASOURCES)) \
+ -H spice-controller.h
+ @touch $@
+
+$(libspice_controller_la_BUILT_SOURCES): controller.vala.stamp
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+/* controller.c generated by valac 0.32.1, the Vala compiler
+ * generated from controller.vala, do not modify */
+
+/* Copyright (C) 2011 Red Hat, Inc.*/
+/* This library is free software; you can redistribute it and/or*/
+/* modify it under the terms of the GNU Lesser General Public*/
+/* License as published by the Free Software Foundation; either*/
+/* version 2.1 of the License, or (at your option) any later version.*/
+/* This library is distributed in the hope that it will be useful,*/
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU*/
+/* Lesser General Public License for more details.*/
+/* You should have received a copy of the GNU Lesser General Public*/
+/* License along with this library; if not, see <http://www.gnu.org/licenses/>.*/
+
+#include <glib.h>
+#include <glib-object.h>
+#include <stdlib.h>
+#include <string.h>
+#include <spice/controller_prot.h>
+#include <gio/gio.h>
+#include <custom.h>
+#include <spice-controller-listener.h>
+
+
+#define SPICE_CTRL_TYPE_CONTROLLER (spice_ctrl_controller_get_type ())
+#define SPICE_CTRL_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_CTRL_TYPE_CONTROLLER, SpiceCtrlController))
+#define SPICE_CTRL_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_CTRL_TYPE_CONTROLLER, SpiceCtrlControllerClass))
+#define SPICE_CTRL_IS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_CTRL_TYPE_CONTROLLER))
+#define SPICE_CTRL_IS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_CTRL_TYPE_CONTROLLER))
+#define SPICE_CTRL_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_CTRL_TYPE_CONTROLLER, SpiceCtrlControllerClass))
+
+typedef struct _SpiceCtrlController SpiceCtrlController;
+typedef struct _SpiceCtrlControllerClass SpiceCtrlControllerClass;
+typedef struct _SpiceCtrlControllerPrivate SpiceCtrlControllerPrivate;
+
+#define SPICE_CTRL_TYPE_MENU (spice_ctrl_menu_get_type ())
+#define SPICE_CTRL_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_CTRL_TYPE_MENU, SpiceCtrlMenu))
+#define SPICE_CTRL_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_CTRL_TYPE_MENU, SpiceCtrlMenuClass))
+#define SPICE_CTRL_IS_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_CTRL_TYPE_MENU))
+#define SPICE_CTRL_IS_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_CTRL_TYPE_MENU))
+#define SPICE_CTRL_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_CTRL_TYPE_MENU, SpiceCtrlMenuClass))
+
+typedef struct _SpiceCtrlMenu SpiceCtrlMenu;
+typedef struct _SpiceCtrlMenuClass SpiceCtrlMenuClass;
+#define _g_free0(var) (var = (g_free (var), NULL))
+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
+#define __g_list_free__g_object_unref0_0(var) ((var == NULL) ? NULL : (var = (_g_list_free__g_object_unref0_ (var), NULL)))
+#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
+typedef struct _SpiceCtrlControllerSendMsgData SpiceCtrlControllerSendMsgData;
+typedef struct _SpiceCtrlControllerHandleClientData SpiceCtrlControllerHandleClientData;
+typedef struct _SpiceCtrlControllerListenData SpiceCtrlControllerListenData;
+
+typedef enum {
+ SPICE_CTRL_ERROR_VALUE
+} SpiceCtrlError;
+#define SPICE_CTRL_ERROR spice_ctrl_error_quark ()
+struct _SpiceCtrlController {
+ GObject parent_instance;
+ SpiceCtrlControllerPrivate * priv;
+};
+
+struct _SpiceCtrlControllerClass {
+ GObjectClass parent_class;
+};
+
+struct _SpiceCtrlControllerPrivate {
+ gchar* _host;
+ guint32 _port;
+ guint32 _sport;
+ gchar* _password;
+ unsigned int _display_flags;
+ gchar* _tls_ciphers;
+ gchar* _host_subject;
+ gchar* _ca_file;
+ gchar* _title;
+ gchar* _hotkeys;
+ gchar** _secure_channels;
+ gint _secure_channels_length1;
+ gint __secure_channels_size_;
+ gchar** _disable_channels;
+ gint _disable_channels_length1;
+ gint __disable_channels_size_;
+ SpiceCtrlMenu* _menu;
+ gboolean _enable_smartcard;
+ gboolean _send_cad;
+ gchar** _disable_effects;
+ gint _disable_effects_length1;
+ gint __disable_effects_size_;
+ guint32 _color_depth;
+ gboolean _enable_usbredir;
+ gboolean _enable_usb_autoshare;
+ gchar* _usb_filter;
+ gchar* _proxy;
+ GIOStream* excl_connection;
+ gint nclients;
+ GList* clients;
+};
+
+struct _SpiceCtrlControllerSendMsgData {
+ int _state_;
+ GObject* _source_object_;
+ GAsyncResult* _res_;
+ GSimpleAsyncResult* _async_result;
+ SpiceCtrlController* self;
+ guint8* p;
+ gint p_length1;
+ gboolean result;
+ GIOStream* _tmp0_;
+ GIOStream* _tmp1_;
+ GOutputStream* _tmp2_;
+ GOutputStream* _tmp3_;
+ guint8* _tmp4_;
+ gint _tmp4__length1;
+ guint8* _tmp5_;
+ gint _tmp5__length1;
+ GList* _tmp6_;
+ GList* c_collection;
+ GList* c_it;
+ GIOStream* _tmp7_;
+ GIOStream* c;
+ GIOStream* _tmp8_;
+ GOutputStream* _tmp9_;
+ GOutputStream* _tmp10_;
+ guint8* _tmp11_;
+ gint _tmp11__length1;
+ guint8* _tmp12_;
+ gint _tmp12__length1;
+ GError* e;
+ GError* _tmp13_;
+ const gchar* _tmp14_;
+ GError * _inner_error_;
+};
+
+struct _SpiceCtrlControllerHandleClientData {
+ int _state_;
+ GObject* _source_object_;
+ GAsyncResult* _res_;
+ GSimpleAsyncResult* _async_result;
+ SpiceCtrlController* self;
+ GIOStream* c;
+ gboolean excl;
+ guint8* p;
+ guint8* _tmp0_;
+ gint p_length1;
+ gint _p_size_;
+ ControllerInit* init;
+ guint8* _tmp1_;
+ gint _tmp1__length1;
+ GIOStream* _tmp2_;
+ GInputStream* _tmp3_;
+ GInputStream* _tmp4_;
+ guint8* _tmp5_;
+ gint _tmp5__length1;
+ ControllerInit* _tmp6_;
+ ControllerInitHeader _tmp7_;
+ guint32 _tmp8_;
+ gboolean _tmp9_;
+ ControllerInit* _tmp10_;
+ ControllerInitHeader _tmp11_;
+ guint32 _tmp12_;
+ gboolean _tmp13_;
+ ControllerInit* _tmp14_;
+ ControllerInitHeader _tmp15_;
+ guint32 _tmp16_;
+ gboolean _tmp17_;
+ ControllerInit* _tmp18_;
+ guint64 _tmp19_;
+ gboolean _tmp20_;
+ GIOStream* _tmp21_;
+ gboolean _tmp22_;
+ ControllerInit* _tmp23_;
+ guint32 _tmp24_;
+ gboolean _tmp25_;
+ gint _tmp26_;
+ gint _tmp27_;
+ gchar* _tmp28_;
+ gchar* _tmp29_;
+ gchar* _tmp30_;
+ gchar* _tmp31_;
+ GIOStream* _tmp32_;
+ GIOStream* _tmp33_;
+ gboolean _tmp34_;
+ guint8* t;
+ guint8* _tmp35_;
+ gint t_length1;
+ gint _t_size_;
+ GIOStream* _tmp36_;
+ GInputStream* _tmp37_;
+ GInputStream* _tmp38_;
+ guint8* _tmp39_;
+ gint _tmp39__length1;
+ ControllerMsg* msg;
+ guint8* _tmp40_;
+ gint _tmp40__length1;
+ ControllerMsg* _tmp41_;
+ guint32 _tmp42_;
+ gchar* _tmp43_;
+ gchar* _tmp44_;
+ gchar* _tmp45_;
+ gchar* _tmp46_;
+ gchar* _tmp47_;
+ gchar* _tmp48_;
+ ControllerMsg* _tmp49_;
+ guint32 _tmp50_;
+ gchar* _tmp51_;
+ gchar* _tmp52_;
+ gchar* _tmp53_;
+ gchar* _tmp54_;
+ ControllerMsg* _tmp55_;
+ guint32 _tmp56_;
+ gboolean _tmp57_;
+ ControllerMsg* _tmp58_;
+ guint32 _tmp59_;
+ ControllerMsg* _tmp60_;
+ guint32 _tmp61_;
+ gint _tmp62_;
+ guint8* _tmp63_;
+ gint _tmp63__length1;
+ GIOStream* _tmp64_;
+ GInputStream* _tmp65_;
+ GInputStream* _tmp66_;
+ guint8* _tmp67_;
+ gint _tmp67__length1;
+ ControllerMsg* _tmp68_;
+ guint32 _tmp69_;
+ ControllerMsg* _tmp70_;
+ gboolean _tmp71_;
+ GError * _inner_error_;
+};
+
+struct _SpiceCtrlControllerListenData {
+ int _state_;
+ GObject* _source_object_;
+ GAsyncResult* _res_;
+ GSimpleAsyncResult* _async_result;
+ SpiceCtrlController* self;
+ gchar* addr;
+ GObject* listener;
+ const gchar* _tmp0_;
+ GObject* _tmp1_;
+ gboolean _tmp2_;
+ GIOStream* c;
+ GObject* _tmp3_;
+ GIOStream* _tmp4_;
+ GIOStream* _tmp5_;
+ gint _tmp6_;
+ GIOStream* _tmp7_;
+ GIOStream* _tmp8_;
+ GIOStream* _tmp9_;
+ GError* e;
+ GError* _tmp10_;
+ const gchar* _tmp11_;
+ GIOStream* _tmp12_;
+ GIOStream* _tmp13_;
+ gint _tmp14_;
+ GError * _inner_error_;
+};
+
+
+static gpointer spice_ctrl_controller_parent_class = NULL;
+
+GQuark spice_ctrl_error_quark (void);
+GType spice_ctrl_controller_get_type (void) G_GNUC_CONST;
+GType spice_ctrl_menu_get_type (void) G_GNUC_CONST;
+#define SPICE_CTRL_CONTROLLER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SPICE_CTRL_TYPE_CONTROLLER, SpiceCtrlControllerPrivate))
+enum {
+ SPICE_CTRL_CONTROLLER_DUMMY_PROPERTY,
+ SPICE_CTRL_CONTROLLER_HOST,
+ SPICE_CTRL_CONTROLLER_PORT,
+ SPICE_CTRL_CONTROLLER_SPORT,
+ SPICE_CTRL_CONTROLLER_PASSWORD,
+ SPICE_CTRL_CONTROLLER_DISPLAY_FLAGS,
+ SPICE_CTRL_CONTROLLER_TLS_CIPHERS,
+ SPICE_CTRL_CONTROLLER_HOST_SUBJECT,
+ SPICE_CTRL_CONTROLLER_CA_FILE,
+ SPICE_CTRL_CONTROLLER_TITLE,
+ SPICE_CTRL_CONTROLLER_HOTKEYS,
+ SPICE_CTRL_CONTROLLER_SECURE_CHANNELS,
+ SPICE_CTRL_CONTROLLER_DISABLE_CHANNELS,
+ SPICE_CTRL_CONTROLLER_MENU,
+ SPICE_CTRL_CONTROLLER_ENABLE_SMARTCARD,
+ SPICE_CTRL_CONTROLLER_SEND_CAD,
+ SPICE_CTRL_CONTROLLER_DISABLE_EFFECTS,
+ SPICE_CTRL_CONTROLLER_COLOR_DEPTH,
+ SPICE_CTRL_CONTROLLER_ENABLE_USBREDIR,
+ SPICE_CTRL_CONTROLLER_ENABLE_USB_AUTOSHARE,
+ SPICE_CTRL_CONTROLLER_USB_FILTER,
+ SPICE_CTRL_CONTROLLER_PROXY
+};
+static void _g_object_unref0_ (gpointer var);
+static void _g_list_free__g_object_unref0_ (GList* self);
+void spice_ctrl_controller_menu_item_click_msg (SpiceCtrlController* self, gint32 item_id);
+void spice_ctrl_controller_send_msg (SpiceCtrlController* self, guint8* p, int p_length1, GAsyncReadyCallback _callback_, gpointer _user_data_);
+gboolean spice_ctrl_controller_send_msg_finish (SpiceCtrlController* self, GAsyncResult* _res_, GError** error);
+static void spice_ctrl_controller_send_msg_data_free (gpointer _data);
+static gboolean spice_ctrl_controller_send_msg_co (SpiceCtrlControllerSendMsgData* _data_);
+void spice_ctrl_output_stream_write (GOutputStream* stream, guint8* buffer, int buffer_length1, GAsyncReadyCallback _callback_, gpointer _user_data_);
+void spice_ctrl_output_stream_write_finish (GAsyncResult* _res_, GError** error);
+static guint8* _vala_array_dup1 (guint8* self, int length);
+static void spice_ctrl_controller_send_msg_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
+static guint8* _vala_array_dup2 (guint8* self, int length);
+static gboolean spice_ctrl_controller_handle_message (SpiceCtrlController* self, ControllerMsg* msg);
+static void spice_ctrl_controller_set_host (SpiceCtrlController* self, const gchar* value);
+static void spice_ctrl_controller_set_port (SpiceCtrlController* self, guint32 value);
+guint32 spice_ctrl_controller_get_port (SpiceCtrlController* self);
+static void spice_ctrl_controller_set_sport (SpiceCtrlController* self, guint32 value);
+guint32 spice_ctrl_controller_get_sport (SpiceCtrlController* self);
+static void spice_ctrl_controller_set_password (SpiceCtrlController* self, const gchar* value);
+static void spice_ctrl_controller_set_secure_channels (SpiceCtrlController* self, gchar** value, int value_length1);
+static void spice_ctrl_controller_set_disable_channels (SpiceCtrlController* self, gchar** value, int value_length1);
+static void spice_ctrl_controller_set_tls_ciphers (SpiceCtrlController* self, const gchar* value);
+static void spice_ctrl_controller_set_ca_file (SpiceCtrlController* self, const gchar* value);
+static void spice_ctrl_controller_set_host_subject (SpiceCtrlController* self, const gchar* value);
+static void spice_ctrl_controller_set_display_flags (SpiceCtrlController* self, unsigned int value);
+static void spice_ctrl_controller_set_title (SpiceCtrlController* self, const gchar* value);
+static void spice_ctrl_controller_set_enable_smartcard (SpiceCtrlController* self, gboolean value);
+SpiceCtrlMenu* spice_ctrl_menu_new_from_string (const gchar* str);
+SpiceCtrlMenu* spice_ctrl_menu_construct_from_string (GType object_type, const gchar* str);
+static void spice_ctrl_controller_set_menu (SpiceCtrlController* self, SpiceCtrlMenu* value);
+static void spice_ctrl_controller_set_send_cad (SpiceCtrlController* self, gboolean value);
+static void spice_ctrl_controller_set_hotkeys (SpiceCtrlController* self, const gchar* value);
+static void spice_ctrl_controller_set_color_depth (SpiceCtrlController* self, guint32 value);
+static void spice_ctrl_controller_set_disable_effects (SpiceCtrlController* self, gchar** value, int value_length1);
+static void spice_ctrl_controller_set_enable_usbredir (SpiceCtrlController* self, gboolean value);
+static void spice_ctrl_controller_set_enable_usb_autoshare (SpiceCtrlController* self, gboolean value);
+static void spice_ctrl_controller_set_usb_filter (SpiceCtrlController* self, const gchar* value);
+static void spice_ctrl_controller_set_proxy (SpiceCtrlController* self, const gchar* value);
+static void spice_ctrl_controller_handle_client_data_free (gpointer _data);
+static void spice_ctrl_controller_handle_client (SpiceCtrlController* self, GIOStream* c, GAsyncReadyCallback _callback_, gpointer _user_data_);
+static void spice_ctrl_controller_handle_client_finish (SpiceCtrlController* self, GAsyncResult* _res_, GError** error);
+static gboolean spice_ctrl_controller_handle_client_co (SpiceCtrlControllerHandleClientData* _data_);
+void spice_ctrl_input_stream_read (GInputStream* stream, guint8* buffer, int buffer_length1, GAsyncReadyCallback _callback_, gpointer _user_data_);
+void spice_ctrl_input_stream_read_finish (GAsyncResult* _res_, GError** error);
+static void spice_ctrl_controller_handle_client_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
+SpiceCtrlController* spice_ctrl_controller_new (void);
+SpiceCtrlController* spice_ctrl_controller_construct (GType object_type);
+static void spice_ctrl_controller_listen_data_free (gpointer _data);
+void spice_ctrl_controller_listen (SpiceCtrlController* self, const gchar* addr, GAsyncReadyCallback _callback_, gpointer _user_data_);
+void spice_ctrl_controller_listen_finish (SpiceCtrlController* self, GAsyncResult* _res_, GError** error);
+static gboolean spice_ctrl_controller_listen_co (SpiceCtrlControllerListenData* _data_);
+static void spice_ctrl_controller_listen_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
+const gchar* spice_ctrl_controller_get_host (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_password (SpiceCtrlController* self);
+unsigned int spice_ctrl_controller_get_display_flags (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_tls_ciphers (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_host_subject (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_ca_file (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_title (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_hotkeys (SpiceCtrlController* self);
+gchar** spice_ctrl_controller_get_secure_channels (SpiceCtrlController* self, int* result_length1);
+static gchar** _vala_array_dup3 (gchar** self, int length);
+gchar** spice_ctrl_controller_get_disable_channels (SpiceCtrlController* self, int* result_length1);
+static gchar** _vala_array_dup4 (gchar** self, int length);
+SpiceCtrlMenu* spice_ctrl_controller_get_menu (SpiceCtrlController* self);
+gboolean spice_ctrl_controller_get_enable_smartcard (SpiceCtrlController* self);
+gboolean spice_ctrl_controller_get_send_cad (SpiceCtrlController* self);
+gchar** spice_ctrl_controller_get_disable_effects (SpiceCtrlController* self, int* result_length1);
+static gchar** _vala_array_dup5 (gchar** self, int length);
+guint32 spice_ctrl_controller_get_color_depth (SpiceCtrlController* self);
+gboolean spice_ctrl_controller_get_enable_usbredir (SpiceCtrlController* self);
+gboolean spice_ctrl_controller_get_enable_usb_autoshare (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_usb_filter (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_proxy (SpiceCtrlController* self);
+static void spice_ctrl_controller_finalize (GObject* obj);
+static void _vala_spice_ctrl_controller_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
+static void _vala_spice_ctrl_controller_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);
+static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
+static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func);
+static gint _vala_array_length (gpointer array);
+
+
+GQuark spice_ctrl_error_quark (void) {
+ return g_quark_from_static_string ("spice_ctrl_error-quark");
+}
+
+
+static void _g_object_unref0_ (gpointer var) {
+ (var == NULL) ? NULL : (var = (g_object_unref (var), NULL));
+}
+
+
+static void _g_list_free__g_object_unref0_ (GList* self) {
+ g_list_foreach (self, (GFunc) _g_object_unref0_, NULL);
+ g_list_free (self);
+}
+
+
+void spice_ctrl_controller_menu_item_click_msg (SpiceCtrlController* self, gint32 item_id) {
+ ControllerValue msg = {0};
+ gint32 _tmp0_ = 0;
+ guint8* p = NULL;
+ ControllerValue _tmp1_ = {0};
+ ControllerMsg _tmp2_ = {0};
+ guint32 _tmp3_ = 0U;
+ gint p_length1 = 0;
+ gint _p_size_ = 0;
+ g_return_if_fail (self != NULL);
+ memset (&msg, 0, sizeof (ControllerValue));
+ msg.base.size = (guint32) sizeof (ControllerValue);
+ msg.base.id = (guint32) CONTROLLER_MENU_ITEM_CLICK;
+ _tmp0_ = item_id;
+ msg.value = (guint32) _tmp0_;
+ _tmp1_ = msg;
+ _tmp2_ = _tmp1_.base;
+ _tmp3_ = _tmp2_.size;
+ p = ((guint8*) (&msg)) + 0;
+ p_length1 = ((gint) _tmp3_) - 0;
+ _p_size_ = p_length1;
+ spice_ctrl_controller_send_msg (self, p, p_length1, NULL, NULL);
+}
+
+
+static void spice_ctrl_controller_send_msg_data_free (gpointer _data) {
+ SpiceCtrlControllerSendMsgData* _data_;
+ _data_ = _data;
+ _g_object_unref0 (_data_->self);
+ g_slice_free (SpiceCtrlControllerSendMsgData, _data_);
+}
+
+
+static gpointer _g_object_ref0 (gpointer self) {
+ return self ? g_object_ref (self) : NULL;
+}
+
+
+void spice_ctrl_controller_send_msg (SpiceCtrlController* self, guint8* p, int p_length1, GAsyncReadyCallback _callback_, gpointer _user_data_) {
+ SpiceCtrlControllerSendMsgData* _data_;
+ SpiceCtrlController* _tmp0_ = NULL;
+ guint8* _tmp1_ = NULL;
+ gint _tmp1__length1 = 0;
+ _data_ = g_slice_new0 (SpiceCtrlControllerSendMsgData);
+ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, spice_ctrl_controller_send_msg);
+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, spice_ctrl_controller_send_msg_data_free);
+ _tmp0_ = _g_object_ref0 (self);
+ _data_->self = _tmp0_;
+ _tmp1_ = p;
+ _tmp1__length1 = p_length1;
+ _data_->p = _tmp1_;
+ _data_->p_length1 = _tmp1__length1;
+ spice_ctrl_controller_send_msg_co (_data_);
+}
+
+
+gboolean spice_ctrl_controller_send_msg_finish (SpiceCtrlController* self, GAsyncResult* _res_, GError** error) {
+ gboolean result;
+ SpiceCtrlControllerSendMsgData* _data_;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
+ return FALSE;
+ }
+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
+ result = _data_->result;
+ return result;
+}
+
+
+static guint8* _vala_array_dup1 (guint8* self, int length) {
+ return g_memdup (self, length * sizeof (guint8));
+}
+
+
+static void spice_ctrl_controller_send_msg_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
+ SpiceCtrlControllerSendMsgData* _data_;
+ _data_ = _user_data_;
+ _data_->_source_object_ = source_object;
+ _data_->_res_ = _res_;
+ spice_ctrl_controller_send_msg_co (_data_);
+}
+
+
+static guint8* _vala_array_dup2 (guint8* self, int length) {
+ return g_memdup (self, length * sizeof (guint8));
+}
+
+
+static gboolean spice_ctrl_controller_send_msg_co (SpiceCtrlControllerSendMsgData* _data_) {
+ switch (_data_->_state_) {
+ case 0:
+ goto _state_0;
+ case 1:
+ goto _state_1;
+ case 2:
+ goto _state_2;
+ default:
+ g_assert_not_reached ();
+ }
+ _state_0:
+ {
+ _data_->_tmp0_ = NULL;
+ _data_->_tmp0_ = _data_->self->priv->excl_connection;
+ if (_data_->_tmp0_ != NULL) {
+ _data_->_tmp1_ = NULL;
+ _data_->_tmp1_ = _data_->self->priv->excl_connection;
+ _data_->_tmp2_ = NULL;
+ _data_->_tmp2_ = g_io_stream_get_output_stream (_data_->_tmp1_);
+ _data_->_tmp3_ = NULL;
+ _data_->_tmp3_ = _data_->_tmp2_;
+ _data_->_tmp4_ = NULL;
+ _data_->_tmp4__length1 = 0;
+ _data_->_tmp4_ = _data_->p;
+ _data_->_tmp4__length1 = _data_->p_length1;
+ _data_->_tmp5_ = NULL;
+ _data_->_tmp5__length1 = 0;
+ _data_->_tmp5_ = (_data_->_tmp4_ != NULL) ? _vala_array_dup1 (_data_->_tmp4_, _data_->_tmp4__length1) : ((gpointer) _data_->_tmp4_);
+ _data_->_tmp5__length1 = _data_->_tmp4__length1;
+ _data_->_state_ = 1;
+ spice_ctrl_output_stream_write (_data_->_tmp3_, _data_->_tmp5_, _data_->_tmp5__length1, spice_ctrl_controller_send_msg_ready, _data_);
+ return FALSE;
+ _state_1:
+ spice_ctrl_output_stream_write_finish (_data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ goto __catch1_g_error;
+ }
+ } else {
+ _data_->_tmp6_ = NULL;
+ _data_->_tmp6_ = _data_->self->priv->clients;
+ {
+ _data_->c_collection = _data_->_tmp6_;
+ for (_data_->c_it = _data_->c_collection; _data_->c_it != NULL; _data_->c_it = _data_->c_it->next) {
+ _data_->_tmp7_ = NULL;
+ _data_->_tmp7_ = _g_object_ref0 ((GIOStream*) _data_->c_it->data);
+ _data_->c = _data_->_tmp7_;
+ {
+ _data_->_tmp8_ = NULL;
+ _data_->_tmp8_ = _data_->c;
+ _data_->_tmp9_ = NULL;
+ _data_->_tmp9_ = g_io_stream_get_output_stream (_data_->_tmp8_);
+ _data_->_tmp10_ = NULL;
+ _data_->_tmp10_ = _data_->_tmp9_;
+ _data_->_tmp11_ = NULL;
+ _data_->_tmp11__length1 = 0;
+ _data_->_tmp11_ = _data_->p;
+ _data_->_tmp11__length1 = _data_->p_length1;
+ _data_->_tmp12_ = NULL;
+ _data_->_tmp12__length1 = 0;
+ _data_->_tmp12_ = (_data_->_tmp11_ != NULL) ? _vala_array_dup2 (_data_->_tmp11_, _data_->_tmp11__length1) : ((gpointer) _data_->_tmp11_);
+ _data_->_tmp12__length1 = _data_->_tmp11__length1;
+ _data_->_state_ = 2;
+ spice_ctrl_output_stream_write (_data_->_tmp10_, _data_->_tmp12_, _data_->_tmp12__length1, spice_ctrl_controller_send_msg_ready, _data_);
+ return FALSE;
+ _state_2:
+ spice_ctrl_output_stream_write_finish (_data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ _g_object_unref0 (_data_->c);
+ goto __catch1_g_error;
+ }
+ _g_object_unref0 (_data_->c);
+ }
+ }
+ }
+ }
+ }
+ goto __finally1;
+ __catch1_g_error:
+ {
+ _data_->e = _data_->_inner_error_;
+ _data_->_inner_error_ = NULL;
+ _data_->_tmp13_ = NULL;
+ _data_->_tmp13_ = _data_->e;
+ _data_->_tmp14_ = NULL;
+ _data_->_tmp14_ = _data_->_tmp13_->message;
+ g_warning ("controller.vala:79: %s", _data_->_tmp14_);
+ _g_error_free0 (_data_->e);
+ }
+ __finally1:
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->result = TRUE;
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+}
+
+
+static gboolean spice_ctrl_controller_handle_message (SpiceCtrlController* self, ControllerMsg* msg) {
+ gboolean result = FALSE;
+ ControllerValue* v = NULL;
+ ControllerMsg* _tmp0_ = NULL;
+ ControllerData* d = NULL;
+ ControllerMsg* _tmp1_ = NULL;
+ const gchar* str = NULL;
+ ControllerMsg* _tmp2_ = NULL;
+ guint32 _tmp3_ = 0U;
+ g_return_val_if_fail (self != NULL, FALSE);
+ _tmp0_ = msg;
+ v = (ControllerValue*) _tmp0_;
+ _tmp1_ = msg;
+ d = (ControllerData*) _tmp1_;
+ str = (const gchar*) (&(*d).data);
+ _tmp2_ = msg;
+ _tmp3_ = (*_tmp2_).id;
+ switch (_tmp3_) {
+ case CONTROLLER_HOST:
+ {
+ const gchar* _tmp4_ = NULL;
+ const gchar* _tmp5_ = NULL;
+ gchar* _tmp6_ = NULL;
+ gchar* _tmp7_ = NULL;
+ _tmp4_ = str;
+ spice_ctrl_controller_set_host (self, _tmp4_);
+ _tmp5_ = str;
+ _tmp6_ = g_strdup_printf ("got HOST: %s", _tmp5_);
+ _tmp7_ = _tmp6_;
+ g_debug ("controller.vala:97: %s", _tmp7_);
+ _g_free0 (_tmp7_);
+ break;
+ }
+ case CONTROLLER_PORT:
+ {
+ ControllerValue* _tmp8_ = NULL;
+ guint32 _tmp9_ = 0U;
+ guint32 _tmp10_ = 0U;
+ gchar* _tmp11_ = NULL;
+ gchar* _tmp12_ = NULL;
+ _tmp8_ = v;
+ _tmp9_ = (*_tmp8_).value;
+ spice_ctrl_controller_set_port (self, _tmp9_);
+ _tmp10_ = self->priv->_port;
+ _tmp11_ = g_strdup_printf ("got PORT: %u", (guint) _tmp10_);
+ _tmp12_ = _tmp11_;
+ g_debug ("controller.vala:101: %s", _tmp12_);
+ _g_free0 (_tmp12_);
+ break;
+ }
+ case CONTROLLER_SPORT:
+ {
+ ControllerValue* _tmp13_ = NULL;
+ guint32 _tmp14_ = 0U;
+ guint32 _tmp15_ = 0U;
+ gchar* _tmp16_ = NULL;
+ gchar* _tmp17_ = NULL;
+ _tmp13_ = v;
+ _tmp14_ = (*_tmp13_).value;
+ spice_ctrl_controller_set_sport (self, _tmp14_);
+ _tmp15_ = self->priv->_sport;
+ _tmp16_ = g_strdup_printf ("got SPORT: %u", (guint) _tmp15_);
+ _tmp17_ = _tmp16_;
+ g_debug ("controller.vala:105: %s", _tmp17_);
+ _g_free0 (_tmp17_);
+ break;
+ }
+ case CONTROLLER_PASSWORD:
+ {
+ const gchar* _tmp18_ = NULL;
+ _tmp18_ = str;
+ spice_ctrl_controller_set_password (self, _tmp18_);
+ g_debug ("controller.vala:109: got PASSWORD");
+ break;
+ }
+ case CONTROLLER_SECURE_CHANNELS:
+ {
+ const gchar* _tmp19_ = NULL;
+ gchar** _tmp20_ = NULL;
+ gchar** _tmp21_ = NULL;
+ gchar** _tmp22_ = NULL;
+ gint _tmp22__length1 = 0;
+ const gchar* _tmp23_ = NULL;
+ gchar* _tmp24_ = NULL;
+ gchar* _tmp25_ = NULL;
+ _tmp19_ = str;
+ _tmp21_ = _tmp20_ = g_strsplit (_tmp19_, ",", 0);
+ _tmp22_ = _tmp21_;
+ _tmp22__length1 = _vala_array_length (_tmp20_);
+ spice_ctrl_controller_set_secure_channels (self, _tmp22_, _vala_array_length (_tmp20_));
+ _tmp22_ = (_vala_array_free (_tmp22_, _tmp22__length1, (GDestroyNotify) g_free), NULL);
+ _tmp23_ = str;
+ _tmp24_ = g_strdup_printf ("got SECURE_CHANNELS %s", _tmp23_);
+ _tmp25_ = _tmp24_;
+ g_debug ("controller.vala:114: %s", _tmp25_);
+ _g_free0 (_tmp25_);
+ break;
+ }
+ case CONTROLLER_DISABLE_CHANNELS:
+ {
+ const gchar* _tmp26_ = NULL;
+ gchar** _tmp27_ = NULL;
+ gchar** _tmp28_ = NULL;
+ gchar** _tmp29_ = NULL;
+ gint _tmp29__length1 = 0;
+ const gchar* _tmp30_ = NULL;
+ gchar* _tmp31_ = NULL;
+ gchar* _tmp32_ = NULL;
+ _tmp26_ = str;
+ _tmp28_ = _tmp27_ = g_strsplit (_tmp26_, ",", 0);
+ _tmp29_ = _tmp28_;
+ _tmp29__length1 = _vala_array_length (_tmp27_);
+ spice_ctrl_controller_set_disable_channels (self, _tmp29_, _vala_array_length (_tmp27_));
+ _tmp29_ = (_vala_array_free (_tmp29_, _tmp29__length1, (GDestroyNotify) g_free), NULL);
+ _tmp30_ = str;
+ _tmp31_ = g_strdup_printf ("got DISABLE_CHANNELS %s", _tmp30_);
+ _tmp32_ = _tmp31_;
+ g_debug ("controller.vala:119: %s", _tmp32_);
+ _g_free0 (_tmp32_);
+ break;
+ }
+ case CONTROLLER_TLS_CIPHERS:
+ {
+ const gchar* _tmp33_ = NULL;
+ const gchar* _tmp34_ = NULL;
+ gchar* _tmp35_ = NULL;
+ gchar* _tmp36_ = NULL;
+ _tmp33_ = str;
+ spice_ctrl_controller_set_tls_ciphers (self, _tmp33_);
+ _tmp34_ = str;
+ _tmp35_ = g_strdup_printf ("got TLS_CIPHERS %s", _tmp34_);
+ _tmp36_ = _tmp35_;
+ g_debug ("controller.vala:124: %s", _tmp36_);
+ _g_free0 (_tmp36_);
+ break;
+ }
+ case CONTROLLER_CA_FILE:
+ {
+ const gchar* _tmp37_ = NULL;
+ const gchar* _tmp38_ = NULL;
+ gchar* _tmp39_ = NULL;
+ gchar* _tmp40_ = NULL;
+ _tmp37_ = str;
+ spice_ctrl_controller_set_ca_file (self, _tmp37_);
+ _tmp38_ = str;
+ _tmp39_ = g_strdup_printf ("got CA_FILE %s", _tmp38_);
+ _tmp40_ = _tmp39_;
+ g_debug ("controller.vala:128: %s", _tmp40_);
+ _g_free0 (_tmp40_);
+ break;
+ }
+ case CONTROLLER_HOST_SUBJECT:
+ {
+ const gchar* _tmp41_ = NULL;
+ const gchar* _tmp42_ = NULL;
+ gchar* _tmp43_ = NULL;
+ gchar* _tmp44_ = NULL;
+ _tmp41_ = str;
+ spice_ctrl_controller_set_host_subject (self, _tmp41_);
+ _tmp42_ = str;
+ _tmp43_ = g_strdup_printf ("got HOST_SUBJECT %s", _tmp42_);
+ _tmp44_ = _tmp43_;
+ g_debug ("controller.vala:132: %s", _tmp44_);
+ _g_free0 (_tmp44_);
+ break;
+ }
+ case CONTROLLER_FULL_SCREEN:
+ {
+ ControllerValue* _tmp45_ = NULL;
+ guint32 _tmp46_ = 0U;
+ ControllerValue* _tmp47_ = NULL;
+ guint32 _tmp48_ = 0U;
+ gchar* _tmp49_ = NULL;
+ gchar* _tmp50_ = NULL;
+ _tmp45_ = v;
+ _tmp46_ = (*_tmp45_).value;
+ spice_ctrl_controller_set_display_flags (self, (unsigned int) _tmp46_);
+ _tmp47_ = v;
+ _tmp48_ = (*_tmp47_).value;
+ _tmp49_ = g_strdup_printf ("got FULL_SCREEN 0x%x", (guint) _tmp48_);
+ _tmp50_ = _tmp49_;
+ g_debug ("controller.vala:137: %s", _tmp50_);
+ _g_free0 (_tmp50_);
+ break;
+ }
+ case CONTROLLER_SET_TITLE:
+ {
+ const gchar* _tmp51_ = NULL;
+ const gchar* _tmp52_ = NULL;
+ gchar* _tmp53_ = NULL;
+ gchar* _tmp54_ = NULL;
+ _tmp51_ = str;
+ spice_ctrl_controller_set_title (self, _tmp51_);
+ _tmp52_ = str;
+ _tmp53_ = g_strdup_printf ("got TITLE %s", _tmp52_);
+ _tmp54_ = _tmp53_;
+ g_debug ("controller.vala:141: %s", _tmp54_);
+ _g_free0 (_tmp54_);
+ break;
+ }
+ case CONTROLLER_ENABLE_SMARTCARD:
+ {
+ ControllerValue* _tmp55_ = NULL;
+ guint32 _tmp56_ = 0U;
+ ControllerValue* _tmp57_ = NULL;
+ guint32 _tmp58_ = 0U;
+ gchar* _tmp59_ = NULL;
+ gchar* _tmp60_ = NULL;
+ _tmp55_ = v;
+ _tmp56_ = (*_tmp55_).value;
+ spice_ctrl_controller_set_enable_smartcard (self, (gboolean) _tmp56_);
+ _tmp57_ = v;
+ _tmp58_ = (*_tmp57_).value;
+ _tmp59_ = g_strdup_printf ("got ENABLE_SMARTCARD 0x%x", (guint) _tmp58_);
+ _tmp60_ = _tmp59_;
+ g_debug ("controller.vala:145: %s", _tmp60_);
+ _g_free0 (_tmp60_);
+ break;
+ }
+ case CONTROLLER_CREATE_MENU:
+ {
+ const gchar* _tmp61_ = NULL;
+ SpiceCtrlMenu* _tmp62_ = NULL;
+ SpiceCtrlMenu* _tmp63_ = NULL;
+ const gchar* _tmp64_ = NULL;
+ gchar* _tmp65_ = NULL;
+ gchar* _tmp66_ = NULL;
+ _tmp61_ = str;
+ _tmp62_ = spice_ctrl_menu_new_from_string (_tmp61_);
+ _tmp63_ = _tmp62_;
+ spice_ctrl_controller_set_menu (self, _tmp63_);
+ _g_object_unref0 (_tmp63_);
+ _tmp64_ = str;
+ _tmp65_ = g_strdup_printf ("got CREATE_MENU %s", _tmp64_);
+ _tmp66_ = _tmp65_;
+ g_debug ("controller.vala:150: %s", _tmp66_);
+ _g_free0 (_tmp66_);
+ break;
+ }
+ case CONTROLLER_DELETE_MENU:
+ {
+ spice_ctrl_controller_set_menu (self, NULL);
+ g_debug ("controller.vala:154: got DELETE_MENU request");
+ break;
+ }
+ case CONTROLLER_SEND_CAD:
+ {
+ ControllerValue* _tmp67_ = NULL;
+ guint32 _tmp68_ = 0U;
+ ControllerValue* _tmp69_ = NULL;
+ guint32 _tmp70_ = 0U;
+ gchar* _tmp71_ = NULL;
+ gchar* _tmp72_ = NULL;
+ _tmp67_ = v;
+ _tmp68_ = (*_tmp67_).value;
+ spice_ctrl_controller_set_send_cad (self, (gboolean) _tmp68_);
+ _tmp69_ = v;
+ _tmp70_ = (*_tmp69_).value;
+ _tmp71_ = g_strdup_printf ("got SEND_CAD %u", (guint) _tmp70_);
+ _tmp72_ = _tmp71_;
+ g_debug ("controller.vala:159: %s", _tmp72_);
+ _g_free0 (_tmp72_);
+ break;
+ }
+ case CONTROLLER_HOTKEYS:
+ {
+ const gchar* _tmp73_ = NULL;
+ const gchar* _tmp74_ = NULL;
+ gchar* _tmp75_ = NULL;
+ gchar* _tmp76_ = NULL;
+ _tmp73_ = str;
+ spice_ctrl_controller_set_hotkeys (self, _tmp73_);
+ _tmp74_ = str;
+ _tmp75_ = g_strdup_printf ("got HOTKEYS %s", _tmp74_);
+ _tmp76_ = _tmp75_;
+ g_debug ("controller.vala:164: %s", _tmp76_);
+ _g_free0 (_tmp76_);
+ break;
+ }
+ case CONTROLLER_COLOR_DEPTH:
+ {
+ ControllerValue* _tmp77_ = NULL;
+ guint32 _tmp78_ = 0U;
+ ControllerValue* _tmp79_ = NULL;
+ guint32 _tmp80_ = 0U;
+ gchar* _tmp81_ = NULL;
+ gchar* _tmp82_ = NULL;
+ _tmp77_ = v;
+ _tmp78_ = (*_tmp77_).value;
+ spice_ctrl_controller_set_color_depth (self, _tmp78_);
+ _tmp79_ = v;
+ _tmp80_ = (*_tmp79_).value;
+ _tmp81_ = g_strdup_printf ("got COLOR_DEPTH %u", (guint) _tmp80_);
+ _tmp82_ = _tmp81_;
+ g_debug ("controller.vala:169: %s", _tmp82_);
+ _g_free0 (_tmp82_);
+ break;
+ }
+ case CONTROLLER_DISABLE_EFFECTS:
+ {
+ const gchar* _tmp83_ = NULL;
+ gchar** _tmp84_ = NULL;
+ gchar** _tmp85_ = NULL;
+ gchar** _tmp86_ = NULL;
+ gint _tmp86__length1 = 0;
+ const gchar* _tmp87_ = NULL;
+ gchar* _tmp88_ = NULL;
+ gchar* _tmp89_ = NULL;
+ _tmp83_ = str;
+ _tmp85_ = _tmp84_ = g_strsplit (_tmp83_, ",", 0);
+ _tmp86_ = _tmp85_;
+ _tmp86__length1 = _vala_array_length (_tmp84_);
+ spice_ctrl_controller_set_disable_effects (self, _tmp86_, _vala_array_length (_tmp84_));
+ _tmp86_ = (_vala_array_free (_tmp86_, _tmp86__length1, (GDestroyNotify) g_free), NULL);
+ _tmp87_ = str;
+ _tmp88_ = g_strdup_printf ("got DISABLE_EFFECTS %s", _tmp87_);
+ _tmp89_ = _tmp88_;
+ g_debug ("controller.vala:173: %s", _tmp89_);
+ _g_free0 (_tmp89_);
+ break;
+ }
+ case CONTROLLER_CONNECT:
+ {
+ g_signal_emit_by_name (self, "do-connect");
+ g_debug ("controller.vala:178: got CONNECT request");
+ break;
+ }
+ case CONTROLLER_SHOW:
+ {
+ g_signal_emit_by_name (self, "show");
+ g_debug ("controller.vala:182: got SHOW request");
+ break;
+ }
+ case CONTROLLER_HIDE:
+ {
+ g_signal_emit_by_name (self, "hide");
+ g_debug ("controller.vala:186: got HIDE request");
+ break;
+ }
+ case CONTROLLER_ENABLE_USB:
+ {
+ ControllerValue* _tmp90_ = NULL;
+ guint32 _tmp91_ = 0U;
+ ControllerValue* _tmp92_ = NULL;
+ guint32 _tmp93_ = 0U;
+ gchar* _tmp94_ = NULL;
+ gchar* _tmp95_ = NULL;
+ _tmp90_ = v;
+ _tmp91_ = (*_tmp90_).value;
+ spice_ctrl_controller_set_enable_usbredir (self, (gboolean) _tmp91_);
+ _tmp92_ = v;
+ _tmp93_ = (*_tmp92_).value;
+ _tmp94_ = g_strdup_printf ("got ENABLE_USB %u", (guint) _tmp93_);
+ _tmp95_ = _tmp94_;
+ g_debug ("controller.vala:190: %s", _tmp95_);
+ _g_free0 (_tmp95_);
+ break;
+ }
+ case CONTROLLER_ENABLE_USB_AUTOSHARE:
+ {
+ ControllerValue* _tmp96_ = NULL;
+ guint32 _tmp97_ = 0U;
+ ControllerValue* _tmp98_ = NULL;
+ guint32 _tmp99_ = 0U;
+ gchar* _tmp100_ = NULL;
+ gchar* _tmp101_ = NULL;
+ _tmp96_ = v;
+ _tmp97_ = (*_tmp96_).value;
+ spice_ctrl_controller_set_enable_usb_autoshare (self, (gboolean) _tmp97_);
+ _tmp98_ = v;
+ _tmp99_ = (*_tmp98_).value;
+ _tmp100_ = g_strdup_printf ("got ENABLE_USB_AUTOSHARE %u", (guint) _tmp99_);
+ _tmp101_ = _tmp100_;
+ g_debug ("controller.vala:194: %s", _tmp101_);
+ _g_free0 (_tmp101_);
+ break;
+ }
+ case CONTROLLER_USB_FILTER:
+ {
+ const gchar* _tmp102_ = NULL;
+ const gchar* _tmp103_ = NULL;
+ gchar* _tmp104_ = NULL;
+ gchar* _tmp105_ = NULL;
+ _tmp102_ = str;
+ spice_ctrl_controller_set_usb_filter (self, _tmp102_);
+ _tmp103_ = str;
+ _tmp104_ = g_strdup_printf ("got USB_FILTER %s", _tmp103_);
+ _tmp105_ = _tmp104_;
+ g_debug ("controller.vala:198: %s", _tmp105_);
+ _g_free0 (_tmp105_);
+ break;
+ }
+ case CONTROLLER_PROXY:
+ {
+ const gchar* _tmp106_ = NULL;
+ const gchar* _tmp107_ = NULL;
+ gchar* _tmp108_ = NULL;
+ gchar* _tmp109_ = NULL;
+ _tmp106_ = str;
+ spice_ctrl_controller_set_proxy (self, _tmp106_);
+ _tmp107_ = str;
+ _tmp108_ = g_strdup_printf ("got PROXY %s", _tmp107_);
+ _tmp109_ = _tmp108_;
+ g_debug ("controller.vala:202: %s", _tmp109_);
+ _g_free0 (_tmp109_);
+ break;
+ }
+ default:
+ {
+ ControllerMsg* _tmp110_ = NULL;
+ guint32 _tmp111_ = 0U;
+ gchar* _tmp112_ = NULL;
+ gchar* _tmp113_ = NULL;
+ _tmp110_ = msg;
+ _tmp111_ = (*_tmp110_).id;
+ _tmp112_ = g_strdup_printf ("got unknown msg.id %u", (guint) _tmp111_);
+ _tmp113_ = _tmp112_;
+ g_debug ("controller.vala:205: %s", _tmp113_);
+ _g_free0 (_tmp113_);
+ g_warn_if_reached ();
+ result = FALSE;
+ return result;
+ }
+ }
+ result = TRUE;
+ return result;
+}
+
+
+static void spice_ctrl_controller_handle_client_data_free (gpointer _data) {
+ SpiceCtrlControllerHandleClientData* _data_;
+ _data_ = _data;
+ _g_object_unref0 (_data_->c);
+ _g_object_unref0 (_data_->self);
+ g_slice_free (SpiceCtrlControllerHandleClientData, _data_);
+}
+
+
+static void spice_ctrl_controller_handle_client (SpiceCtrlController* self, GIOStream* c, GAsyncReadyCallback _callback_, gpointer _user_data_) {
+ SpiceCtrlControllerHandleClientData* _data_;
+ SpiceCtrlController* _tmp0_ = NULL;
+ GIOStream* _tmp1_ = NULL;
+ GIOStream* _tmp2_ = NULL;
+ _data_ = g_slice_new0 (SpiceCtrlControllerHandleClientData);
+ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, spice_ctrl_controller_handle_client);
+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, spice_ctrl_controller_handle_client_data_free);
+ _tmp0_ = _g_object_ref0 (self);
+ _data_->self = _tmp0_;
+ _tmp1_ = c;
+ _tmp2_ = _g_object_ref0 (_tmp1_);
+ _g_object_unref0 (_data_->c);
+ _data_->c = _tmp2_;
+ spice_ctrl_controller_handle_client_co (_data_);
+}
+
+
+static void spice_ctrl_controller_handle_client_finish (SpiceCtrlController* self, GAsyncResult* _res_, GError** error) {
+ SpiceCtrlControllerHandleClientData* _data_;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
+ return;
+ }
+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
+}
+
+
+static void spice_ctrl_controller_handle_client_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
+ SpiceCtrlControllerHandleClientData* _data_;
+ _data_ = _user_data_;
+ _data_->_source_object_ = source_object;
+ _data_->_res_ = _res_;
+ spice_ctrl_controller_handle_client_co (_data_);
+}
+
+
+static gboolean spice_ctrl_controller_handle_client_co (SpiceCtrlControllerHandleClientData* _data_) {
+ switch (_data_->_state_) {
+ case 0:
+ goto _state_0;
+ case 1:
+ goto _state_1;
+ case 2:
+ goto _state_2;
+ case 3:
+ goto _state_3;
+ default:
+ g_assert_not_reached ();
+ }
+ _state_0:
+ _data_->excl = FALSE;
+ g_debug ("controller.vala:215: new socket client, reading init header");
+ _data_->_tmp0_ = NULL;
+ _data_->_tmp0_ = g_new0 (guint8, sizeof (ControllerInit));
+ _data_->p_length1 = 0;
+ _data_->_p_size_ = 0;
+ _data_->p = _data_->_tmp0_;
+ _data_->p_length1 = sizeof (ControllerInit);
+ _data_->_p_size_ = _data_->p_length1;
+ _data_->_tmp1_ = NULL;
+ _data_->_tmp1__length1 = 0;
+ _data_->_tmp1_ = _data_->p;
+ _data_->_tmp1__length1 = _data_->p_length1;
+ _data_->init = (ControllerInit*) _data_->_tmp1_;
+ _data_->_tmp2_ = NULL;
+ _data_->_tmp2_ = _data_->c;
+ _data_->_tmp3_ = NULL;
+ _data_->_tmp3_ = g_io_stream_get_input_stream (_data_->_tmp2_);
+ _data_->_tmp4_ = NULL;
+ _data_->_tmp4_ = _data_->_tmp3_;
+ _data_->_tmp5_ = NULL;
+ _data_->_tmp5__length1 = 0;
+ _data_->_tmp5_ = _data_->p;
+ _data_->_tmp5__length1 = _data_->p_length1;
+ _data_->_state_ = 1;
+ spice_ctrl_input_stream_read (_data_->_tmp4_, _data_->_tmp5_, _data_->_tmp5__length1, spice_ctrl_controller_handle_client_ready, _data_);
+ return FALSE;
+ _state_1:
+ spice_ctrl_input_stream_read_finish (_data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp6_ = NULL;
+ _data_->_tmp6_ = _data_->init;
+ memset (&_data_->_tmp7_, 0, sizeof (ControllerInitHeader));
+ _data_->_tmp7_ = (*_data_->_tmp6_).base;
+ _data_->_tmp8_ = 0U;
+ _data_->_tmp8_ = _data_->_tmp7_.magic;
+ _data_->_tmp9_ = FALSE;
+ _data_->_tmp9_ = g_warn_if (_data_->_tmp8_ != CONTROLLER_MAGIC);
+ if (_data_->_tmp9_) {
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp10_ = NULL;
+ _data_->_tmp10_ = _data_->init;
+ memset (&_data_->_tmp11_, 0, sizeof (ControllerInitHeader));
+ _data_->_tmp11_ = (*_data_->_tmp10_).base;
+ _data_->_tmp12_ = 0U;
+ _data_->_tmp12_ = _data_->_tmp11_.version;
+ _data_->_tmp13_ = FALSE;
+ _data_->_tmp13_ = g_warn_if (_data_->_tmp12_ != ((guint32) CONTROLLER_VERSION));
+ if (_data_->_tmp13_) {
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp14_ = NULL;
+ _data_->_tmp14_ = _data_->init;
+ memset (&_data_->_tmp15_, 0, sizeof (ControllerInitHeader));
+ _data_->_tmp15_ = (*_data_->_tmp14_).base;
+ _data_->_tmp16_ = 0U;
+ _data_->_tmp16_ = _data_->_tmp15_.size;
+ _data_->_tmp17_ = FALSE;
+ _data_->_tmp17_ = g_warn_if (((gulong) _data_->_tmp16_) < sizeof (ControllerInit));
+ if (_data_->_tmp17_) {
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp18_ = NULL;
+ _data_->_tmp18_ = _data_->init;
+ _data_->_tmp19_ = 0ULL;
+ _data_->_tmp19_ = (*_data_->_tmp18_).credentials;
+ _data_->_tmp20_ = FALSE;
+ _data_->_tmp20_ = g_warn_if (_data_->_tmp19_ != ((guint64) 0));
+ if (_data_->_tmp20_) {
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp21_ = NULL;
+ _data_->_tmp21_ = _data_->self->priv->excl_connection;
+ _data_->_tmp22_ = FALSE;
+ _data_->_tmp22_ = g_warn_if (_data_->_tmp21_ != NULL);
+ if (_data_->_tmp22_) {
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp23_ = NULL;
+ _data_->_tmp23_ = _data_->init;
+ _data_->_tmp24_ = 0U;
+ _data_->_tmp24_ = (*_data_->_tmp23_).flags;
+ _data_->excl = (gboolean) (_data_->_tmp24_ & CONTROLLER_FLAG_EXCLUSIVE);
+ _data_->_tmp25_ = FALSE;
+ _data_->_tmp25_ = _data_->excl;
+ if (_data_->_tmp25_) {
+ _data_->_tmp26_ = 0;
+ _data_->_tmp26_ = _data_->self->priv->nclients;
+ if (_data_->_tmp26_ > 1) {
+ _data_->_tmp27_ = 0;
+ _data_->_tmp27_ = _data_->self->priv->nclients;
+ _data_->_tmp28_ = NULL;
+ _data_->_tmp28_ = g_strdup_printf ("%i", _data_->_tmp27_);
+ _data_->_tmp29_ = NULL;
+ _data_->_tmp29_ = _data_->_tmp28_;
+ _data_->_tmp30_ = NULL;
+ _data_->_tmp30_ = g_strconcat ("Can't make the client exclusive, there is already ", _data_->_tmp29_, " connected clients", NULL);
+ _data_->_tmp31_ = NULL;
+ _data_->_tmp31_ = _data_->_tmp30_;
+ g_warning ("controller.vala:234: %s", _data_->_tmp31_);
+ _g_free0 (_data_->_tmp31_);
+ _g_free0 (_data_->_tmp29_);
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp32_ = NULL;
+ _data_->_tmp32_ = _data_->c;
+ _data_->_tmp33_ = NULL;
+ _data_->_tmp33_ = _g_object_ref0 (_data_->_tmp32_);
+ _g_object_unref0 (_data_->self->priv->excl_connection);
+ _data_->self->priv->excl_connection = _data_->_tmp33_;
+ }
+ g_signal_emit_by_name (_data_->self, "client-connected");
+ {
+ _data_->_tmp34_ = TRUE;
+ while (TRUE) {
+ if (!_data_->_tmp34_) {
+ }
+ _data_->_tmp34_ = FALSE;
+ _data_->_tmp35_ = NULL;
+ _data_->_tmp35_ = g_new0 (guint8, sizeof (ControllerMsg));
+ _data_->t_length1 = 0;
+ _data_->_t_size_ = 0;
+ _data_->t = _data_->_tmp35_;
+ _data_->t_length1 = sizeof (ControllerMsg);
+ _data_->_t_size_ = _data_->t_length1;
+ _data_->_tmp36_ = NULL;
+ _data_->_tmp36_ = _data_->c;
+ _data_->_tmp37_ = NULL;
+ _data_->_tmp37_ = g_io_stream_get_input_stream (_data_->_tmp36_);
+ _data_->_tmp38_ = NULL;
+ _data_->_tmp38_ = _data_->_tmp37_;
+ _data_->_tmp39_ = NULL;
+ _data_->_tmp39__length1 = 0;
+ _data_->_tmp39_ = _data_->t;
+ _data_->_tmp39__length1 = _data_->t_length1;
+ _data_->_state_ = 2;
+ spice_ctrl_input_stream_read (_data_->_tmp38_, _data_->_tmp39_, _data_->_tmp39__length1, spice_ctrl_controller_handle_client_ready, _data_);
+ return FALSE;
+ _state_2:
+ spice_ctrl_input_stream_read_finish (_data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _data_->t = (g_free (_data_->t), NULL);
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp40_ = NULL;
+ _data_->_tmp40__length1 = 0;
+ _data_->_tmp40_ = _data_->t;
+ _data_->_tmp40__length1 = _data_->t_length1;
+ _data_->msg = (ControllerMsg*) _data_->_tmp40_;
+ _data_->_tmp41_ = NULL;
+ _data_->_tmp41_ = _data_->msg;
+ _data_->_tmp42_ = 0U;
+ _data_->_tmp42_ = (*_data_->_tmp41_).id;
+ _data_->_tmp43_ = NULL;
+ _data_->_tmp43_ = g_strdup_printf ("%u", _data_->_tmp42_);
+ _data_->_tmp44_ = NULL;
+ _data_->_tmp44_ = _data_->_tmp43_;
+ _data_->_tmp45_ = NULL;
+ _data_->_tmp45_ = g_strconcat ("new message ", _data_->_tmp44_, NULL);
+ _data_->_tmp46_ = NULL;
+ _data_->_tmp46_ = _data_->_tmp45_;
+ _data_->_tmp47_ = NULL;
+ _data_->_tmp47_ = g_strconcat (_data_->_tmp46_, "size ", NULL);
+ _data_->_tmp48_ = NULL;
+ _data_->_tmp48_ = _data_->_tmp47_;
+ _data_->_tmp49_ = NULL;
+ _data_->_tmp49_ = _data_->msg;
+ _data_->_tmp50_ = 0U;
+ _data_->_tmp50_ = (*_data_->_tmp49_).size;
+ _data_->_tmp51_ = NULL;
+ _data_->_tmp51_ = g_strdup_printf ("%u", _data_->_tmp50_);
+ _data_->_tmp52_ = NULL;
+ _data_->_tmp52_ = _data_->_tmp51_;
+ _data_->_tmp53_ = NULL;
+ _data_->_tmp53_ = g_strconcat (_data_->_tmp48_, _data_->_tmp52_, NULL);
+ _data_->_tmp54_ = NULL;
+ _data_->_tmp54_ = _data_->_tmp53_;
+ g_debug ("controller.vala:246: %s", _data_->_tmp54_);
+ _g_free0 (_data_->_tmp54_);
+ _g_free0 (_data_->_tmp52_);
+ _g_free0 (_data_->_tmp48_);
+ _g_free0 (_data_->_tmp46_);
+ _g_free0 (_data_->_tmp44_);
+ _data_->_tmp55_ = NULL;
+ _data_->_tmp55_ = _data_->msg;
+ _data_->_tmp56_ = 0U;
+ _data_->_tmp56_ = (*_data_->_tmp55_).size;
+ _data_->_tmp57_ = FALSE;
+ _data_->_tmp57_ = g_warn_if (((gulong) _data_->_tmp56_) < sizeof (ControllerMsg));
+ if (_data_->_tmp57_) {
+ _data_->t = (g_free (_data_->t), NULL);
+ break;
+ }
+ _data_->_tmp58_ = NULL;
+ _data_->_tmp58_ = _data_->msg;
+ _data_->_tmp59_ = 0U;
+ _data_->_tmp59_ = (*_data_->_tmp58_).size;
+ if (((gulong) _data_->_tmp59_) > sizeof (ControllerMsg)) {
+ _data_->_tmp60_ = NULL;
+ _data_->_tmp60_ = _data_->msg;
+ _data_->_tmp61_ = 0U;
+ _data_->_tmp61_ = (*_data_->_tmp60_).size;
+ _data_->_tmp62_ = 0;
+ _data_->_tmp62_ = (gint) _data_->_tmp61_;
+ _data_->t = g_renew (guint8, _data_->t, (gint) _data_->_tmp61_);
+ (_data_->_tmp62_ > _data_->t_length1) ? memset (_data_->t + _data_->t_length1, 0, sizeof (guint8) * (_data_->_tmp62_ - _data_->t_length1)) : NULL;
+ _data_->t_length1 = _data_->_tmp62_;
+ _data_->_t_size_ = _data_->_tmp62_;
+ _data_->_tmp63_ = NULL;
+ _data_->_tmp63__length1 = 0;
+ _data_->_tmp63_ = _data_->t;
+ _data_->_tmp63__length1 = _data_->t_length1;
+ _data_->msg = (ControllerMsg*) _data_->_tmp63_;
+ _data_->_tmp64_ = NULL;
+ _data_->_tmp64_ = _data_->c;
+ _data_->_tmp65_ = NULL;
+ _data_->_tmp65_ = g_io_stream_get_input_stream (_data_->_tmp64_);
+ _data_->_tmp66_ = NULL;
+ _data_->_tmp66_ = _data_->_tmp65_;
+ _data_->_tmp67_ = NULL;
+ _data_->_tmp67__length1 = 0;
+ _data_->_tmp67_ = _data_->t;
+ _data_->_tmp67__length1 = _data_->t_length1;
+ _data_->_tmp68_ = NULL;
+ _data_->_tmp68_ = _data_->msg;
+ _data_->_tmp69_ = 0U;
+ _data_->_tmp69_ = (*_data_->_tmp68_).size;
+ _data_->_state_ = 3;
+ spice_ctrl_input_stream_read (_data_->_tmp66_, _data_->_tmp67_ + ((gint) sizeof (ControllerMsg)), ((gint) _data_->_tmp69_) - ((gint) sizeof (ControllerMsg)), spice_ctrl_controller_handle_client_ready, _data_);
+ return FALSE;
+ _state_3:
+ spice_ctrl_input_stream_read_finish (_data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _data_->t = (g_free (_data_->t), NULL);
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ }
+ _data_->_tmp70_ = NULL;
+ _data_->_tmp70_ = _data_->msg;
+ spice_ctrl_controller_handle_message (_data_->self, _data_->_tmp70_);
+ _data_->t = (g_free (_data_->t), NULL);
+ }
+ }
+ _data_->_tmp71_ = FALSE;
+ _data_->_tmp71_ = _data_->excl;
+ if (_data_->_tmp71_) {
+ _g_object_unref0 (_data_->self->priv->excl_connection);
+ _data_->self->priv->excl_connection = NULL;
+ }
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+}
+
+
+SpiceCtrlController* spice_ctrl_controller_construct (GType object_type) {
+ SpiceCtrlController * self = NULL;
+ self = (SpiceCtrlController*) g_object_new (object_type, NULL);
+ return self;
+}
+
+
+SpiceCtrlController* spice_ctrl_controller_new (void) {
+ return spice_ctrl_controller_construct (SPICE_CTRL_TYPE_CONTROLLER);
+}
+
+
+static void spice_ctrl_controller_listen_data_free (gpointer _data) {
+ SpiceCtrlControllerListenData* _data_;
+ _data_ = _data;
+ _g_free0 (_data_->addr);
+ _g_object_unref0 (_data_->self);
+ g_slice_free (SpiceCtrlControllerListenData, _data_);
+}
+
+
+void spice_ctrl_controller_listen (SpiceCtrlController* self, const gchar* addr, GAsyncReadyCallback _callback_, gpointer _user_data_) {
+ SpiceCtrlControllerListenData* _data_;
+ SpiceCtrlController* _tmp0_ = NULL;
+ const gchar* _tmp1_ = NULL;
+ gchar* _tmp2_ = NULL;
+ _data_ = g_slice_new0 (SpiceCtrlControllerListenData);
+ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, spice_ctrl_controller_listen);
+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, spice_ctrl_controller_listen_data_free);
+ _tmp0_ = _g_object_ref0 (self);
+ _data_->self = _tmp0_;
+ _tmp1_ = addr;
+ _tmp2_ = g_strdup (_tmp1_);
+ _g_free0 (_data_->addr);
+ _data_->addr = _tmp2_;
+ spice_ctrl_controller_listen_co (_data_);
+}
+
+
+void spice_ctrl_controller_listen_finish (SpiceCtrlController* self, GAsyncResult* _res_, GError** error) {
+ SpiceCtrlControllerListenData* _data_;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
+ return;
+ }
+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
+}
+
+
+static void spice_ctrl_controller_listen_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
+ SpiceCtrlControllerListenData* _data_;
+ _data_ = _user_data_;
+ _data_->_source_object_ = source_object;
+ _data_->_res_ = _res_;
+ spice_ctrl_controller_listen_co (_data_);
+}
+
+
+static gboolean spice_ctrl_controller_listen_co (SpiceCtrlControllerListenData* _data_) {
+ switch (_data_->_state_) {
+ case 0:
+ goto _state_0;
+ case 1:
+ goto _state_1;
+ case 2:
+ goto _state_2;
+ default:
+ g_assert_not_reached ();
+ }
+ _state_0:
+ _data_->_tmp0_ = NULL;
+ _data_->_tmp0_ = _data_->addr;
+ _data_->_tmp1_ = NULL;
+ _data_->_tmp1_ = spice_controller_listener_new (_data_->_tmp0_, &_data_->_inner_error_);
+ _data_->listener = _data_->_tmp1_;
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ {
+ _data_->_tmp2_ = TRUE;
+ while (TRUE) {
+ if (!_data_->_tmp2_) {
+ }
+ _data_->_tmp2_ = FALSE;
+ _data_->_tmp3_ = NULL;
+ _data_->_tmp3_ = _data_->listener;
+ _data_->_state_ = 1;
+ spice_controller_listener_accept_async (_data_->_tmp3_, NULL, spice_ctrl_controller_listen_ready, _data_);
+ return FALSE;
+ _state_1:
+ _data_->_tmp4_ = NULL;
+ _data_->_tmp4_ = spice_controller_listener_accept_finish (_data_->_tmp3_, _data_->_res_, NULL, &_data_->_inner_error_);
+ _data_->_tmp5_ = NULL;
+ _data_->_tmp5_ = _g_object_ref0 (_data_->_tmp4_);
+ _data_->c = _data_->_tmp5_;
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _g_object_unref0 (_data_->listener);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp6_ = 0;
+ _data_->_tmp6_ = _data_->self->priv->nclients;
+ _data_->self->priv->nclients = _data_->_tmp6_ + 1;
+ _data_->_tmp7_ = NULL;
+ _data_->_tmp7_ = _data_->c;
+ _data_->_tmp8_ = NULL;
+ _data_->_tmp8_ = _g_object_ref0 (_data_->_tmp7_);
+ _data_->self->priv->clients = g_list_append (_data_->self->priv->clients, _data_->_tmp8_);
+ {
+ _data_->_tmp9_ = NULL;
+ _data_->_tmp9_ = _data_->c;
+ _data_->_state_ = 2;
+ spice_ctrl_controller_handle_client (_data_->self, _data_->_tmp9_, spice_ctrl_controller_listen_ready, _data_);
+ return FALSE;
+ _state_2:
+ spice_ctrl_controller_handle_client_finish (_data_->self, _data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ goto __catch2_g_error;
+ }
+ }
+ goto __finally2;
+ __catch2_g_error:
+ {
+ _data_->e = _data_->_inner_error_;
+ _data_->_inner_error_ = NULL;
+ _data_->_tmp10_ = NULL;
+ _data_->_tmp10_ = _data_->e;
+ _data_->_tmp11_ = NULL;
+ _data_->_tmp11_ = _data_->_tmp10_->message;
+ g_warning ("controller.vala:277: %s", _data_->_tmp11_);
+ _g_error_free0 (_data_->e);
+ }
+ __finally2:
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _g_object_unref0 (_data_->c);
+ _g_object_unref0 (_data_->listener);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp12_ = NULL;
+ _data_->_tmp12_ = _data_->c;
+ g_io_stream_close (_data_->_tmp12_, NULL, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _g_object_unref0 (_data_->c);
+ _g_object_unref0 (_data_->listener);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp13_ = NULL;
+ _data_->_tmp13_ = _data_->c;
+ _data_->self->priv->clients = g_list_remove (_data_->self->priv->clients, _data_->_tmp13_);
+ _data_->_tmp14_ = 0;
+ _data_->_tmp14_ = _data_->self->priv->nclients;
+ _data_->self->priv->nclients = _data_->_tmp14_ - 1;
+ _g_object_unref0 (_data_->c);
+ }
+ }
+ _g_object_unref0 (_data_->listener);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+}
+
+
+const gchar* spice_ctrl_controller_get_host (SpiceCtrlController* self) {
+ const gchar* result;
+ const gchar* _tmp0_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_host;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_host (SpiceCtrlController* self, const gchar* value) {
+ const gchar* _tmp0_ = NULL;
+ gchar* _tmp1_ = NULL;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp1_ = g_strdup (_tmp0_);
+ _g_free0 (self->priv->_host);
+ self->priv->_host = _tmp1_;
+ g_object_notify ((GObject *) self, "host");
+}
+
+
+guint32 spice_ctrl_controller_get_port (SpiceCtrlController* self) {
+ guint32 result;
+ guint32 _tmp0_ = 0U;
+ g_return_val_if_fail (self != NULL, 0U);
+ _tmp0_ = self->priv->_port;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_port (SpiceCtrlController* self, guint32 value) {
+ guint32 _tmp0_ = 0U;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ self->priv->_port = _tmp0_;
+ g_object_notify ((GObject *) self, "port");
+}
+
+
+guint32 spice_ctrl_controller_get_sport (SpiceCtrlController* self) {
+ guint32 result;
+ guint32 _tmp0_ = 0U;
+ g_return_val_if_fail (self != NULL, 0U);
+ _tmp0_ = self->priv->_sport;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_sport (SpiceCtrlController* self, guint32 value) {
+ guint32 _tmp0_ = 0U;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ self->priv->_sport = _tmp0_;
+ g_object_notify ((GObject *) self, "sport");
+}
+
+
+const gchar* spice_ctrl_controller_get_password (SpiceCtrlController* self) {
+ const gchar* result;
+ const gchar* _tmp0_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_password;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_password (SpiceCtrlController* self, const gchar* value) {
+ const gchar* _tmp0_ = NULL;
+ gchar* _tmp1_ = NULL;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp1_ = g_strdup (_tmp0_);
+ _g_free0 (self->priv->_password);
+ self->priv->_password = _tmp1_;
+ g_object_notify ((GObject *) self, "password");
+}
+
+
+unsigned int spice_ctrl_controller_get_display_flags (SpiceCtrlController* self) {
+ unsigned int result;
+ unsigned int _tmp0_ = 0;
+ g_return_val_if_fail (self != NULL, 0);
+ _tmp0_ = self->priv->_display_flags;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_display_flags (SpiceCtrlController* self, unsigned int value) {
+ unsigned int _tmp0_ = 0;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ self->priv->_display_flags = _tmp0_;
+ g_object_notify ((GObject *) self, "display-flags");
+}
+
+
+const gchar* spice_ctrl_controller_get_tls_ciphers (SpiceCtrlController* self) {
+ const gchar* result;
+ const gchar* _tmp0_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_tls_ciphers;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_tls_ciphers (SpiceCtrlController* self, const gchar* value) {
+ const gchar* _tmp0_ = NULL;
+ gchar* _tmp1_ = NULL;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp1_ = g_strdup (_tmp0_);
+ _g_free0 (self->priv->_tls_ciphers);
+ self->priv->_tls_ciphers = _tmp1_;
+ g_object_notify ((GObject *) self, "tls-ciphers");
+}
+
+
+const gchar* spice_ctrl_controller_get_host_subject (SpiceCtrlController* self) {
+ const gchar* result;
+ const gchar* _tmp0_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_host_subject;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_host_subject (SpiceCtrlController* self, const gchar* value) {
+ const gchar* _tmp0_ = NULL;
+ gchar* _tmp1_ = NULL;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp1_ = g_strdup (_tmp0_);
+ _g_free0 (self->priv->_host_subject);
+ self->priv->_host_subject = _tmp1_;
+ g_object_notify ((GObject *) self, "host-subject");
+}
+
+
+const gchar* spice_ctrl_controller_get_ca_file (SpiceCtrlController* self) {
+ const gchar* result;
+ const gchar* _tmp0_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_ca_file;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_ca_file (SpiceCtrlController* self, const gchar* value) {
+ const gchar* _tmp0_ = NULL;
+ gchar* _tmp1_ = NULL;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp1_ = g_strdup (_tmp0_);
+ _g_free0 (self->priv->_ca_file);
+ self->priv->_ca_file = _tmp1_;
+ g_object_notify ((GObject *) self, "ca-file");
+}
+
+
+const gchar* spice_ctrl_controller_get_title (SpiceCtrlController* self) {
+ const gchar* result;
+ const gchar* _tmp0_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_title;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_title (SpiceCtrlController* self, const gchar* value) {
+ const gchar* _tmp0_ = NULL;
+ gchar* _tmp1_ = NULL;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp1_ = g_strdup (_tmp0_);
+ _g_free0 (self->priv->_title);
+ self->priv->_title = _tmp1_;
+ g_object_notify ((GObject *) self, "title");
+}
+
+
+const gchar* spice_ctrl_controller_get_hotkeys (SpiceCtrlController* self) {
+ const gchar* result;
+ const gchar* _tmp0_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_hotkeys;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_hotkeys (SpiceCtrlController* self, const gchar* value) {
+ const gchar* _tmp0_ = NULL;
+ gchar* _tmp1_ = NULL;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp1_ = g_strdup (_tmp0_);
+ _g_free0 (self->priv->_hotkeys);
+ self->priv->_hotkeys = _tmp1_;
+ g_object_notify ((GObject *) self, "hotkeys");
+}
+
+
+gchar** spice_ctrl_controller_get_secure_channels (SpiceCtrlController* self, int* result_length1) {
+ gchar** result;
+ gchar** _tmp0_ = NULL;
+ gint _tmp0__length1 = 0;
+ gchar** _tmp1_ = NULL;
+ gint _tmp1__length1 = 0;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_secure_channels;
+ _tmp0__length1 = self->priv->_secure_channels_length1;
+ _tmp1_ = _tmp0_;
+ _tmp1__length1 = _tmp0__length1;
+ if (result_length1) {
+ *result_length1 = _tmp1__length1;
+ }
+ result = _tmp1_;
+ return result;
+}
+
+
+static gchar** _vala_array_dup3 (gchar** self, int length) {
+ gchar** result;
+ int i;
+ result = g_new0 (gchar*, length + 1);
+ for (i = 0; i < length; i++) {
+ gchar* _tmp0_ = NULL;
+ _tmp0_ = g_strdup (self[i]);
+ result[i] = _tmp0_;
+ }
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_secure_channels (SpiceCtrlController* self, gchar** value, int value_length1) {
+ gchar** _tmp0_ = NULL;
+ gint _tmp0__length1 = 0;
+ gchar** _tmp1_ = NULL;
+ gint _tmp1__length1 = 0;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp0__length1 = value_length1;
+ _tmp1_ = (_tmp0_ != NULL) ? _vala_array_dup3 (_tmp0_, _tmp0__length1) : ((gpointer) _tmp0_);
+ _tmp1__length1 = _tmp0__length1;
+ self->priv->_secure_channels = (_vala_array_free (self->priv->_secure_channels, self->priv->_secure_channels_length1, (GDestroyNotify) g_free), NULL);
+ self->priv->_secure_channels = _tmp1_;
+ self->priv->_secure_channels_length1 = _tmp1__length1;
+ self->priv->__secure_channels_size_ = self->priv->_secure_channels_length1;
+ g_object_notify ((GObject *) self, "secure-channels");
+}
+
+
+gchar** spice_ctrl_controller_get_disable_channels (SpiceCtrlController* self, int* result_length1) {
+ gchar** result;
+ gchar** _tmp0_ = NULL;
+ gint _tmp0__length1 = 0;
+ gchar** _tmp1_ = NULL;
+ gint _tmp1__length1 = 0;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_disable_channels;
+ _tmp0__length1 = self->priv->_disable_channels_length1;
+ _tmp1_ = _tmp0_;
+ _tmp1__length1 = _tmp0__length1;
+ if (result_length1) {
+ *result_length1 = _tmp1__length1;
+ }
+ result = _tmp1_;
+ return result;
+}
+
+
+static gchar** _vala_array_dup4 (gchar** self, int length) {
+ gchar** result;
+ int i;
+ result = g_new0 (gchar*, length + 1);
+ for (i = 0; i < length; i++) {
+ gchar* _tmp0_ = NULL;
+ _tmp0_ = g_strdup (self[i]);
+ result[i] = _tmp0_;
+ }
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_disable_channels (SpiceCtrlController* self, gchar** value, int value_length1) {
+ gchar** _tmp0_ = NULL;
+ gint _tmp0__length1 = 0;
+ gchar** _tmp1_ = NULL;
+ gint _tmp1__length1 = 0;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp0__length1 = value_length1;
+ _tmp1_ = (_tmp0_ != NULL) ? _vala_array_dup4 (_tmp0_, _tmp0__length1) : ((gpointer) _tmp0_);
+ _tmp1__length1 = _tmp0__length1;
+ self->priv->_disable_channels = (_vala_array_free (self->priv->_disable_channels, self->priv->_disable_channels_length1, (GDestroyNotify) g_free), NULL);
+ self->priv->_disable_channels = _tmp1_;
+ self->priv->_disable_channels_length1 = _tmp1__length1;
+ self->priv->__disable_channels_size_ = self->priv->_disable_channels_length1;
+ g_object_notify ((GObject *) self, "disable-channels");
+}
+
+
+SpiceCtrlMenu* spice_ctrl_controller_get_menu (SpiceCtrlController* self) {
+ SpiceCtrlMenu* result;
+ SpiceCtrlMenu* _tmp0_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_menu;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_menu (SpiceCtrlController* self, SpiceCtrlMenu* value) {
+ SpiceCtrlMenu* _tmp0_ = NULL;
+ SpiceCtrlMenu* _tmp1_ = NULL;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp1_ = _g_object_ref0 (_tmp0_);
+ _g_object_unref0 (self->priv->_menu);
+ self->priv->_menu = _tmp1_;
+ g_object_notify ((GObject *) self, "menu");
+}
+
+
+gboolean spice_ctrl_controller_get_enable_smartcard (SpiceCtrlController* self) {
+ gboolean result;
+ gboolean _tmp0_ = FALSE;
+ g_return_val_if_fail (self != NULL, FALSE);
+ _tmp0_ = self->priv->_enable_smartcard;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_enable_smartcard (SpiceCtrlController* self, gboolean value) {
+ gboolean _tmp0_ = FALSE;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ self->priv->_enable_smartcard = _tmp0_;
+ g_object_notify ((GObject *) self, "enable-smartcard");
+}
+
+
+gboolean spice_ctrl_controller_get_send_cad (SpiceCtrlController* self) {
+ gboolean result;
+ gboolean _tmp0_ = FALSE;
+ g_return_val_if_fail (self != NULL, FALSE);
+ _tmp0_ = self->priv->_send_cad;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_send_cad (SpiceCtrlController* self, gboolean value) {
+ gboolean _tmp0_ = FALSE;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ self->priv->_send_cad = _tmp0_;
+ g_object_notify ((GObject *) self, "send-cad");
+}
+
+
+gchar** spice_ctrl_controller_get_disable_effects (SpiceCtrlController* self, int* result_length1) {
+ gchar** result;
+ gchar** _tmp0_ = NULL;
+ gint _tmp0__length1 = 0;
+ gchar** _tmp1_ = NULL;
+ gint _tmp1__length1 = 0;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_disable_effects;
+ _tmp0__length1 = self->priv->_disable_effects_length1;
+ _tmp1_ = _tmp0_;
+ _tmp1__length1 = _tmp0__length1;
+ if (result_length1) {
+ *result_length1 = _tmp1__length1;
+ }
+ result = _tmp1_;
+ return result;
+}
+
+
+static gchar** _vala_array_dup5 (gchar** self, int length) {
+ gchar** result;
+ int i;
+ result = g_new0 (gchar*, length + 1);
+ for (i = 0; i < length; i++) {
+ gchar* _tmp0_ = NULL;
+ _tmp0_ = g_strdup (self[i]);
+ result[i] = _tmp0_;
+ }
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_disable_effects (SpiceCtrlController* self, gchar** value, int value_length1) {
+ gchar** _tmp0_ = NULL;
+ gint _tmp0__length1 = 0;
+ gchar** _tmp1_ = NULL;
+ gint _tmp1__length1 = 0;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp0__length1 = value_length1;
+ _tmp1_ = (_tmp0_ != NULL) ? _vala_array_dup5 (_tmp0_, _tmp0__length1) : ((gpointer) _tmp0_);
+ _tmp1__length1 = _tmp0__length1;
+ self->priv->_disable_effects = (_vala_array_free (self->priv->_disable_effects, self->priv->_disable_effects_length1, (GDestroyNotify) g_free), NULL);
+ self->priv->_disable_effects = _tmp1_;
+ self->priv->_disable_effects_length1 = _tmp1__length1;
+ self->priv->__disable_effects_size_ = self->priv->_disable_effects_length1;
+ g_object_notify ((GObject *) self, "disable-effects");
+}
+
+
+guint32 spice_ctrl_controller_get_color_depth (SpiceCtrlController* self) {
+ guint32 result;
+ guint32 _tmp0_ = 0U;
+ g_return_val_if_fail (self != NULL, 0U);
+ _tmp0_ = self->priv->_color_depth;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_color_depth (SpiceCtrlController* self, guint32 value) {
+ guint32 _tmp0_ = 0U;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ self->priv->_color_depth = _tmp0_;
+ g_object_notify ((GObject *) self, "color-depth");
+}
+
+
+gboolean spice_ctrl_controller_get_enable_usbredir (SpiceCtrlController* self) {
+ gboolean result;
+ gboolean _tmp0_ = FALSE;
+ g_return_val_if_fail (self != NULL, FALSE);
+ _tmp0_ = self->priv->_enable_usbredir;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_enable_usbredir (SpiceCtrlController* self, gboolean value) {
+ gboolean _tmp0_ = FALSE;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ self->priv->_enable_usbredir = _tmp0_;
+ g_object_notify ((GObject *) self, "enable-usbredir");
+}
+
+
+gboolean spice_ctrl_controller_get_enable_usb_autoshare (SpiceCtrlController* self) {
+ gboolean result;
+ gboolean _tmp0_ = FALSE;
+ g_return_val_if_fail (self != NULL, FALSE);
+ _tmp0_ = self->priv->_enable_usb_autoshare;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_enable_usb_autoshare (SpiceCtrlController* self, gboolean value) {
+ gboolean _tmp0_ = FALSE;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ self->priv->_enable_usb_autoshare = _tmp0_;
+ g_object_notify ((GObject *) self, "enable-usb-autoshare");
+}
+
+
+const gchar* spice_ctrl_controller_get_usb_filter (SpiceCtrlController* self) {
+ const gchar* result;
+ const gchar* _tmp0_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_usb_filter;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_usb_filter (SpiceCtrlController* self, const gchar* value) {
+ const gchar* _tmp0_ = NULL;
+ gchar* _tmp1_ = NULL;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp1_ = g_strdup (_tmp0_);
+ _g_free0 (self->priv->_usb_filter);
+ self->priv->_usb_filter = _tmp1_;
+ g_object_notify ((GObject *) self, "usb-filter");
+}
+
+
+const gchar* spice_ctrl_controller_get_proxy (SpiceCtrlController* self) {
+ const gchar* result;
+ const gchar* _tmp0_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_proxy;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_controller_set_proxy (SpiceCtrlController* self, const gchar* value) {
+ const gchar* _tmp0_ = NULL;
+ gchar* _tmp1_ = NULL;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp1_ = g_strdup (_tmp0_);
+ _g_free0 (self->priv->_proxy);
+ self->priv->_proxy = _tmp1_;
+ g_object_notify ((GObject *) self, "proxy");
+}
+
+
+static void spice_ctrl_controller_class_init (SpiceCtrlControllerClass * klass) {
+ spice_ctrl_controller_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (SpiceCtrlControllerPrivate));
+ G_OBJECT_CLASS (klass)->get_property = _vala_spice_ctrl_controller_get_property;
+ G_OBJECT_CLASS (klass)->set_property = _vala_spice_ctrl_controller_set_property;
+ G_OBJECT_CLASS (klass)->finalize = spice_ctrl_controller_finalize;
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_HOST, g_param_spec_string ("host", "host", "host", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_PORT, g_param_spec_uint ("port", "port", "port", 0, G_MAXUINT, 0U, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_SPORT, g_param_spec_uint ("sport", "sport", "sport", 0, G_MAXUINT, 0U, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_PASSWORD, g_param_spec_string ("password", "password", "password", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_DISPLAY_FLAGS, g_param_spec_uint ("display-flags", "display-flags", "display-flags", 0, G_MAXUINT, 0, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_TLS_CIPHERS, g_param_spec_string ("tls-ciphers", "tls-ciphers", "tls-ciphers", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_HOST_SUBJECT, g_param_spec_string ("host-subject", "host-subject", "host-subject", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_CA_FILE, g_param_spec_string ("ca-file", "ca-file", "ca-file", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_TITLE, g_param_spec_string ("title", "title", "title", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_HOTKEYS, g_param_spec_string ("hotkeys", "hotkeys", "hotkeys", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_SECURE_CHANNELS, g_param_spec_boxed ("secure-channels", "secure-channels", "secure-channels", G_TYPE_STRV, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_DISABLE_CHANNELS, g_param_spec_boxed ("disable-channels", "disable-channels", "disable-channels", G_TYPE_STRV, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_MENU, g_param_spec_object ("menu", "menu", "menu", SPICE_CTRL_TYPE_MENU, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_ENABLE_SMARTCARD, g_param_spec_boolean ("enable-smartcard", "enable-smartcard", "enable-smartcard", FALSE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_SEND_CAD, g_param_spec_boolean ("send-cad", "send-cad", "send-cad", FALSE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_DISABLE_EFFECTS, g_param_spec_boxed ("disable-effects", "disable-effects", "disable-effects", G_TYPE_STRV, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_COLOR_DEPTH, g_param_spec_uint ("color-depth", "color-depth", "color-depth", 0, G_MAXUINT, 0U, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_ENABLE_USBREDIR, g_param_spec_boolean ("enable-usbredir", "enable-usbredir", "enable-usbredir", FALSE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_ENABLE_USB_AUTOSHARE, g_param_spec_boolean ("enable-usb-autoshare", "enable-usb-autoshare", "enable-usb-autoshare", FALSE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_USB_FILTER, g_param_spec_string ("usb-filter", "usb-filter", "usb-filter", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_CONTROLLER_PROXY, g_param_spec_string ("proxy", "proxy", "proxy", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_signal_new ("do_connect", SPICE_CTRL_TYPE_CONTROLLER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+ g_signal_new ("show", SPICE_CTRL_TYPE_CONTROLLER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+ g_signal_new ("hide", SPICE_CTRL_TYPE_CONTROLLER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+ g_signal_new ("client_connected", SPICE_CTRL_TYPE_CONTROLLER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+
+static void spice_ctrl_controller_instance_init (SpiceCtrlController * self) {
+ self->priv = SPICE_CTRL_CONTROLLER_GET_PRIVATE (self);
+}
+
+
+static void spice_ctrl_controller_finalize (GObject* obj) {
+ SpiceCtrlController * self;
+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, SPICE_CTRL_TYPE_CONTROLLER, SpiceCtrlController);
+ _g_free0 (self->priv->_host);
+ _g_free0 (self->priv->_password);
+ _g_free0 (self->priv->_tls_ciphers);
+ _g_free0 (self->priv->_host_subject);
+ _g_free0 (self->priv->_ca_file);
+ _g_free0 (self->priv->_title);
+ _g_free0 (self->priv->_hotkeys);
+ self->priv->_secure_channels = (_vala_array_free (self->priv->_secure_channels, self->priv->_secure_channels_length1, (GDestroyNotify) g_free), NULL);
+ self->priv->_disable_channels = (_vala_array_free (self->priv->_disable_channels, self->priv->_disable_channels_length1, (GDestroyNotify) g_free), NULL);
+ _g_object_unref0 (self->priv->_menu);
+ self->priv->_disable_effects = (_vala_array_free (self->priv->_disable_effects, self->priv->_disable_effects_length1, (GDestroyNotify) g_free), NULL);
+ _g_free0 (self->priv->_usb_filter);
+ _g_free0 (self->priv->_proxy);
+ _g_object_unref0 (self->priv->excl_connection);
+ __g_list_free__g_object_unref0_0 (self->priv->clients);
+ G_OBJECT_CLASS (spice_ctrl_controller_parent_class)->finalize (obj);
+}
+
+
+GType spice_ctrl_controller_get_type (void) {
+ static volatile gsize spice_ctrl_controller_type_id__volatile = 0;
+ if (g_once_init_enter (&spice_ctrl_controller_type_id__volatile)) {
+ static const GTypeInfo g_define_type_info = { sizeof (SpiceCtrlControllerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) spice_ctrl_controller_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SpiceCtrlController), 0, (GInstanceInitFunc) spice_ctrl_controller_instance_init, NULL };
+ GType spice_ctrl_controller_type_id;
+ spice_ctrl_controller_type_id = g_type_register_static (G_TYPE_OBJECT, "SpiceCtrlController", &g_define_type_info, 0);
+ g_once_init_leave (&spice_ctrl_controller_type_id__volatile, spice_ctrl_controller_type_id);
+ }
+ return spice_ctrl_controller_type_id__volatile;
+}
+
+
+static void _vala_spice_ctrl_controller_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
+ SpiceCtrlController * self;
+ self = G_TYPE_CHECK_INSTANCE_CAST (object, SPICE_CTRL_TYPE_CONTROLLER, SpiceCtrlController);
+ switch (property_id) {
+ case SPICE_CTRL_CONTROLLER_HOST:
+ g_value_set_string (value, spice_ctrl_controller_get_host (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_PORT:
+ g_value_set_uint (value, spice_ctrl_controller_get_port (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_SPORT:
+ g_value_set_uint (value, spice_ctrl_controller_get_sport (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_PASSWORD:
+ g_value_set_string (value, spice_ctrl_controller_get_password (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_DISPLAY_FLAGS:
+ g_value_set_uint (value, spice_ctrl_controller_get_display_flags (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_TLS_CIPHERS:
+ g_value_set_string (value, spice_ctrl_controller_get_tls_ciphers (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_HOST_SUBJECT:
+ g_value_set_string (value, spice_ctrl_controller_get_host_subject (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_CA_FILE:
+ g_value_set_string (value, spice_ctrl_controller_get_ca_file (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_TITLE:
+ g_value_set_string (value, spice_ctrl_controller_get_title (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_HOTKEYS:
+ g_value_set_string (value, spice_ctrl_controller_get_hotkeys (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_SECURE_CHANNELS:
+ {
+ int length;
+ g_value_set_boxed (value, spice_ctrl_controller_get_secure_channels (self, &length));
+ }
+ break;
+ case SPICE_CTRL_CONTROLLER_DISABLE_CHANNELS:
+ {
+ int length;
+ g_value_set_boxed (value, spice_ctrl_controller_get_disable_channels (self, &length));
+ }
+ break;
+ case SPICE_CTRL_CONTROLLER_MENU:
+ g_value_set_object (value, spice_ctrl_controller_get_menu (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_ENABLE_SMARTCARD:
+ g_value_set_boolean (value, spice_ctrl_controller_get_enable_smartcard (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_SEND_CAD:
+ g_value_set_boolean (value, spice_ctrl_controller_get_send_cad (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_DISABLE_EFFECTS:
+ {
+ int length;
+ g_value_set_boxed (value, spice_ctrl_controller_get_disable_effects (self, &length));
+ }
+ break;
+ case SPICE_CTRL_CONTROLLER_COLOR_DEPTH:
+ g_value_set_uint (value, spice_ctrl_controller_get_color_depth (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_ENABLE_USBREDIR:
+ g_value_set_boolean (value, spice_ctrl_controller_get_enable_usbredir (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_ENABLE_USB_AUTOSHARE:
+ g_value_set_boolean (value, spice_ctrl_controller_get_enable_usb_autoshare (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_USB_FILTER:
+ g_value_set_string (value, spice_ctrl_controller_get_usb_filter (self));
+ break;
+ case SPICE_CTRL_CONTROLLER_PROXY:
+ g_value_set_string (value, spice_ctrl_controller_get_proxy (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void _vala_spice_ctrl_controller_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
+ SpiceCtrlController * self;
+ self = G_TYPE_CHECK_INSTANCE_CAST (object, SPICE_CTRL_TYPE_CONTROLLER, SpiceCtrlController);
+ switch (property_id) {
+ case SPICE_CTRL_CONTROLLER_HOST:
+ spice_ctrl_controller_set_host (self, g_value_get_string (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_PORT:
+ spice_ctrl_controller_set_port (self, g_value_get_uint (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_SPORT:
+ spice_ctrl_controller_set_sport (self, g_value_get_uint (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_PASSWORD:
+ spice_ctrl_controller_set_password (self, g_value_get_string (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_DISPLAY_FLAGS:
+ spice_ctrl_controller_set_display_flags (self, g_value_get_uint (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_TLS_CIPHERS:
+ spice_ctrl_controller_set_tls_ciphers (self, g_value_get_string (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_HOST_SUBJECT:
+ spice_ctrl_controller_set_host_subject (self, g_value_get_string (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_CA_FILE:
+ spice_ctrl_controller_set_ca_file (self, g_value_get_string (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_TITLE:
+ spice_ctrl_controller_set_title (self, g_value_get_string (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_HOTKEYS:
+ spice_ctrl_controller_set_hotkeys (self, g_value_get_string (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_SECURE_CHANNELS:
+ {
+ gpointer boxed;
+ boxed = g_value_get_boxed (value);
+ spice_ctrl_controller_set_secure_channels (self, boxed, (boxed == NULL) ? 0 : g_strv_length (boxed));
+ }
+ break;
+ case SPICE_CTRL_CONTROLLER_DISABLE_CHANNELS:
+ {
+ gpointer boxed;
+ boxed = g_value_get_boxed (value);
+ spice_ctrl_controller_set_disable_channels (self, boxed, (boxed == NULL) ? 0 : g_strv_length (boxed));
+ }
+ break;
+ case SPICE_CTRL_CONTROLLER_MENU:
+ spice_ctrl_controller_set_menu (self, g_value_get_object (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_ENABLE_SMARTCARD:
+ spice_ctrl_controller_set_enable_smartcard (self, g_value_get_boolean (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_SEND_CAD:
+ spice_ctrl_controller_set_send_cad (self, g_value_get_boolean (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_DISABLE_EFFECTS:
+ {
+ gpointer boxed;
+ boxed = g_value_get_boxed (value);
+ spice_ctrl_controller_set_disable_effects (self, boxed, (boxed == NULL) ? 0 : g_strv_length (boxed));
+ }
+ break;
+ case SPICE_CTRL_CONTROLLER_COLOR_DEPTH:
+ spice_ctrl_controller_set_color_depth (self, g_value_get_uint (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_ENABLE_USBREDIR:
+ spice_ctrl_controller_set_enable_usbredir (self, g_value_get_boolean (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_ENABLE_USB_AUTOSHARE:
+ spice_ctrl_controller_set_enable_usb_autoshare (self, g_value_get_boolean (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_USB_FILTER:
+ spice_ctrl_controller_set_usb_filter (self, g_value_get_string (value));
+ break;
+ case SPICE_CTRL_CONTROLLER_PROXY:
+ spice_ctrl_controller_set_proxy (self, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
+ if ((array != NULL) && (destroy_func != NULL)) {
+ int i;
+ for (i = 0; i < array_length; i = i + 1) {
+ if (((gpointer*) array)[i] != NULL) {
+ destroy_func (((gpointer*) array)[i]);
+ }
+ }
+ }
+}
+
+
+static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) {
+ _vala_array_destroy (array, array_length, destroy_func);
+ g_free (array);
+}
+
+
+static gint _vala_array_length (gpointer array) {
+ int length;
+ length = 0;
+ if (array) {
+ while (((gpointer*) array)[length]) {
+ length++;
+ }
+ }
+ return length;
+}
+
+
+
--- /dev/null
+// Copyright (C) 2011 Red Hat, Inc.
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+using GLib;
+using Custom;
+using Win32;
+using Spice;
+using SpiceProtocol;
+
+namespace SpiceCtrl {
+
+public errordomain Error {
+ VALUE,
+}
+
+public class Controller: Object {
+ public string host { private set; get; }
+ public uint32 port { private set; get; }
+ public uint32 sport { private set; get; }
+ public string password { private set; get; }
+ public SpiceProtocol.Controller.Display display_flags { private set; get; }
+ public string tls_ciphers { private set; get; }
+ public string host_subject { private set; get; }
+ public string ca_file { private set; get; }
+ public string title { private set; get; }
+ public string hotkeys { private set; get; }
+ public string[] secure_channels { private set; get; }
+ public string[] disable_channels { private set; get; }
+ public SpiceCtrl.Menu? menu { private set; get; }
+ public bool enable_smartcard { private set; get; }
+ public bool send_cad { private set; get; }
+ public string[] disable_effects {private set; get; }
+ public uint32 color_depth {private set; get; }
+ public bool enable_usbredir { private set; get; }
+ public bool enable_usb_autoshare { private set; get; }
+ public string usb_filter { private set; get; }
+ public string proxy { private set; get; }
+
+ public signal void do_connect ();
+ public signal void show ();
+ public signal void hide ();
+
+ public signal void client_connected ();
+
+ public void menu_item_click_msg (int32 item_id) {
+ var msg = SpiceProtocol.Controller.MsgValue ();
+ msg.base.size = (uint32)sizeof (SpiceProtocol.Controller.MsgValue);
+ msg.base.id = SpiceProtocol.Controller.MsgId.MENU_ITEM_CLICK;
+ msg.value = item_id;
+ unowned uint8[] p = ((uint8[])(&msg))[0:msg.base.size];
+ send_msg.begin (p);
+ }
+
+ public async bool send_msg (uint8[] p) throws GLib.Error {
+ // vala FIXME: pass Controller.Msg instead
+ // vala doesn't keep reference on the struct in async methods
+ // it copies only base, which is not enough to transmit the whole
+ // message.
+ try {
+ if (excl_connection != null) {
+ yield output_stream_write (excl_connection.output_stream, p);
+ } else {
+ foreach (var c in clients)
+ yield output_stream_write (c.output_stream, p);
+ }
+ } catch (GLib.Error e) {
+ warning (e.message);
+ }
+
+ return true;
+ }
+
+ private GLib.IOStream? excl_connection;
+ private int nclients;
+ List<IOStream> clients;
+
+ private bool handle_message (SpiceProtocol.Controller.Msg* msg) {
+ var v = (SpiceProtocol.Controller.MsgValue*)(msg);
+ var d = (SpiceProtocol.Controller.MsgData*)(msg);
+ unowned string str = (string)(&d.data);
+
+ switch (msg.id) {
+ case SpiceProtocol.Controller.MsgId.HOST:
+ host = str;
+ debug ("got HOST: %s".printf (str));
+ break;
+ case SpiceProtocol.Controller.MsgId.PORT:
+ port = v.value;
+ debug ("got PORT: %u".printf (port));
+ break;
+ case SpiceProtocol.Controller.MsgId.SPORT:
+ sport = v.value;
+ debug ("got SPORT: %u".printf (sport));
+ break;
+ case SpiceProtocol.Controller.MsgId.PASSWORD:
+ password = str;
+ debug ("got PASSWORD");
+ break;
+
+ case SpiceProtocol.Controller.MsgId.SECURE_CHANNELS:
+ secure_channels = str.split(",");
+ debug ("got SECURE_CHANNELS %s".printf (str));
+ break;
+
+ case SpiceProtocol.Controller.MsgId.DISABLE_CHANNELS:
+ disable_channels = str.split(",");
+ debug ("got DISABLE_CHANNELS %s".printf (str));
+ break;
+
+ case SpiceProtocol.Controller.MsgId.TLS_CIPHERS:
+ tls_ciphers = str;
+ debug ("got TLS_CIPHERS %s".printf (str));
+ break;
+ case SpiceProtocol.Controller.MsgId.CA_FILE:
+ ca_file = str;
+ debug ("got CA_FILE %s".printf (str));
+ break;
+ case SpiceProtocol.Controller.MsgId.HOST_SUBJECT:
+ host_subject = str;
+ debug ("got HOST_SUBJECT %s".printf (str));
+ break;
+
+ case SpiceProtocol.Controller.MsgId.FULL_SCREEN:
+ display_flags = (SpiceProtocol.Controller.Display)v.value;
+ debug ("got FULL_SCREEN 0x%x".printf (v.value));
+ break;
+ case SpiceProtocol.Controller.MsgId.SET_TITLE:
+ title = str;
+ debug ("got TITLE %s".printf (str));
+ break;
+ case SpiceProtocol.Controller.MsgId.ENABLE_SMARTCARD:
+ enable_smartcard = (bool)v.value;
+ debug ("got ENABLE_SMARTCARD 0x%x".printf (v.value));
+ break;
+
+ case SpiceProtocol.Controller.MsgId.CREATE_MENU:
+ menu = new SpiceCtrl.Menu.from_string (str);
+ debug ("got CREATE_MENU %s".printf (str));
+ break;
+ case SpiceProtocol.Controller.MsgId.DELETE_MENU:
+ menu = null;
+ debug ("got DELETE_MENU request");
+ break;
+
+ case SpiceProtocol.Controller.MsgId.SEND_CAD:
+ send_cad = (bool)v.value;
+ debug ("got SEND_CAD %u".printf (v.value));
+ break;
+
+ case SpiceProtocol.Controller.MsgId.HOTKEYS:
+ hotkeys = str;
+ debug ("got HOTKEYS %s".printf (str));
+ break;
+
+ case SpiceProtocol.Controller.MsgId.COLOR_DEPTH:
+ color_depth = v.value;
+ debug ("got COLOR_DEPTH %u".printf (v.value));
+ break;
+ case SpiceProtocol.Controller.MsgId.DISABLE_EFFECTS:
+ disable_effects = str.split(",");
+ debug ("got DISABLE_EFFECTS %s".printf (str));
+ break;
+
+ case SpiceProtocol.Controller.MsgId.CONNECT:
+ do_connect ();
+ debug ("got CONNECT request");
+ break;
+ case SpiceProtocol.Controller.MsgId.SHOW:
+ show ();
+ debug ("got SHOW request");
+ break;
+ case SpiceProtocol.Controller.MsgId.HIDE:
+ hide ();
+ debug ("got HIDE request");
+ break;
+ case SpiceProtocol.Controller.MsgId.ENABLE_USB:
+ enable_usbredir = (bool)v.value;
+ debug ("got ENABLE_USB %u".printf (v.value));
+ break;
+ case SpiceProtocol.Controller.MsgId.ENABLE_USB_AUTOSHARE:
+ enable_usb_autoshare = (bool)v.value;
+ debug ("got ENABLE_USB_AUTOSHARE %u".printf (v.value));
+ break;
+ case SpiceProtocol.Controller.MsgId.USB_FILTER:
+ usb_filter = str;
+ debug ("got USB_FILTER %s".printf (str));
+ break;
+ case SpiceProtocol.Controller.MsgId.PROXY:
+ proxy = str;
+ debug ("got PROXY %s".printf (str));
+ break;
+ default:
+ debug ("got unknown msg.id %u".printf (msg.id));
+ warn_if_reached ();
+ return false;
+ }
+ return true;
+ }
+
+ private async void handle_client (IOStream c) throws GLib.Error {
+ var excl = false;
+
+ debug ("new socket client, reading init header");
+
+ var p = new uint8[sizeof(SpiceProtocol.Controller.Init)];
+ var init = (SpiceProtocol.Controller.Init*)p;
+ yield input_stream_read (c.input_stream, p);
+ if (warn_if (init.base.magic != SpiceProtocol.Controller.MAGIC))
+ return;
+ if (warn_if (init.base.version != SpiceProtocol.Controller.VERSION))
+ return;
+ if (warn_if (init.base.size < sizeof (SpiceProtocol.Controller.Init)))
+ return;
+ if (warn_if (init.credentials != 0))
+ return;
+ if (warn_if (excl_connection != null))
+ return;
+
+ excl = (bool)(init.flags & SpiceProtocol.Controller.Flag.EXCLUSIVE);
+ if (excl) {
+ if (nclients > 1) {
+ warning (@"Can't make the client exclusive, there is already $nclients connected clients");
+ return;
+ }
+ excl_connection = c;
+ }
+
+ client_connected ();
+
+ for (;;) {
+ var t = new uint8[sizeof(SpiceProtocol.Controller.Msg)];
+ yield input_stream_read (c.input_stream, t);
+ var msg = (SpiceProtocol.Controller.Msg*)t;
+ debug ("new message " + msg.id.to_string () + "size " + msg.size.to_string ());
+ if (warn_if (msg.size < sizeof (SpiceProtocol.Controller.Msg)))
+ break;
+
+ if (msg.size > sizeof (SpiceProtocol.Controller.Msg)) {
+ t.resize ((int)msg.size);
+ msg = (SpiceProtocol.Controller.Msg*)t;
+ yield input_stream_read (c.input_stream, t[sizeof(SpiceProtocol.Controller.Msg):msg.size]);
+ }
+
+ handle_message (msg);
+ }
+
+ if (excl)
+ excl_connection = null;
+ }
+
+ public Controller() {
+ }
+
+ public async void listen (string? addr = null) throws GLib.Error, SpiceCtrl.Error
+ {
+ var listener = ControllerListener.new_listener (addr);
+
+ for (;;) {
+ var c = yield listener.accept_async ();
+ nclients += 1;
+ clients.append (c);
+ try {
+ yield handle_client (c);
+ } catch (GLib.Error e) {
+ warning (e.message);
+ }
+ c.close ();
+ clients.remove (c);
+ nclients -= 1;
+ }
+ }
+}
+
+} // SpiceCtrl
--- /dev/null
+#ifndef CUSTOM_H_
+#define CUSTOM_H_
+
+#include <glib.h>
+
+static inline gboolean g_warn_if_expr (gboolean condition,
+ const char *pretty_func,
+ const char *expression) {
+ if G_UNLIKELY(condition) {
+ g_log (G_LOG_DOMAIN,
+ G_LOG_LEVEL_CRITICAL,
+ "%s: `%s' condition reached",
+ pretty_func,
+ expression);
+ }
+
+ return condition;
+}
+
+#define g_warn_if(expr) g_warn_if_expr((expr), __PRETTY_FUNCTION__, #expr)
+
+#endif
--- /dev/null
+using GLib;
+
+namespace Custom {
+
+ [CCode (cname = "g_warn_if", cheader_filename = "custom.h")]
+ public bool warn_if(bool condition);
+}
+
+namespace Spice {
+
+ [CCode (cname = "GObject", ref_function = "g_object_ref", unref_function = "g_object_unref", free_function = "")]
+ class ControllerListener {
+ [CCode (cname = "spice_controller_listener_new", cheader_filename = "spice-controller-listener.h")]
+ public static ControllerListener new_listener (string addr) throws GLib.Error;
+
+ [CCode (cname = "spice_controller_listener_accept_async", cheader_filename = "spice-controller-listener.h")]
+ public async unowned GLib.IOStream accept_async (GLib.Cancellable? cancellable = null, out GLib.Object? source_object = null) throws GLib.Error;
+ }
+
+ [CCode (cname = "GObject", ref_function = "g_object_ref", unref_function = "g_object_unref", free_function = "")]
+ class ForeignMenuListener {
+ [CCode (cname = "spice_foreign_menu_listener_new", cheader_filename = "spice-foreign-menu-listener.h")]
+ public static ForeignMenuListener new_listener (string addr) throws GLib.Error;
+
+ [CCode (cname = "spice_foreign_menu_listener_accept_async", cheader_filename = "spice-foreign-menu-listener.h")]
+ public async unowned GLib.IOStream accept_async (GLib.Cancellable? cancellable = null, out GLib.Object? source_object = null) throws GLib.Error;
+ }
+}
--- /dev/null
+/* Copyright (C) 2011 Red Hat, Inc. */
+
+/* This library is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU Lesser General Public */
+/* License as published by the Free Software Foundation; either */
+/* version 2.1 of the License, or (at your option) any later version. */
+
+/* This library is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* Lesser General Public License for more details. */
+
+/* You should have received a copy of the GNU Lesser General Public */
+/* License along with this library; if not, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdint.h>
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <sys/socket.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <sys/un.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#endif
+
+#include "spice-controller.h"
+
+SpiceCtrlController *ctrl = NULL;
+SpiceCtrlForeignMenu *menu = NULL;
+GMainLoop *loop = NULL;
+
+void signaled (GObject *gobject, const gchar *signal_name)
+{
+ g_message ("signaled: %s", signal_name);
+}
+
+void notified (GObject *gobject, GParamSpec *pspec,
+ gpointer user_data)
+{
+ GValue value = { 0, };
+ GValue strvalue = { 0, };
+
+ g_return_if_fail (gobject != NULL);
+ g_return_if_fail (pspec != NULL);
+
+ g_value_init (&value, pspec->value_type);
+ g_value_init (&strvalue, G_TYPE_STRING);
+ g_object_get_property (gobject, pspec->name, &value);
+
+ if (pspec->value_type == G_TYPE_STRV) {
+ gchar** p = (gchar **)g_value_get_boxed (&value);
+ g_message ("notify::%s == ", pspec->name);
+ while (*p)
+ g_message ("%s", *p++);
+ } else if (G_TYPE_IS_OBJECT(pspec->value_type)) {
+ GObject *o = g_value_get_object (&value);
+ g_message ("notify::%s == %s", pspec->name, o ? G_OBJECT_TYPE_NAME (o) : "null");
+ } else {
+ g_value_transform (&value, &strvalue);
+ g_message ("notify::%s = %s", pspec->name, g_value_get_string (&strvalue));
+ }
+
+ g_value_unset (&value);
+ g_value_unset (&strvalue);
+}
+
+void connect_signals (gpointer obj)
+{
+ guint i, n_ids = 0;
+ guint *ids = NULL;
+ GType type = G_OBJECT_TYPE (obj);
+
+ ids = g_signal_list_ids (type, &n_ids);
+ for (i = 0; i < n_ids; i++) {
+ const gchar *name = g_signal_name (ids[i]);
+ g_signal_connect (obj, name, G_CALLBACK (signaled), (gpointer)name);
+ }
+}
+
+int main (int argc, char *argv[])
+{
+ loop = g_main_loop_new (NULL, FALSE);
+
+ if (argc > 1 && g_str_equal(argv[1], "--menu")) {
+ menu = spice_ctrl_foreign_menu_new ();
+ g_signal_connect (menu, "notify", G_CALLBACK (notified), NULL);
+ connect_signals (menu);
+
+ spice_ctrl_foreign_menu_listen (menu, NULL, NULL, NULL);
+ } else {
+ ctrl = spice_ctrl_controller_new ();
+ g_signal_connect (ctrl, "notify", G_CALLBACK (notified), NULL);
+ connect_signals (ctrl);
+
+ spice_ctrl_controller_listen (ctrl, NULL, NULL, NULL);
+ }
+
+ g_main_loop_run (loop);
+
+ if (ctrl != NULL)
+ g_object_unref (ctrl);
+ if (menu != NULL)
+ g_object_unref (menu);
+
+ return 0;
+}
--- /dev/null
+/* foreign-menu.c generated by valac 0.32.1, the Vala compiler
+ * generated from foreign-menu.vala, do not modify */
+
+/* Copyright (C) 2012 Red Hat, Inc.*/
+/* This library is free software; you can redistribute it and/or*/
+/* modify it under the terms of the GNU Lesser General Public*/
+/* License as published by the Free Software Foundation; either*/
+/* version 2.1 of the License, or (at your option) any later version.*/
+/* This library is distributed in the hope that it will be useful,*/
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU*/
+/* Lesser General Public License for more details.*/
+/* You should have received a copy of the GNU Lesser General Public*/
+/* License along with this library; if not, see <http://www.gnu.org/licenses/>.*/
+
+#include <glib.h>
+#include <glib-object.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gio/gio.h>
+#include <spice/foreign_menu_prot.h>
+#include <spice/controller_prot.h>
+#include <custom.h>
+#include <spice-foreign-menu-listener.h>
+
+
+#define SPICE_CTRL_TYPE_FOREIGN_MENU (spice_ctrl_foreign_menu_get_type ())
+#define SPICE_CTRL_FOREIGN_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_CTRL_TYPE_FOREIGN_MENU, SpiceCtrlForeignMenu))
+#define SPICE_CTRL_FOREIGN_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_CTRL_TYPE_FOREIGN_MENU, SpiceCtrlForeignMenuClass))
+#define SPICE_CTRL_IS_FOREIGN_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_CTRL_TYPE_FOREIGN_MENU))
+#define SPICE_CTRL_IS_FOREIGN_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_CTRL_TYPE_FOREIGN_MENU))
+#define SPICE_CTRL_FOREIGN_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_CTRL_TYPE_FOREIGN_MENU, SpiceCtrlForeignMenuClass))
+
+typedef struct _SpiceCtrlForeignMenu SpiceCtrlForeignMenu;
+typedef struct _SpiceCtrlForeignMenuClass SpiceCtrlForeignMenuClass;
+typedef struct _SpiceCtrlForeignMenuPrivate SpiceCtrlForeignMenuPrivate;
+
+#define SPICE_CTRL_TYPE_MENU (spice_ctrl_menu_get_type ())
+#define SPICE_CTRL_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_CTRL_TYPE_MENU, SpiceCtrlMenu))
+#define SPICE_CTRL_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_CTRL_TYPE_MENU, SpiceCtrlMenuClass))
+#define SPICE_CTRL_IS_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_CTRL_TYPE_MENU))
+#define SPICE_CTRL_IS_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_CTRL_TYPE_MENU))
+#define SPICE_CTRL_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_CTRL_TYPE_MENU, SpiceCtrlMenuClass))
+
+typedef struct _SpiceCtrlMenu SpiceCtrlMenu;
+typedef struct _SpiceCtrlMenuClass SpiceCtrlMenuClass;
+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
+#define _g_free0(var) (var = (g_free (var), NULL))
+#define __g_list_free__g_object_unref0_0(var) ((var == NULL) ? NULL : (var = (_g_list_free__g_object_unref0_ (var), NULL)))
+#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
+typedef struct _SpiceCtrlForeignMenuSendMsgData SpiceCtrlForeignMenuSendMsgData;
+typedef struct _SpiceCtrlMenuPrivate SpiceCtrlMenuPrivate;
+
+#define SPICE_CTRL_TYPE_MENU_ITEM (spice_ctrl_menu_item_get_type ())
+#define SPICE_CTRL_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_CTRL_TYPE_MENU_ITEM, SpiceCtrlMenuItem))
+#define SPICE_CTRL_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_CTRL_TYPE_MENU_ITEM, SpiceCtrlMenuItemClass))
+#define SPICE_CTRL_IS_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_CTRL_TYPE_MENU_ITEM))
+#define SPICE_CTRL_IS_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_CTRL_TYPE_MENU_ITEM))
+#define SPICE_CTRL_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_CTRL_TYPE_MENU_ITEM, SpiceCtrlMenuItemClass))
+
+typedef struct _SpiceCtrlMenuItem SpiceCtrlMenuItem;
+typedef struct _SpiceCtrlMenuItemClass SpiceCtrlMenuItemClass;
+typedef struct _SpiceCtrlForeignMenuHandleClientData SpiceCtrlForeignMenuHandleClientData;
+typedef struct _SpiceCtrlForeignMenuListenData SpiceCtrlForeignMenuListenData;
+
+struct _SpiceCtrlForeignMenu {
+ GObject parent_instance;
+ SpiceCtrlForeignMenuPrivate * priv;
+};
+
+struct _SpiceCtrlForeignMenuClass {
+ GObjectClass parent_class;
+};
+
+struct _SpiceCtrlForeignMenuPrivate {
+ SpiceCtrlMenu* _menu;
+ gchar* _title;
+ gint nclients;
+ GList* clients;
+};
+
+struct _SpiceCtrlForeignMenuSendMsgData {
+ int _state_;
+ GObject* _source_object_;
+ GAsyncResult* _res_;
+ GSimpleAsyncResult* _async_result;
+ SpiceCtrlForeignMenu* self;
+ guint8* p;
+ gint p_length1;
+ gboolean result;
+ GList* _tmp0_;
+ GList* c_collection;
+ GList* c_it;
+ GIOStream* _tmp1_;
+ GIOStream* c;
+ GIOStream* _tmp2_;
+ GOutputStream* _tmp3_;
+ GOutputStream* _tmp4_;
+ guint8* _tmp5_;
+ gint _tmp5__length1;
+ guint8* _tmp6_;
+ gint _tmp6__length1;
+ GError* e;
+ GError* _tmp7_;
+ const gchar* _tmp8_;
+ GError * _inner_error_;
+};
+
+struct _SpiceCtrlMenu {
+ GObject parent_instance;
+ SpiceCtrlMenuPrivate * priv;
+ GList* items;
+};
+
+struct _SpiceCtrlMenuClass {
+ GObjectClass parent_class;
+};
+
+struct _SpiceCtrlForeignMenuHandleClientData {
+ int _state_;
+ GObject* _source_object_;
+ GAsyncResult* _res_;
+ GSimpleAsyncResult* _async_result;
+ SpiceCtrlForeignMenu* self;
+ GIOStream* c;
+ guint8* p;
+ guint8* _tmp0_;
+ gint p_length1;
+ gint _p_size_;
+ FrgMenuInitHeader* header;
+ guint8* _tmp1_;
+ gint _tmp1__length1;
+ GIOStream* _tmp2_;
+ GInputStream* _tmp3_;
+ GInputStream* _tmp4_;
+ guint8* _tmp5_;
+ gint _tmp5__length1;
+ FrgMenuInitHeader* _tmp6_;
+ guint32 _tmp7_;
+ gboolean _tmp8_;
+ FrgMenuInitHeader* _tmp9_;
+ guint32 _tmp10_;
+ gboolean _tmp11_;
+ FrgMenuInitHeader* _tmp12_;
+ guint32 _tmp13_;
+ gboolean _tmp14_;
+ guint8* cp;
+ guint8* _tmp15_;
+ gint cp_length1;
+ gint _cp_size_;
+ GIOStream* _tmp16_;
+ GInputStream* _tmp17_;
+ GInputStream* _tmp18_;
+ guint8* _tmp19_;
+ gint _tmp19__length1;
+ guint64 credentials;
+ guint8* _tmp20_;
+ gint _tmp20__length1;
+ guint64 _tmp21_;
+ gboolean _tmp22_;
+ gulong title_size;
+ FrgMenuInitHeader* _tmp23_;
+ guint32 _tmp24_;
+ guint8* title;
+ gulong _tmp25_;
+ guint8* _tmp26_;
+ gint title_length1;
+ gint _title_size_;
+ GIOStream* _tmp27_;
+ GInputStream* _tmp28_;
+ GInputStream* _tmp29_;
+ guint8* _tmp30_;
+ gint _tmp30__length1;
+ gulong _tmp31_;
+ guint8* _tmp32_;
+ gint _tmp32__length1;
+ gboolean _tmp33_;
+ guint8* t;
+ guint8* _tmp34_;
+ gint t_length1;
+ gint _t_size_;
+ GIOStream* _tmp35_;
+ GInputStream* _tmp36_;
+ GInputStream* _tmp37_;
+ guint8* _tmp38_;
+ gint _tmp38__length1;
+ FrgMenuMsg* msg;
+ guint8* _tmp39_;
+ gint _tmp39__length1;
+ FrgMenuMsg* _tmp40_;
+ guint32 _tmp41_;
+ gchar* _tmp42_;
+ gchar* _tmp43_;
+ gchar* _tmp44_;
+ gchar* _tmp45_;
+ gchar* _tmp46_;
+ gchar* _tmp47_;
+ FrgMenuMsg* _tmp48_;
+ guint32 _tmp49_;
+ gchar* _tmp50_;
+ gchar* _tmp51_;
+ gchar* _tmp52_;
+ gchar* _tmp53_;
+ FrgMenuMsg* _tmp54_;
+ guint32 _tmp55_;
+ gboolean _tmp56_;
+ FrgMenuMsg* _tmp57_;
+ guint32 _tmp58_;
+ FrgMenuMsg* _tmp59_;
+ guint32 _tmp60_;
+ gint _tmp61_;
+ guint8* _tmp62_;
+ gint _tmp62__length1;
+ GIOStream* _tmp63_;
+ GInputStream* _tmp64_;
+ GInputStream* _tmp65_;
+ guint8* _tmp66_;
+ gint _tmp66__length1;
+ FrgMenuMsg* _tmp67_;
+ guint32 _tmp68_;
+ FrgMenuMsg* _tmp69_;
+ GError * _inner_error_;
+};
+
+typedef enum {
+ SPICE_CTRL_ERROR_VALUE
+} SpiceCtrlError;
+#define SPICE_CTRL_ERROR spice_ctrl_error_quark ()
+struct _SpiceCtrlForeignMenuListenData {
+ int _state_;
+ GObject* _source_object_;
+ GAsyncResult* _res_;
+ GSimpleAsyncResult* _async_result;
+ SpiceCtrlForeignMenu* self;
+ gchar* addr;
+ GObject* listener;
+ const gchar* _tmp0_;
+ GObject* _tmp1_;
+ gboolean _tmp2_;
+ GIOStream* c;
+ GObject* _tmp3_;
+ GIOStream* _tmp4_;
+ GIOStream* _tmp5_;
+ gint _tmp6_;
+ GIOStream* _tmp7_;
+ GIOStream* _tmp8_;
+ GIOStream* _tmp9_;
+ GError* e;
+ GError* _tmp10_;
+ const gchar* _tmp11_;
+ GIOStream* _tmp12_;
+ GIOStream* _tmp13_;
+ gint _tmp14_;
+ GError * _inner_error_;
+};
+
+
+static gpointer spice_ctrl_foreign_menu_parent_class = NULL;
+
+GType spice_ctrl_foreign_menu_get_type (void) G_GNUC_CONST;
+GType spice_ctrl_menu_get_type (void) G_GNUC_CONST;
+#define SPICE_CTRL_FOREIGN_MENU_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SPICE_CTRL_TYPE_FOREIGN_MENU, SpiceCtrlForeignMenuPrivate))
+enum {
+ SPICE_CTRL_FOREIGN_MENU_DUMMY_PROPERTY,
+ SPICE_CTRL_FOREIGN_MENU_MENU,
+ SPICE_CTRL_FOREIGN_MENU_TITLE
+};
+static void _g_object_unref0_ (gpointer var);
+static void _g_list_free__g_object_unref0_ (GList* self);
+SpiceCtrlForeignMenu* spice_ctrl_foreign_menu_new (void);
+SpiceCtrlForeignMenu* spice_ctrl_foreign_menu_construct (GType object_type);
+SpiceCtrlMenu* spice_ctrl_menu_new (void);
+SpiceCtrlMenu* spice_ctrl_menu_construct (GType object_type);
+static void spice_ctrl_foreign_menu_set_menu (SpiceCtrlForeignMenu* self, SpiceCtrlMenu* value);
+void spice_ctrl_foreign_menu_menu_item_click_msg (SpiceCtrlForeignMenu* self, gint32 item_id);
+void spice_ctrl_foreign_menu_send_msg (SpiceCtrlForeignMenu* self, guint8* p, int p_length1, GAsyncReadyCallback _callback_, gpointer _user_data_);
+gboolean spice_ctrl_foreign_menu_send_msg_finish (SpiceCtrlForeignMenu* self, GAsyncResult* _res_, GError** error);
+static guint8* _vala_array_dup6 (guint8* self, int length);
+void spice_ctrl_foreign_menu_menu_item_checked_msg (SpiceCtrlForeignMenu* self, gint32 item_id, gboolean checked);
+static guint8* _vala_array_dup7 (guint8* self, int length);
+void spice_ctrl_foreign_menu_app_activated_msg (SpiceCtrlForeignMenu* self, gboolean activated);
+static guint8* _vala_array_dup8 (guint8* self, int length);
+static void spice_ctrl_foreign_menu_send_msg_data_free (gpointer _data);
+static gboolean spice_ctrl_foreign_menu_send_msg_co (SpiceCtrlForeignMenuSendMsgData* _data_);
+void spice_ctrl_output_stream_write (GOutputStream* stream, guint8* buffer, int buffer_length1, GAsyncReadyCallback _callback_, gpointer _user_data_);
+void spice_ctrl_output_stream_write_finish (GAsyncResult* _res_, GError** error);
+static guint8* _vala_array_dup9 (guint8* self, int length);
+static void spice_ctrl_foreign_menu_send_msg_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
+static unsigned int spice_ctrl_foreign_menu_get_menu_flags (SpiceCtrlForeignMenu* self, guint32 type);
+static gboolean spice_ctrl_foreign_menu_handle_message (SpiceCtrlForeignMenu* self, FrgMenuMsg* msg);
+static void spice_ctrl_foreign_menu_set_title (SpiceCtrlForeignMenu* self, const gchar* value);
+SpiceCtrlMenu* spice_ctrl_foreign_menu_get_menu (SpiceCtrlForeignMenu* self);
+GType spice_ctrl_menu_item_get_type (void) G_GNUC_CONST;
+SpiceCtrlMenuItem* spice_ctrl_menu_item_new (gint id, const gchar* text, unsigned int flags);
+SpiceCtrlMenuItem* spice_ctrl_menu_item_construct (GType object_type, gint id, const gchar* text, unsigned int flags);
+static void spice_ctrl_foreign_menu_handle_client_data_free (gpointer _data);
+static void spice_ctrl_foreign_menu_handle_client (SpiceCtrlForeignMenu* self, GIOStream* c, GAsyncReadyCallback _callback_, gpointer _user_data_);
+static void spice_ctrl_foreign_menu_handle_client_finish (SpiceCtrlForeignMenu* self, GAsyncResult* _res_, GError** error);
+static gboolean spice_ctrl_foreign_menu_handle_client_co (SpiceCtrlForeignMenuHandleClientData* _data_);
+void spice_ctrl_input_stream_read (GInputStream* stream, guint8* buffer, int buffer_length1, GAsyncReadyCallback _callback_, gpointer _user_data_);
+void spice_ctrl_input_stream_read_finish (GAsyncResult* _res_, GError** error);
+static void spice_ctrl_foreign_menu_handle_client_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
+static void spice_ctrl_foreign_menu_listen_data_free (gpointer _data);
+GQuark spice_ctrl_error_quark (void);
+void spice_ctrl_foreign_menu_listen (SpiceCtrlForeignMenu* self, const gchar* addr, GAsyncReadyCallback _callback_, gpointer _user_data_);
+void spice_ctrl_foreign_menu_listen_finish (SpiceCtrlForeignMenu* self, GAsyncResult* _res_, GError** error);
+static gboolean spice_ctrl_foreign_menu_listen_co (SpiceCtrlForeignMenuListenData* _data_);
+static void spice_ctrl_foreign_menu_listen_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
+const gchar* spice_ctrl_foreign_menu_get_title (SpiceCtrlForeignMenu* self);
+static void spice_ctrl_foreign_menu_finalize (GObject* obj);
+static void _vala_spice_ctrl_foreign_menu_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec);
+static void _vala_spice_ctrl_foreign_menu_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec);
+
+
+static void _g_object_unref0_ (gpointer var) {
+ (var == NULL) ? NULL : (var = (g_object_unref (var), NULL));
+}
+
+
+static void _g_list_free__g_object_unref0_ (GList* self) {
+ g_list_foreach (self, (GFunc) _g_object_unref0_, NULL);
+ g_list_free (self);
+}
+
+
+SpiceCtrlForeignMenu* spice_ctrl_foreign_menu_construct (GType object_type) {
+ SpiceCtrlForeignMenu * self = NULL;
+ SpiceCtrlMenu* _tmp0_ = NULL;
+ SpiceCtrlMenu* _tmp1_ = NULL;
+ self = (SpiceCtrlForeignMenu*) g_object_new (object_type, NULL);
+ _tmp0_ = spice_ctrl_menu_new ();
+ _tmp1_ = _tmp0_;
+ spice_ctrl_foreign_menu_set_menu (self, _tmp1_);
+ _g_object_unref0 (_tmp1_);
+ return self;
+}
+
+
+SpiceCtrlForeignMenu* spice_ctrl_foreign_menu_new (void) {
+ return spice_ctrl_foreign_menu_construct (SPICE_CTRL_TYPE_FOREIGN_MENU);
+}
+
+
+static guint8* _vala_array_dup6 (guint8* self, int length) {
+ return g_memdup (self, length * sizeof (guint8));
+}
+
+
+void spice_ctrl_foreign_menu_menu_item_click_msg (SpiceCtrlForeignMenu* self, gint32 item_id) {
+ gint32 _tmp0_ = 0;
+ gchar* _tmp1_ = NULL;
+ gchar* _tmp2_ = NULL;
+ FrgMenuEvent msg = {0};
+ gint32 _tmp3_ = 0;
+ guint8* p = NULL;
+ FrgMenuEvent _tmp4_ = {0};
+ FrgMenuMsg _tmp5_ = {0};
+ guint32 _tmp6_ = 0U;
+ gint p_length1 = 0;
+ gint _p_size_ = 0;
+ guint8* _tmp7_ = NULL;
+ gint _tmp7__length1 = 0;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = item_id;
+ _tmp1_ = g_strdup_printf ("clicked id: %d", (gint) _tmp0_);
+ _tmp2_ = _tmp1_;
+ g_debug ("foreign-menu.vala:35: %s", _tmp2_);
+ _g_free0 (_tmp2_);
+ memset (&msg, 0, sizeof (FrgMenuEvent));
+ msg.base.size = (guint32) sizeof (FrgMenuEvent);
+ msg.base.id = (guint32) FOREIGN_MENU_ITEM_EVENT;
+ _tmp3_ = item_id;
+ msg.id = (guint32) _tmp3_;
+ msg.action = (guint32) FOREIGN_MENU_EVENT_CLICK;
+ _tmp4_ = msg;
+ _tmp5_ = _tmp4_.base;
+ _tmp6_ = _tmp5_.size;
+ p = ((guint8*) (&msg)) + 0;
+ p_length1 = ((gint) _tmp6_) - 0;
+ _p_size_ = p_length1;
+ _tmp7_ = (p != NULL) ? _vala_array_dup6 (p, p_length1) : ((gpointer) p);
+ _tmp7__length1 = p_length1;
+ spice_ctrl_foreign_menu_send_msg (self, _tmp7_, _tmp7__length1, NULL, NULL);
+}
+
+
+static guint8* _vala_array_dup7 (guint8* self, int length) {
+ return g_memdup (self, length * sizeof (guint8));
+}
+
+
+void spice_ctrl_foreign_menu_menu_item_checked_msg (SpiceCtrlForeignMenu* self, gint32 item_id, gboolean checked) {
+ const gchar* _tmp0_ = NULL;
+ gboolean _tmp1_ = FALSE;
+ gint32 _tmp2_ = 0;
+ gchar* _tmp3_ = NULL;
+ gchar* _tmp4_ = NULL;
+ FrgMenuEvent msg = {0};
+ gint32 _tmp5_ = 0;
+ int _tmp6_ = 0;
+ gboolean _tmp7_ = FALSE;
+ guint8* p = NULL;
+ FrgMenuEvent _tmp8_ = {0};
+ FrgMenuMsg _tmp9_ = {0};
+ guint32 _tmp10_ = 0U;
+ gint p_length1 = 0;
+ gint _p_size_ = 0;
+ guint8* _tmp11_ = NULL;
+ gint _tmp11__length1 = 0;
+ g_return_if_fail (self != NULL);
+ _tmp1_ = checked;
+ if (_tmp1_) {
+ _tmp0_ = "";
+ } else {
+ _tmp0_ = "un";
+ }
+ _tmp2_ = item_id;
+ _tmp3_ = g_strdup_printf ("%schecked id: %d", _tmp0_, (gint) _tmp2_);
+ _tmp4_ = _tmp3_;
+ g_debug ("foreign-menu.vala:48: %s", _tmp4_);
+ _g_free0 (_tmp4_);
+ memset (&msg, 0, sizeof (FrgMenuEvent));
+ msg.base.size = (guint32) sizeof (FrgMenuEvent);
+ msg.base.id = (guint32) FOREIGN_MENU_ITEM_EVENT;
+ _tmp5_ = item_id;
+ msg.id = (guint32) _tmp5_;
+ _tmp7_ = checked;
+ if (_tmp7_) {
+ _tmp6_ = FOREIGN_MENU_EVENT_CHECKED;
+ } else {
+ _tmp6_ = FOREIGN_MENU_EVENT_UNCHECKED;
+ }
+ msg.action = (guint32) _tmp6_;
+ _tmp8_ = msg;
+ _tmp9_ = _tmp8_.base;
+ _tmp10_ = _tmp9_.size;
+ p = ((guint8*) (&msg)) + 0;
+ p_length1 = ((gint) _tmp10_) - 0;
+ _p_size_ = p_length1;
+ _tmp11_ = (p != NULL) ? _vala_array_dup7 (p, p_length1) : ((gpointer) p);
+ _tmp11__length1 = p_length1;
+ spice_ctrl_foreign_menu_send_msg (self, _tmp11_, _tmp11__length1, NULL, NULL);
+}
+
+
+static guint8* _vala_array_dup8 (guint8* self, int length) {
+ return g_memdup (self, length * sizeof (guint8));
+}
+
+
+void spice_ctrl_foreign_menu_app_activated_msg (SpiceCtrlForeignMenu* self, gboolean activated) {
+ FrgMenuMsg msg = {0};
+ int _tmp0_ = 0;
+ gboolean _tmp1_ = FALSE;
+ guint8* p = NULL;
+ FrgMenuMsg _tmp2_ = {0};
+ guint32 _tmp3_ = 0U;
+ gint p_length1 = 0;
+ gint _p_size_ = 0;
+ guint8* _tmp4_ = NULL;
+ gint _tmp4__length1 = 0;
+ g_return_if_fail (self != NULL);
+ memset (&msg, 0, sizeof (FrgMenuMsg));
+ msg.size = (guint32) sizeof (FrgMenuEvent);
+ _tmp1_ = activated;
+ if (_tmp1_) {
+ _tmp0_ = FOREIGN_MENU_APP_ACTIVATED;
+ } else {
+ _tmp0_ = FOREIGN_MENU_APP_DEACTIVATED;
+ }
+ msg.id = (guint32) _tmp0_;
+ _tmp2_ = msg;
+ _tmp3_ = _tmp2_.size;
+ p = ((guint8*) (&msg)) + 0;
+ p_length1 = ((gint) _tmp3_) - 0;
+ _p_size_ = p_length1;
+ _tmp4_ = (p != NULL) ? _vala_array_dup8 (p, p_length1) : ((gpointer) p);
+ _tmp4__length1 = p_length1;
+ spice_ctrl_foreign_menu_send_msg (self, _tmp4_, _tmp4__length1, NULL, NULL);
+}
+
+
+static void spice_ctrl_foreign_menu_send_msg_data_free (gpointer _data) {
+ SpiceCtrlForeignMenuSendMsgData* _data_;
+ _data_ = _data;
+ _data_->p = (g_free (_data_->p), NULL);
+ _g_object_unref0 (_data_->self);
+ g_slice_free (SpiceCtrlForeignMenuSendMsgData, _data_);
+}
+
+
+static gpointer _g_object_ref0 (gpointer self) {
+ return self ? g_object_ref (self) : NULL;
+}
+
+
+void spice_ctrl_foreign_menu_send_msg (SpiceCtrlForeignMenu* self, guint8* p, int p_length1, GAsyncReadyCallback _callback_, gpointer _user_data_) {
+ SpiceCtrlForeignMenuSendMsgData* _data_;
+ SpiceCtrlForeignMenu* _tmp0_ = NULL;
+ _data_ = g_slice_new0 (SpiceCtrlForeignMenuSendMsgData);
+ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, spice_ctrl_foreign_menu_send_msg);
+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, spice_ctrl_foreign_menu_send_msg_data_free);
+ _tmp0_ = _g_object_ref0 (self);
+ _data_->self = _tmp0_;
+ _data_->p = (g_free (_data_->p), NULL);
+ _data_->p = p;
+ _data_->p_length1 = p_length1;
+ spice_ctrl_foreign_menu_send_msg_co (_data_);
+}
+
+
+gboolean spice_ctrl_foreign_menu_send_msg_finish (SpiceCtrlForeignMenu* self, GAsyncResult* _res_, GError** error) {
+ gboolean result;
+ SpiceCtrlForeignMenuSendMsgData* _data_;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
+ return FALSE;
+ }
+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
+ result = _data_->result;
+ return result;
+}
+
+
+static guint8* _vala_array_dup9 (guint8* self, int length) {
+ return g_memdup (self, length * sizeof (guint8));
+}
+
+
+static void spice_ctrl_foreign_menu_send_msg_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
+ SpiceCtrlForeignMenuSendMsgData* _data_;
+ _data_ = _user_data_;
+ _data_->_source_object_ = source_object;
+ _data_->_res_ = _res_;
+ spice_ctrl_foreign_menu_send_msg_co (_data_);
+}
+
+
+static gboolean spice_ctrl_foreign_menu_send_msg_co (SpiceCtrlForeignMenuSendMsgData* _data_) {
+ switch (_data_->_state_) {
+ case 0:
+ goto _state_0;
+ case 1:
+ goto _state_1;
+ default:
+ g_assert_not_reached ();
+ }
+ _state_0:
+ {
+ _data_->_tmp0_ = NULL;
+ _data_->_tmp0_ = _data_->self->priv->clients;
+ {
+ _data_->c_collection = _data_->_tmp0_;
+ for (_data_->c_it = _data_->c_collection; _data_->c_it != NULL; _data_->c_it = _data_->c_it->next) {
+ _data_->_tmp1_ = NULL;
+ _data_->_tmp1_ = _g_object_ref0 ((GIOStream*) _data_->c_it->data);
+ _data_->c = _data_->_tmp1_;
+ {
+ _data_->_tmp2_ = NULL;
+ _data_->_tmp2_ = _data_->c;
+ _data_->_tmp3_ = NULL;
+ _data_->_tmp3_ = g_io_stream_get_output_stream (_data_->_tmp2_);
+ _data_->_tmp4_ = NULL;
+ _data_->_tmp4_ = _data_->_tmp3_;
+ _data_->_tmp5_ = NULL;
+ _data_->_tmp5__length1 = 0;
+ _data_->_tmp5_ = _data_->p;
+ _data_->_tmp5__length1 = _data_->p_length1;
+ _data_->_tmp6_ = NULL;
+ _data_->_tmp6__length1 = 0;
+ _data_->_tmp6_ = (_data_->_tmp5_ != NULL) ? _vala_array_dup9 (_data_->_tmp5_, _data_->_tmp5__length1) : ((gpointer) _data_->_tmp5_);
+ _data_->_tmp6__length1 = _data_->_tmp5__length1;
+ _data_->_state_ = 1;
+ spice_ctrl_output_stream_write (_data_->_tmp4_, _data_->_tmp6_, _data_->_tmp6__length1, spice_ctrl_foreign_menu_send_msg_ready, _data_);
+ return FALSE;
+ _state_1:
+ spice_ctrl_output_stream_write_finish (_data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ _g_object_unref0 (_data_->c);
+ goto __catch3_g_error;
+ }
+ _g_object_unref0 (_data_->c);
+ }
+ }
+ }
+ }
+ goto __finally3;
+ __catch3_g_error:
+ {
+ _data_->e = _data_->_inner_error_;
+ _data_->_inner_error_ = NULL;
+ _data_->_tmp7_ = NULL;
+ _data_->_tmp7_ = _data_->e;
+ _data_->_tmp8_ = NULL;
+ _data_->_tmp8_ = _data_->_tmp7_->message;
+ g_warning ("foreign-menu.vala:83: %s", _data_->_tmp8_);
+ _g_error_free0 (_data_->e);
+ }
+ __finally3:
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->result = TRUE;
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+}
+
+
+static unsigned int spice_ctrl_foreign_menu_get_menu_flags (SpiceCtrlForeignMenu* self, guint32 type) {
+ unsigned int result = 0;
+ unsigned int flags = 0;
+ guint32 _tmp0_ = 0U;
+ guint32 _tmp2_ = 0U;
+ g_return_val_if_fail (self != NULL, 0);
+ flags = 0;
+ _tmp0_ = type;
+ if ((FOREIGN_MENU_ITEM_TYPE_CHECKED & _tmp0_) != 0) {
+ unsigned int _tmp1_ = 0;
+ _tmp1_ = flags;
+ flags = _tmp1_ | CONTROLLER_MENU_FLAGS_CHECKED;
+ }
+ _tmp2_ = type;
+ if ((FOREIGN_MENU_ITEM_TYPE_DIM & _tmp2_) != 0) {
+ unsigned int _tmp3_ = 0;
+ _tmp3_ = flags;
+ flags = _tmp3_ | CONTROLLER_MENU_FLAGS_GRAYED;
+ }
+ result = flags;
+ return result;
+}
+
+
+static gboolean spice_ctrl_foreign_menu_handle_message (SpiceCtrlForeignMenu* self, FrgMenuMsg* msg) {
+ gboolean result = FALSE;
+ FrgMenuMsg* _tmp0_ = NULL;
+ guint32 _tmp1_ = 0U;
+ g_return_val_if_fail (self != NULL, FALSE);
+ _tmp0_ = msg;
+ _tmp1_ = (*_tmp0_).id;
+ switch (_tmp1_) {
+ case FOREIGN_MENU_SET_TITLE:
+ {
+ FrgMenuSetTitle* t = NULL;
+ FrgMenuMsg* _tmp2_ = NULL;
+ FrgMenuSetTitle* _tmp3_ = NULL;
+ const gchar* _tmp4_ = NULL;
+ _tmp2_ = msg;
+ t = (FrgMenuSetTitle*) _tmp2_;
+ _tmp3_ = t;
+ _tmp4_ = (*_tmp3_).string;
+ spice_ctrl_foreign_menu_set_title (self, _tmp4_);
+ break;
+ }
+ case FOREIGN_MENU_ADD_ITEM:
+ {
+ FrgMenuAddItem* i = NULL;
+ FrgMenuMsg* _tmp5_ = NULL;
+ FrgMenuAddItem* _tmp6_ = NULL;
+ guint32 _tmp7_ = 0U;
+ FrgMenuAddItem* _tmp8_ = NULL;
+ guint32 _tmp9_ = 0U;
+ FrgMenuAddItem* _tmp10_ = NULL;
+ guint32 _tmp11_ = 0U;
+ FrgMenuAddItem* _tmp12_ = NULL;
+ const gchar* _tmp13_ = NULL;
+ SpiceCtrlMenu* _tmp14_ = NULL;
+ FrgMenuAddItem* _tmp15_ = NULL;
+ guint32 _tmp16_ = 0U;
+ FrgMenuAddItem* _tmp17_ = NULL;
+ const gchar* _tmp18_ = NULL;
+ FrgMenuAddItem* _tmp19_ = NULL;
+ guint32 _tmp20_ = 0U;
+ unsigned int _tmp21_ = 0;
+ SpiceCtrlMenuItem* _tmp22_ = NULL;
+ _tmp5_ = msg;
+ i = (FrgMenuAddItem*) _tmp5_;
+ _tmp6_ = i;
+ _tmp7_ = (*_tmp6_).id;
+ _tmp8_ = i;
+ _tmp9_ = (*_tmp8_).type;
+ _tmp10_ = i;
+ _tmp11_ = (*_tmp10_).position;
+ _tmp12_ = i;
+ _tmp13_ = (*_tmp12_).string;
+ g_debug ("foreign-menu.vala:108: add id:%u type:%u position:%u title:%s", (guint) _tmp7_, (guint) _tmp9_, (guint) _tmp11_, _tmp13_);
+ _tmp14_ = self->priv->_menu;
+ _tmp15_ = i;
+ _tmp16_ = (*_tmp15_).id;
+ _tmp17_ = i;
+ _tmp18_ = (*_tmp17_).string;
+ _tmp19_ = i;
+ _tmp20_ = (*_tmp19_).type;
+ _tmp21_ = spice_ctrl_foreign_menu_get_menu_flags (self, _tmp20_);
+ _tmp22_ = spice_ctrl_menu_item_new ((gint) _tmp16_, _tmp18_, _tmp21_);
+ _tmp14_->items = g_list_append (_tmp14_->items, _tmp22_);
+ g_object_notify ((GObject*) self, "menu");
+ break;
+ }
+ case FOREIGN_MENU_MODIFY_ITEM:
+ {
+ g_debug ("foreign-menu.vala:113: deprecated: modify item");
+ break;
+ }
+ case FOREIGN_MENU_REMOVE_ITEM:
+ {
+ FrgMenuRmItem* i = NULL;
+ FrgMenuMsg* _tmp23_ = NULL;
+ FrgMenuRmItem* _tmp24_ = NULL;
+ guint32 _tmp25_ = 0U;
+ gchar* _tmp26_ = NULL;
+ gchar* _tmp27_ = NULL;
+ _tmp23_ = msg;
+ i = (FrgMenuRmItem*) _tmp23_;
+ _tmp24_ = i;
+ _tmp25_ = (*_tmp24_).id;
+ _tmp26_ = g_strdup_printf ("not implemented: remove id:%u", (guint) _tmp25_);
+ _tmp27_ = _tmp26_;
+ g_debug ("foreign-menu.vala:117: %s", _tmp27_);
+ _g_free0 (_tmp27_);
+ break;
+ }
+ case FOREIGN_MENU_CLEAR:
+ {
+ SpiceCtrlMenu* _tmp28_ = NULL;
+ SpiceCtrlMenu* _tmp29_ = NULL;
+ _tmp28_ = spice_ctrl_menu_new ();
+ _tmp29_ = _tmp28_;
+ spice_ctrl_foreign_menu_set_menu (self, _tmp29_);
+ _g_object_unref0 (_tmp29_);
+ break;
+ }
+ default:
+ {
+ g_warn_if_reached ();
+ result = FALSE;
+ return result;
+ }
+ }
+ result = TRUE;
+ return result;
+}
+
+
+static void spice_ctrl_foreign_menu_handle_client_data_free (gpointer _data) {
+ SpiceCtrlForeignMenuHandleClientData* _data_;
+ _data_ = _data;
+ _g_object_unref0 (_data_->c);
+ _g_object_unref0 (_data_->self);
+ g_slice_free (SpiceCtrlForeignMenuHandleClientData, _data_);
+}
+
+
+static void spice_ctrl_foreign_menu_handle_client (SpiceCtrlForeignMenu* self, GIOStream* c, GAsyncReadyCallback _callback_, gpointer _user_data_) {
+ SpiceCtrlForeignMenuHandleClientData* _data_;
+ SpiceCtrlForeignMenu* _tmp0_ = NULL;
+ GIOStream* _tmp1_ = NULL;
+ GIOStream* _tmp2_ = NULL;
+ _data_ = g_slice_new0 (SpiceCtrlForeignMenuHandleClientData);
+ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, spice_ctrl_foreign_menu_handle_client);
+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, spice_ctrl_foreign_menu_handle_client_data_free);
+ _tmp0_ = _g_object_ref0 (self);
+ _data_->self = _tmp0_;
+ _tmp1_ = c;
+ _tmp2_ = _g_object_ref0 (_tmp1_);
+ _g_object_unref0 (_data_->c);
+ _data_->c = _tmp2_;
+ spice_ctrl_foreign_menu_handle_client_co (_data_);
+}
+
+
+static void spice_ctrl_foreign_menu_handle_client_finish (SpiceCtrlForeignMenu* self, GAsyncResult* _res_, GError** error) {
+ SpiceCtrlForeignMenuHandleClientData* _data_;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
+ return;
+ }
+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
+}
+
+
+static void spice_ctrl_foreign_menu_handle_client_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
+ SpiceCtrlForeignMenuHandleClientData* _data_;
+ _data_ = _user_data_;
+ _data_->_source_object_ = source_object;
+ _data_->_res_ = _res_;
+ spice_ctrl_foreign_menu_handle_client_co (_data_);
+}
+
+
+static gboolean spice_ctrl_foreign_menu_handle_client_co (SpiceCtrlForeignMenuHandleClientData* _data_) {
+ switch (_data_->_state_) {
+ case 0:
+ goto _state_0;
+ case 1:
+ goto _state_1;
+ case 2:
+ goto _state_2;
+ case 3:
+ goto _state_3;
+ case 4:
+ goto _state_4;
+ case 5:
+ goto _state_5;
+ default:
+ g_assert_not_reached ();
+ }
+ _state_0:
+ g_debug ("foreign-menu.vala:130: new socket client, reading init header");
+ _data_->_tmp0_ = NULL;
+ _data_->_tmp0_ = g_new0 (guint8, sizeof (FrgMenuInitHeader));
+ _data_->p_length1 = 0;
+ _data_->_p_size_ = 0;
+ _data_->p = _data_->_tmp0_;
+ _data_->p_length1 = sizeof (FrgMenuInitHeader);
+ _data_->_p_size_ = _data_->p_length1;
+ _data_->_tmp1_ = NULL;
+ _data_->_tmp1__length1 = 0;
+ _data_->_tmp1_ = _data_->p;
+ _data_->_tmp1__length1 = _data_->p_length1;
+ _data_->header = (FrgMenuInitHeader*) _data_->_tmp1_;
+ _data_->_tmp2_ = NULL;
+ _data_->_tmp2_ = _data_->c;
+ _data_->_tmp3_ = NULL;
+ _data_->_tmp3_ = g_io_stream_get_input_stream (_data_->_tmp2_);
+ _data_->_tmp4_ = NULL;
+ _data_->_tmp4_ = _data_->_tmp3_;
+ _data_->_tmp5_ = NULL;
+ _data_->_tmp5__length1 = 0;
+ _data_->_tmp5_ = _data_->p;
+ _data_->_tmp5__length1 = _data_->p_length1;
+ _data_->_state_ = 1;
+ spice_ctrl_input_stream_read (_data_->_tmp4_, _data_->_tmp5_, _data_->_tmp5__length1, spice_ctrl_foreign_menu_handle_client_ready, _data_);
+ return FALSE;
+ _state_1:
+ spice_ctrl_input_stream_read_finish (_data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp6_ = NULL;
+ _data_->_tmp6_ = _data_->header;
+ _data_->_tmp7_ = 0U;
+ _data_->_tmp7_ = (*_data_->_tmp6_).magic;
+ _data_->_tmp8_ = FALSE;
+ _data_->_tmp8_ = g_warn_if (_data_->_tmp7_ != FOREIGN_MENU_MAGIC);
+ if (_data_->_tmp8_) {
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp9_ = NULL;
+ _data_->_tmp9_ = _data_->header;
+ _data_->_tmp10_ = 0U;
+ _data_->_tmp10_ = (*_data_->_tmp9_).version;
+ _data_->_tmp11_ = FALSE;
+ _data_->_tmp11_ = g_warn_if (_data_->_tmp10_ != ((guint32) FOREIGN_MENU_VERSION));
+ if (_data_->_tmp11_) {
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp12_ = NULL;
+ _data_->_tmp12_ = _data_->header;
+ _data_->_tmp13_ = 0U;
+ _data_->_tmp13_ = (*_data_->_tmp12_).size;
+ _data_->_tmp14_ = FALSE;
+ _data_->_tmp14_ = g_warn_if (((gulong) _data_->_tmp13_) < sizeof (FrgMenuInit));
+ if (_data_->_tmp14_) {
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp15_ = NULL;
+ _data_->_tmp15_ = g_new0 (guint8, sizeof (guint64));
+ _data_->cp_length1 = 0;
+ _data_->_cp_size_ = 0;
+ _data_->cp = _data_->_tmp15_;
+ _data_->cp_length1 = sizeof (guint64);
+ _data_->_cp_size_ = _data_->cp_length1;
+ _data_->_tmp16_ = NULL;
+ _data_->_tmp16_ = _data_->c;
+ _data_->_tmp17_ = NULL;
+ _data_->_tmp17_ = g_io_stream_get_input_stream (_data_->_tmp16_);
+ _data_->_tmp18_ = NULL;
+ _data_->_tmp18_ = _data_->_tmp17_;
+ _data_->_tmp19_ = NULL;
+ _data_->_tmp19__length1 = 0;
+ _data_->_tmp19_ = _data_->cp;
+ _data_->_tmp19__length1 = _data_->cp_length1;
+ _data_->_state_ = 2;
+ spice_ctrl_input_stream_read (_data_->_tmp18_, _data_->_tmp19_, _data_->_tmp19__length1, spice_ctrl_foreign_menu_handle_client_ready, _data_);
+ return FALSE;
+ _state_2:
+ spice_ctrl_input_stream_read_finish (_data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _data_->cp = (g_free (_data_->cp), NULL);
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp20_ = NULL;
+ _data_->_tmp20__length1 = 0;
+ _data_->_tmp20_ = _data_->cp;
+ _data_->_tmp20__length1 = _data_->cp_length1;
+ _data_->credentials = *((guint64*) _data_->_tmp20_);
+ _data_->_tmp21_ = 0ULL;
+ _data_->_tmp21_ = _data_->credentials;
+ _data_->_tmp22_ = FALSE;
+ _data_->_tmp22_ = g_warn_if (_data_->_tmp21_ != ((guint64) 0));
+ if (_data_->_tmp22_) {
+ _data_->cp = (g_free (_data_->cp), NULL);
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp23_ = NULL;
+ _data_->_tmp23_ = _data_->header;
+ _data_->_tmp24_ = 0U;
+ _data_->_tmp24_ = (*_data_->_tmp23_).size;
+ _data_->title_size = _data_->_tmp24_ - sizeof (FrgMenuInit);
+ _data_->_tmp25_ = 0UL;
+ _data_->_tmp25_ = _data_->title_size;
+ _data_->_tmp26_ = NULL;
+ _data_->_tmp26_ = g_new0 (guint8, _data_->_tmp25_ + 1);
+ _data_->title_length1 = 0;
+ _data_->_title_size_ = 0;
+ _data_->title = _data_->_tmp26_;
+ _data_->title_length1 = _data_->_tmp25_ + 1;
+ _data_->_title_size_ = _data_->title_length1;
+ _data_->_tmp27_ = NULL;
+ _data_->_tmp27_ = _data_->c;
+ _data_->_tmp28_ = NULL;
+ _data_->_tmp28_ = g_io_stream_get_input_stream (_data_->_tmp27_);
+ _data_->_tmp29_ = NULL;
+ _data_->_tmp29_ = _data_->_tmp28_;
+ _data_->_tmp30_ = NULL;
+ _data_->_tmp30__length1 = 0;
+ _data_->_tmp30_ = _data_->title;
+ _data_->_tmp30__length1 = _data_->title_length1;
+ _data_->_tmp31_ = 0UL;
+ _data_->_tmp31_ = _data_->title_size;
+ _data_->_state_ = 3;
+ g_input_stream_read_async (_data_->_tmp29_, _data_->_tmp30_ + 0, (gsize) (((gint) _data_->_tmp31_) - 0), G_PRIORITY_DEFAULT, NULL, spice_ctrl_foreign_menu_handle_client_ready, _data_);
+ return FALSE;
+ _state_3:
+ g_input_stream_read_finish (_data_->_tmp29_, _data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _data_->title = (g_free (_data_->title), NULL);
+ _data_->cp = (g_free (_data_->cp), NULL);
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp32_ = NULL;
+ _data_->_tmp32__length1 = 0;
+ _data_->_tmp32_ = _data_->title;
+ _data_->_tmp32__length1 = _data_->title_length1;
+ spice_ctrl_foreign_menu_set_title (_data_->self, (const gchar*) _data_->_tmp32_);
+ g_signal_emit_by_name (_data_->self, "client-connected");
+ {
+ _data_->_tmp33_ = TRUE;
+ while (TRUE) {
+ if (!_data_->_tmp33_) {
+ }
+ _data_->_tmp33_ = FALSE;
+ _data_->_tmp34_ = NULL;
+ _data_->_tmp34_ = g_new0 (guint8, sizeof (FrgMenuMsg));
+ _data_->t_length1 = 0;
+ _data_->_t_size_ = 0;
+ _data_->t = _data_->_tmp34_;
+ _data_->t_length1 = sizeof (FrgMenuMsg);
+ _data_->_t_size_ = _data_->t_length1;
+ _data_->_tmp35_ = NULL;
+ _data_->_tmp35_ = _data_->c;
+ _data_->_tmp36_ = NULL;
+ _data_->_tmp36_ = g_io_stream_get_input_stream (_data_->_tmp35_);
+ _data_->_tmp37_ = NULL;
+ _data_->_tmp37_ = _data_->_tmp36_;
+ _data_->_tmp38_ = NULL;
+ _data_->_tmp38__length1 = 0;
+ _data_->_tmp38_ = _data_->t;
+ _data_->_tmp38__length1 = _data_->t_length1;
+ _data_->_state_ = 4;
+ spice_ctrl_input_stream_read (_data_->_tmp37_, _data_->_tmp38_, _data_->_tmp38__length1, spice_ctrl_foreign_menu_handle_client_ready, _data_);
+ return FALSE;
+ _state_4:
+ spice_ctrl_input_stream_read_finish (_data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _data_->t = (g_free (_data_->t), NULL);
+ _data_->title = (g_free (_data_->title), NULL);
+ _data_->cp = (g_free (_data_->cp), NULL);
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp39_ = NULL;
+ _data_->_tmp39__length1 = 0;
+ _data_->_tmp39_ = _data_->t;
+ _data_->_tmp39__length1 = _data_->t_length1;
+ _data_->msg = (FrgMenuMsg*) _data_->_tmp39_;
+ _data_->_tmp40_ = NULL;
+ _data_->_tmp40_ = _data_->msg;
+ _data_->_tmp41_ = 0U;
+ _data_->_tmp41_ = (*_data_->_tmp40_).id;
+ _data_->_tmp42_ = NULL;
+ _data_->_tmp42_ = g_strdup_printf ("%u", _data_->_tmp41_);
+ _data_->_tmp43_ = NULL;
+ _data_->_tmp43_ = _data_->_tmp42_;
+ _data_->_tmp44_ = NULL;
+ _data_->_tmp44_ = g_strconcat ("new message ", _data_->_tmp43_, NULL);
+ _data_->_tmp45_ = NULL;
+ _data_->_tmp45_ = _data_->_tmp44_;
+ _data_->_tmp46_ = NULL;
+ _data_->_tmp46_ = g_strconcat (_data_->_tmp45_, "size ", NULL);
+ _data_->_tmp47_ = NULL;
+ _data_->_tmp47_ = _data_->_tmp46_;
+ _data_->_tmp48_ = NULL;
+ _data_->_tmp48_ = _data_->msg;
+ _data_->_tmp49_ = 0U;
+ _data_->_tmp49_ = (*_data_->_tmp48_).size;
+ _data_->_tmp50_ = NULL;
+ _data_->_tmp50_ = g_strdup_printf ("%u", _data_->_tmp49_);
+ _data_->_tmp51_ = NULL;
+ _data_->_tmp51_ = _data_->_tmp50_;
+ _data_->_tmp52_ = NULL;
+ _data_->_tmp52_ = g_strconcat (_data_->_tmp47_, _data_->_tmp51_, NULL);
+ _data_->_tmp53_ = NULL;
+ _data_->_tmp53_ = _data_->_tmp52_;
+ g_debug ("foreign-menu.vala:159: %s", _data_->_tmp53_);
+ _g_free0 (_data_->_tmp53_);
+ _g_free0 (_data_->_tmp51_);
+ _g_free0 (_data_->_tmp47_);
+ _g_free0 (_data_->_tmp45_);
+ _g_free0 (_data_->_tmp43_);
+ _data_->_tmp54_ = NULL;
+ _data_->_tmp54_ = _data_->msg;
+ _data_->_tmp55_ = 0U;
+ _data_->_tmp55_ = (*_data_->_tmp54_).size;
+ _data_->_tmp56_ = FALSE;
+ _data_->_tmp56_ = g_warn_if (((gulong) _data_->_tmp55_) < sizeof (FrgMenuMsg));
+ if (_data_->_tmp56_) {
+ _data_->t = (g_free (_data_->t), NULL);
+ break;
+ }
+ _data_->_tmp57_ = NULL;
+ _data_->_tmp57_ = _data_->msg;
+ _data_->_tmp58_ = 0U;
+ _data_->_tmp58_ = (*_data_->_tmp57_).size;
+ if (((gulong) _data_->_tmp58_) > sizeof (FrgMenuMsg)) {
+ _data_->_tmp59_ = NULL;
+ _data_->_tmp59_ = _data_->msg;
+ _data_->_tmp60_ = 0U;
+ _data_->_tmp60_ = (*_data_->_tmp59_).size;
+ _data_->_tmp61_ = 0;
+ _data_->_tmp61_ = (gint) _data_->_tmp60_;
+ _data_->t = g_renew (guint8, _data_->t, (gint) _data_->_tmp60_);
+ (_data_->_tmp61_ > _data_->t_length1) ? memset (_data_->t + _data_->t_length1, 0, sizeof (guint8) * (_data_->_tmp61_ - _data_->t_length1)) : NULL;
+ _data_->t_length1 = _data_->_tmp61_;
+ _data_->_t_size_ = _data_->_tmp61_;
+ _data_->_tmp62_ = NULL;
+ _data_->_tmp62__length1 = 0;
+ _data_->_tmp62_ = _data_->t;
+ _data_->_tmp62__length1 = _data_->t_length1;
+ _data_->msg = (FrgMenuMsg*) _data_->_tmp62_;
+ _data_->_tmp63_ = NULL;
+ _data_->_tmp63_ = _data_->c;
+ _data_->_tmp64_ = NULL;
+ _data_->_tmp64_ = g_io_stream_get_input_stream (_data_->_tmp63_);
+ _data_->_tmp65_ = NULL;
+ _data_->_tmp65_ = _data_->_tmp64_;
+ _data_->_tmp66_ = NULL;
+ _data_->_tmp66__length1 = 0;
+ _data_->_tmp66_ = _data_->t;
+ _data_->_tmp66__length1 = _data_->t_length1;
+ _data_->_tmp67_ = NULL;
+ _data_->_tmp67_ = _data_->msg;
+ _data_->_tmp68_ = 0U;
+ _data_->_tmp68_ = (*_data_->_tmp67_).size;
+ _data_->_state_ = 5;
+ spice_ctrl_input_stream_read (_data_->_tmp65_, _data_->_tmp66_ + ((gint) sizeof (FrgMenuMsg)), ((gint) _data_->_tmp68_) - ((gint) sizeof (FrgMenuMsg)), spice_ctrl_foreign_menu_handle_client_ready, _data_);
+ return FALSE;
+ _state_5:
+ spice_ctrl_input_stream_read_finish (_data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _data_->t = (g_free (_data_->t), NULL);
+ _data_->title = (g_free (_data_->title), NULL);
+ _data_->cp = (g_free (_data_->cp), NULL);
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ }
+ _data_->_tmp69_ = NULL;
+ _data_->_tmp69_ = _data_->msg;
+ spice_ctrl_foreign_menu_handle_message (_data_->self, _data_->_tmp69_);
+ _data_->t = (g_free (_data_->t), NULL);
+ }
+ }
+ _data_->title = (g_free (_data_->title), NULL);
+ _data_->cp = (g_free (_data_->cp), NULL);
+ _data_->p = (g_free (_data_->p), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+}
+
+
+static void spice_ctrl_foreign_menu_listen_data_free (gpointer _data) {
+ SpiceCtrlForeignMenuListenData* _data_;
+ _data_ = _data;
+ _g_free0 (_data_->addr);
+ _g_object_unref0 (_data_->self);
+ g_slice_free (SpiceCtrlForeignMenuListenData, _data_);
+}
+
+
+void spice_ctrl_foreign_menu_listen (SpiceCtrlForeignMenu* self, const gchar* addr, GAsyncReadyCallback _callback_, gpointer _user_data_) {
+ SpiceCtrlForeignMenuListenData* _data_;
+ SpiceCtrlForeignMenu* _tmp0_ = NULL;
+ const gchar* _tmp1_ = NULL;
+ gchar* _tmp2_ = NULL;
+ _data_ = g_slice_new0 (SpiceCtrlForeignMenuListenData);
+ _data_->_async_result = g_simple_async_result_new (G_OBJECT (self), _callback_, _user_data_, spice_ctrl_foreign_menu_listen);
+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, spice_ctrl_foreign_menu_listen_data_free);
+ _tmp0_ = _g_object_ref0 (self);
+ _data_->self = _tmp0_;
+ _tmp1_ = addr;
+ _tmp2_ = g_strdup (_tmp1_);
+ _g_free0 (_data_->addr);
+ _data_->addr = _tmp2_;
+ spice_ctrl_foreign_menu_listen_co (_data_);
+}
+
+
+void spice_ctrl_foreign_menu_listen_finish (SpiceCtrlForeignMenu* self, GAsyncResult* _res_, GError** error) {
+ SpiceCtrlForeignMenuListenData* _data_;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
+ return;
+ }
+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
+}
+
+
+static void spice_ctrl_foreign_menu_listen_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
+ SpiceCtrlForeignMenuListenData* _data_;
+ _data_ = _user_data_;
+ _data_->_source_object_ = source_object;
+ _data_->_res_ = _res_;
+ spice_ctrl_foreign_menu_listen_co (_data_);
+}
+
+
+static gboolean spice_ctrl_foreign_menu_listen_co (SpiceCtrlForeignMenuListenData* _data_) {
+ switch (_data_->_state_) {
+ case 0:
+ goto _state_0;
+ case 1:
+ goto _state_1;
+ case 2:
+ goto _state_2;
+ default:
+ g_assert_not_reached ();
+ }
+ _state_0:
+ _data_->_tmp0_ = NULL;
+ _data_->_tmp0_ = _data_->addr;
+ _data_->_tmp1_ = NULL;
+ _data_->_tmp1_ = spice_foreign_menu_listener_new (_data_->_tmp0_, &_data_->_inner_error_);
+ _data_->listener = _data_->_tmp1_;
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ {
+ _data_->_tmp2_ = TRUE;
+ while (TRUE) {
+ if (!_data_->_tmp2_) {
+ }
+ _data_->_tmp2_ = FALSE;
+ _data_->_tmp3_ = NULL;
+ _data_->_tmp3_ = _data_->listener;
+ _data_->_state_ = 1;
+ spice_foreign_menu_listener_accept_async (_data_->_tmp3_, NULL, spice_ctrl_foreign_menu_listen_ready, _data_);
+ return FALSE;
+ _state_1:
+ _data_->_tmp4_ = NULL;
+ _data_->_tmp4_ = spice_foreign_menu_listener_accept_finish (_data_->_tmp3_, _data_->_res_, NULL, &_data_->_inner_error_);
+ _data_->_tmp5_ = NULL;
+ _data_->_tmp5_ = _g_object_ref0 (_data_->_tmp4_);
+ _data_->c = _data_->_tmp5_;
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _g_object_unref0 (_data_->listener);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp6_ = 0;
+ _data_->_tmp6_ = _data_->self->priv->nclients;
+ _data_->self->priv->nclients = _data_->_tmp6_ + 1;
+ _data_->_tmp7_ = NULL;
+ _data_->_tmp7_ = _data_->c;
+ _data_->_tmp8_ = NULL;
+ _data_->_tmp8_ = _g_object_ref0 (_data_->_tmp7_);
+ _data_->self->priv->clients = g_list_append (_data_->self->priv->clients, _data_->_tmp8_);
+ {
+ _data_->_tmp9_ = NULL;
+ _data_->_tmp9_ = _data_->c;
+ _data_->_state_ = 2;
+ spice_ctrl_foreign_menu_handle_client (_data_->self, _data_->_tmp9_, spice_ctrl_foreign_menu_listen_ready, _data_);
+ return FALSE;
+ _state_2:
+ spice_ctrl_foreign_menu_handle_client_finish (_data_->self, _data_->_res_, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ goto __catch4_g_error;
+ }
+ }
+ goto __finally4;
+ __catch4_g_error:
+ {
+ _data_->e = _data_->_inner_error_;
+ _data_->_inner_error_ = NULL;
+ _data_->_tmp10_ = NULL;
+ _data_->_tmp10_ = _data_->e;
+ _data_->_tmp11_ = NULL;
+ _data_->_tmp11_ = _data_->_tmp10_->message;
+ g_warning ("foreign-menu.vala:187: %s", _data_->_tmp11_);
+ _g_error_free0 (_data_->e);
+ }
+ __finally4:
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _g_object_unref0 (_data_->c);
+ _g_object_unref0 (_data_->listener);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp12_ = NULL;
+ _data_->_tmp12_ = _data_->c;
+ g_io_stream_close (_data_->_tmp12_, NULL, &_data_->_inner_error_);
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _g_object_unref0 (_data_->c);
+ _g_object_unref0 (_data_->listener);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ }
+ _data_->_tmp13_ = NULL;
+ _data_->_tmp13_ = _data_->c;
+ _data_->self->priv->clients = g_list_remove (_data_->self->priv->clients, _data_->_tmp13_);
+ _data_->_tmp14_ = 0;
+ _data_->_tmp14_ = _data_->self->priv->nclients;
+ _data_->self->priv->nclients = _data_->_tmp14_ - 1;
+ _g_object_unref0 (_data_->c);
+ }
+ }
+ _g_object_unref0 (_data_->listener);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+}
+
+
+SpiceCtrlMenu* spice_ctrl_foreign_menu_get_menu (SpiceCtrlForeignMenu* self) {
+ SpiceCtrlMenu* result;
+ SpiceCtrlMenu* _tmp0_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_menu;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_foreign_menu_set_menu (SpiceCtrlForeignMenu* self, SpiceCtrlMenu* value) {
+ SpiceCtrlMenu* _tmp0_ = NULL;
+ SpiceCtrlMenu* _tmp1_ = NULL;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp1_ = _g_object_ref0 (_tmp0_);
+ _g_object_unref0 (self->priv->_menu);
+ self->priv->_menu = _tmp1_;
+ g_object_notify ((GObject *) self, "menu");
+}
+
+
+const gchar* spice_ctrl_foreign_menu_get_title (SpiceCtrlForeignMenu* self) {
+ const gchar* result;
+ const gchar* _tmp0_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->priv->_title;
+ result = _tmp0_;
+ return result;
+}
+
+
+static void spice_ctrl_foreign_menu_set_title (SpiceCtrlForeignMenu* self, const gchar* value) {
+ const gchar* _tmp0_ = NULL;
+ gchar* _tmp1_ = NULL;
+ g_return_if_fail (self != NULL);
+ _tmp0_ = value;
+ _tmp1_ = g_strdup (_tmp0_);
+ _g_free0 (self->priv->_title);
+ self->priv->_title = _tmp1_;
+ g_object_notify ((GObject *) self, "title");
+}
+
+
+static void spice_ctrl_foreign_menu_class_init (SpiceCtrlForeignMenuClass * klass) {
+ spice_ctrl_foreign_menu_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (SpiceCtrlForeignMenuPrivate));
+ G_OBJECT_CLASS (klass)->get_property = _vala_spice_ctrl_foreign_menu_get_property;
+ G_OBJECT_CLASS (klass)->set_property = _vala_spice_ctrl_foreign_menu_set_property;
+ G_OBJECT_CLASS (klass)->finalize = spice_ctrl_foreign_menu_finalize;
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_FOREIGN_MENU_MENU, g_param_spec_object ("menu", "menu", "menu", SPICE_CTRL_TYPE_MENU, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), SPICE_CTRL_FOREIGN_MENU_TITLE, g_param_spec_string ("title", "title", "title", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+ g_signal_new ("client_connected", SPICE_CTRL_TYPE_FOREIGN_MENU, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+
+static void spice_ctrl_foreign_menu_instance_init (SpiceCtrlForeignMenu * self) {
+ self->priv = SPICE_CTRL_FOREIGN_MENU_GET_PRIVATE (self);
+}
+
+
+static void spice_ctrl_foreign_menu_finalize (GObject* obj) {
+ SpiceCtrlForeignMenu * self;
+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, SPICE_CTRL_TYPE_FOREIGN_MENU, SpiceCtrlForeignMenu);
+ _g_object_unref0 (self->priv->_menu);
+ _g_free0 (self->priv->_title);
+ __g_list_free__g_object_unref0_0 (self->priv->clients);
+ G_OBJECT_CLASS (spice_ctrl_foreign_menu_parent_class)->finalize (obj);
+}
+
+
+GType spice_ctrl_foreign_menu_get_type (void) {
+ static volatile gsize spice_ctrl_foreign_menu_type_id__volatile = 0;
+ if (g_once_init_enter (&spice_ctrl_foreign_menu_type_id__volatile)) {
+ static const GTypeInfo g_define_type_info = { sizeof (SpiceCtrlForeignMenuClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) spice_ctrl_foreign_menu_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SpiceCtrlForeignMenu), 0, (GInstanceInitFunc) spice_ctrl_foreign_menu_instance_init, NULL };
+ GType spice_ctrl_foreign_menu_type_id;
+ spice_ctrl_foreign_menu_type_id = g_type_register_static (G_TYPE_OBJECT, "SpiceCtrlForeignMenu", &g_define_type_info, 0);
+ g_once_init_leave (&spice_ctrl_foreign_menu_type_id__volatile, spice_ctrl_foreign_menu_type_id);
+ }
+ return spice_ctrl_foreign_menu_type_id__volatile;
+}
+
+
+static void _vala_spice_ctrl_foreign_menu_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
+ SpiceCtrlForeignMenu * self;
+ self = G_TYPE_CHECK_INSTANCE_CAST (object, SPICE_CTRL_TYPE_FOREIGN_MENU, SpiceCtrlForeignMenu);
+ switch (property_id) {
+ case SPICE_CTRL_FOREIGN_MENU_MENU:
+ g_value_set_object (value, spice_ctrl_foreign_menu_get_menu (self));
+ break;
+ case SPICE_CTRL_FOREIGN_MENU_TITLE:
+ g_value_set_string (value, spice_ctrl_foreign_menu_get_title (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void _vala_spice_ctrl_foreign_menu_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
+ SpiceCtrlForeignMenu * self;
+ self = G_TYPE_CHECK_INSTANCE_CAST (object, SPICE_CTRL_TYPE_FOREIGN_MENU, SpiceCtrlForeignMenu);
+ switch (property_id) {
+ case SPICE_CTRL_FOREIGN_MENU_MENU:
+ spice_ctrl_foreign_menu_set_menu (self, g_value_get_object (value));
+ break;
+ case SPICE_CTRL_FOREIGN_MENU_TITLE:
+ spice_ctrl_foreign_menu_set_title (self, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+
+
--- /dev/null
+// Copyright (C) 2012 Red Hat, Inc.
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+using Custom;
+
+namespace SpiceCtrl {
+
+public class ForeignMenu: Object {
+
+ public Menu menu { get; private set; }
+ public string title { get; private set; }
+
+ public signal void client_connected ();
+
+ private int nclients;
+ private List<IOStream> clients;
+
+ public ForeignMenu() {
+ menu = new Menu ();
+ }
+
+ public void menu_item_click_msg (int32 item_id) {
+ debug ("clicked id: %d".printf (item_id));
+
+ var msg = SpiceProtocol.ForeignMenu.Event ();
+ msg.base.size = (uint32)sizeof (SpiceProtocol.ForeignMenu.Event);
+ msg.base.id = SpiceProtocol.ForeignMenu.MsgId.ITEM_EVENT;
+ msg.id = item_id;
+ msg.action = SpiceProtocol.ForeignMenu.EventType.CLICK;
+
+ unowned uint8[] p = ((uint8[])(&msg))[0:msg.base.size];
+ send_msg.begin (p);
+ }
+
+ public void menu_item_checked_msg (int32 item_id, bool checked = true) {
+ debug ("%schecked id: %d".printf (checked ? "" : "un", item_id));
+
+ var msg = SpiceProtocol.ForeignMenu.Event ();
+ msg.base.size = (uint32)sizeof (SpiceProtocol.ForeignMenu.Event);
+ msg.base.id = SpiceProtocol.ForeignMenu.MsgId.ITEM_EVENT;
+ msg.id = item_id;
+ msg.action = checked ?
+ SpiceProtocol.ForeignMenu.EventType.CHECKED :
+ SpiceProtocol.ForeignMenu.EventType.UNCHECKED;
+
+ unowned uint8[] p = ((uint8[])(&msg))[0:msg.base.size];
+ send_msg.begin (p);
+ }
+
+ public void app_activated_msg (bool activated = true) {
+ var msg = SpiceProtocol.ForeignMenu.Msg ();
+ msg.size = (uint32)sizeof (SpiceProtocol.ForeignMenu.Event);
+ msg.id = activated ?
+ SpiceProtocol.ForeignMenu.MsgId.APP_ACTIVATED :
+ SpiceProtocol.ForeignMenu.MsgId.APP_DEACTIVATED;
+
+ unowned uint8[] p = ((uint8[])(&msg))[0:msg.size];
+ send_msg.begin (p);
+ }
+
+ public async bool send_msg (owned uint8[] p) throws GLib.Error {
+ // vala FIXME: pass Controller.Msg instead
+ // vala doesn't keep reference on the struct in async methods
+ // it copies only base, which is not enough to transmit the whole
+ // message.
+ try {
+ foreach (var c in clients) {
+ yield output_stream_write (c.output_stream, p);
+ }
+ } catch (GLib.Error e) {
+ warning (e.message);
+ }
+
+ return true;
+ }
+
+ SpiceProtocol.Controller.MenuFlags get_menu_flags (uint32 type) {
+ SpiceProtocol.Controller.MenuFlags flags = 0;
+
+ if ((SpiceProtocol.ForeignMenu.MenuFlags.CHECKED & type) != 0)
+ flags |= SpiceProtocol.Controller.MenuFlags.CHECKED;
+ if ((SpiceProtocol.ForeignMenu.MenuFlags.DIM & type) != 0)
+ flags |= SpiceProtocol.Controller.MenuFlags.GRAYED;
+
+ return flags;
+ }
+
+ private bool handle_message (SpiceProtocol.ForeignMenu.Msg* msg) {
+ switch (msg.id) {
+ case SpiceProtocol.ForeignMenu.MsgId.SET_TITLE:
+ var t = (SpiceProtocol.ForeignMenu.SetTitle*)(msg);
+ title = t.string;
+ break;
+ case SpiceProtocol.ForeignMenu.MsgId.ADD_ITEM:
+ var i = (SpiceProtocol.ForeignMenu.AddItem*)(msg);
+ debug ("add id:%u type:%u position:%u title:%s", i.id, i.type, i.position, i.string);
+ menu.items.append (new MenuItem ((int)i.id, i.string, get_menu_flags (i.type)));
+ notify_property ("menu");
+ break;
+ case SpiceProtocol.ForeignMenu.MsgId.MODIFY_ITEM:
+ debug ("deprecated: modify item");
+ break;
+ case SpiceProtocol.ForeignMenu.MsgId.REMOVE_ITEM:
+ var i = (SpiceProtocol.ForeignMenu.RmItem*)(msg);
+ debug ("not implemented: remove id:%u".printf (i.id));
+ break;
+ case SpiceProtocol.ForeignMenu.MsgId.CLEAR:
+ menu = new Menu ();
+ break;
+ default:
+ warn_if_reached ();
+ return false;
+ }
+ return true;
+ }
+
+ private async void handle_client (IOStream c) throws GLib.Error {
+ debug ("new socket client, reading init header");
+
+ var p = new uint8[sizeof(SpiceProtocol.ForeignMenu.InitHeader)];
+ var header = (SpiceProtocol.ForeignMenu.InitHeader*)p;
+ yield input_stream_read (c.input_stream, p);
+ if (warn_if (header.magic != SpiceProtocol.ForeignMenu.MAGIC))
+ return;
+ if (warn_if (header.version != SpiceProtocol.ForeignMenu.VERSION))
+ return;
+ if (warn_if (header.size < sizeof (SpiceProtocol.ForeignMenu.Init)))
+ return;
+
+ var cp = new uint8[sizeof(uint64)];
+ yield input_stream_read (c.input_stream, cp);
+ uint64 credentials = *(uint64*)cp;
+ if (warn_if (credentials != 0))
+ return;
+
+ var title_size = header.size - sizeof(SpiceProtocol.ForeignMenu.Init);
+ var title = new uint8[title_size + 1];
+ yield c.input_stream.read_async (title[0:title_size]);
+ this.title = (string)title;
+
+ client_connected ();
+
+ for (;;) {
+ var t = new uint8[sizeof(SpiceProtocol.ForeignMenu.Msg)];
+ yield input_stream_read (c.input_stream, t);
+ var msg = (SpiceProtocol.ForeignMenu.Msg*)t;
+ debug ("new message " + msg.id.to_string () + "size " + msg.size.to_string ());
+
+ if (warn_if (msg.size < sizeof (SpiceProtocol.ForeignMenu.Msg)))
+ break;
+
+ if (msg.size > sizeof (SpiceProtocol.ForeignMenu.Msg)) {
+ t.resize ((int)msg.size);
+ msg = (SpiceProtocol.ForeignMenu.Msg*)t;
+
+ yield input_stream_read (c.input_stream, t[sizeof(SpiceProtocol.ForeignMenu.Msg):msg.size]);
+ }
+
+ handle_message (msg);
+ }
+
+ }
+
+ public async void listen (string? addr = null) throws GLib.Error, SpiceCtrl.Error
+ {
+ var listener = Spice.ForeignMenuListener.new_listener (addr);
+
+ for (;;) {
+ var c = yield listener.accept_async ();
+ nclients += 1;
+ clients.append (c);
+ try {
+ yield handle_client (c);
+ } catch (GLib.Error e) {
+ warning (e.message);
+ }
+ c.close ();
+ clients.remove (c);
+ nclients -= 1;
+ }
+ }
+
+}
+
+} // SpiceCtrl
--- /dev/null
+/* gio-windows-2.0.vapi generated by vapigen. */
+/* NOT YET UPSTREAM: https://bugzilla.gnome.org/show_bug.cgi?id=650052 */
+
+[CCode (cprefix = "GLib", lower_case_cprefix = "glib_")]
+namespace GLib {
+ [CCode (cheader_filename = "gio/gwin32inputstream.h")]
+ public class Win32InputStream : GLib.InputStream {
+ public weak GLib.InputStream parent_instance;
+ [CCode (cname = "g_win32_input_stream_new", type = "GInputStream*", has_construct_function = false)]
+ public Win32InputStream (void* handle, bool close_handle);
+ [CCode (cname = "g_win32_input_stream_get_close_handle")]
+ public static bool get_close_handle (GLib.Win32InputStream stream);
+ [CCode (cname = "g_win32_input_stream_get_handle")]
+ public static void* get_handle (GLib.Win32InputStream stream);
+ [CCode (cname = "g_win32_input_stream_set_close_handle")]
+ public static void set_close_handle (GLib.Win32InputStream stream, bool close_handle);
+ }
+ [CCode (cheader_filename = "gio/gwin32inputstream.h")]
+ public class Win32OutputStream : GLib.OutputStream {
+ public weak GLib.OutputStream parent_instance;
+ [CCode (cname = "g_win32_output_stream_new", type = "GOutputStream*", has_construct_function = false)]
+ public Win32OutputStream (void* handle, bool close_handle);
+ [CCode (cname = "g_win32_output_stream_get_close_handle")]
+ public static bool get_close_handle (GLib.Win32OutputStream stream);
+ [CCode (cname = "g_win32_output_stream_get_handle")]
+ public static void* get_handle (GLib.Win32OutputStream stream);
+ [CCode (cname = "g_win32_output_stream_set_close_handle")]
+ public static void set_close_handle (GLib.Win32OutputStream stream, bool close_handle);
+ }
+}
--- /dev/null
+/* menu.c generated by valac 0.32.1, the Vala compiler
+ * generated from menu.vala, do not modify */
+
+/* Copyright (C) 2011 Red Hat, Inc.*/
+/* This library is free software; you can redistribute it and/or*/
+/* modify it under the terms of the GNU Lesser General Public*/
+/* License as published by the Free Software Foundation; either*/
+/* version 2.1 of the License, or (at your option) any later version.*/
+/* This library is distributed in the hope that it will be useful,*/
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU*/
+/* Lesser General Public License for more details.*/
+/* You should have received a copy of the GNU Lesser General Public*/
+/* License along with this library; if not, see <http://www.gnu.org/licenses/>.*/
+
+#include <glib.h>
+#include <glib-object.h>
+#include <stdlib.h>
+#include <string.h>
+#include <spice/controller_prot.h>
+#include <custom.h>
+
+
+#define SPICE_CTRL_TYPE_MENU_ITEM (spice_ctrl_menu_item_get_type ())
+#define SPICE_CTRL_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_CTRL_TYPE_MENU_ITEM, SpiceCtrlMenuItem))
+#define SPICE_CTRL_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_CTRL_TYPE_MENU_ITEM, SpiceCtrlMenuItemClass))
+#define SPICE_CTRL_IS_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_CTRL_TYPE_MENU_ITEM))
+#define SPICE_CTRL_IS_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_CTRL_TYPE_MENU_ITEM))
+#define SPICE_CTRL_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_CTRL_TYPE_MENU_ITEM, SpiceCtrlMenuItemClass))
+
+typedef struct _SpiceCtrlMenuItem SpiceCtrlMenuItem;
+typedef struct _SpiceCtrlMenuItemClass SpiceCtrlMenuItemClass;
+typedef struct _SpiceCtrlMenuItemPrivate SpiceCtrlMenuItemPrivate;
+
+#define SPICE_CTRL_TYPE_MENU (spice_ctrl_menu_get_type ())
+#define SPICE_CTRL_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_CTRL_TYPE_MENU, SpiceCtrlMenu))
+#define SPICE_CTRL_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_CTRL_TYPE_MENU, SpiceCtrlMenuClass))
+#define SPICE_CTRL_IS_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_CTRL_TYPE_MENU))
+#define SPICE_CTRL_IS_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_CTRL_TYPE_MENU))
+#define SPICE_CTRL_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_CTRL_TYPE_MENU, SpiceCtrlMenuClass))
+
+typedef struct _SpiceCtrlMenu SpiceCtrlMenu;
+typedef struct _SpiceCtrlMenuClass SpiceCtrlMenuClass;
+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
+#define _g_free0(var) (var = (g_free (var), NULL))
+typedef struct _SpiceCtrlMenuPrivate SpiceCtrlMenuPrivate;
+#define __g_list_free__g_object_unref0_0(var) ((var == NULL) ? NULL : (var = (_g_list_free__g_object_unref0_ (var), NULL)))
+#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
+
+struct _SpiceCtrlMenuItem {
+ GObject parent_instance;
+ SpiceCtrlMenuItemPrivate * priv;
+ SpiceCtrlMenu* submenu;
+ gint parent_id;
+ gint id;
+ gchar* text;
+ gchar* accel;
+ unsigned int flags;
+};
+
+struct _SpiceCtrlMenuItemClass {
+ GObjectClass parent_class;
+};
+
+typedef enum {
+ SPICE_CTRL_ERROR_VALUE
+} SpiceCtrlError;
+#define SPICE_CTRL_ERROR spice_ctrl_error_quark ()
+struct _SpiceCtrlMenu {
+ GObject parent_instance;
+ SpiceCtrlMenuPrivate * priv;
+ GList* items;
+};
+
+struct _SpiceCtrlMenuClass {
+ GObjectClass parent_class;
+};
+
+
+static gpointer spice_ctrl_menu_item_parent_class = NULL;
+static gpointer spice_ctrl_menu_parent_class = NULL;
+
+GType spice_ctrl_menu_item_get_type (void) G_GNUC_CONST;
+GType spice_ctrl_menu_get_type (void) G_GNUC_CONST;
+enum {
+ SPICE_CTRL_MENU_ITEM_DUMMY_PROPERTY
+};
+SpiceCtrlMenuItem* spice_ctrl_menu_item_new (gint id, const gchar* text, unsigned int flags);
+SpiceCtrlMenuItem* spice_ctrl_menu_item_construct (GType object_type, gint id, const gchar* text, unsigned int flags);
+GQuark spice_ctrl_error_quark (void);
+SpiceCtrlMenuItem* spice_ctrl_menu_item_new_from_string (const gchar* str, GError** error);
+SpiceCtrlMenuItem* spice_ctrl_menu_item_construct_from_string (GType object_type, const gchar* str, GError** error);
+SpiceCtrlMenu* spice_ctrl_menu_new (void);
+SpiceCtrlMenu* spice_ctrl_menu_construct (GType object_type);
+gchar* spice_ctrl_menu_item_to_string (SpiceCtrlMenuItem* self);
+gchar* spice_ctrl_menu_to_string (SpiceCtrlMenu* self);
+const gchar* spice_protocol_controller_menu_flags_to_string (unsigned int self);
+static const char* _spice_protocol_controller_menu_flags_to_string (unsigned int value);
+static void spice_ctrl_menu_item_finalize (GObject* obj);
+enum {
+ SPICE_CTRL_MENU_DUMMY_PROPERTY
+};
+static void _g_object_unref0_ (gpointer var);
+static void _g_list_free__g_object_unref0_ (GList* self);
+SpiceCtrlMenu* spice_ctrl_menu_find_id (SpiceCtrlMenu* self, gint id);
+SpiceCtrlMenu* spice_ctrl_menu_new_from_string (const gchar* str);
+SpiceCtrlMenu* spice_ctrl_menu_construct_from_string (GType object_type, const gchar* str);
+static void spice_ctrl_menu_finalize (GObject* obj);
+static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
+static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func);
+static gint _vala_array_length (gpointer array);
+
+
+SpiceCtrlMenuItem* spice_ctrl_menu_item_construct (GType object_type, gint id, const gchar* text, unsigned int flags) {
+ SpiceCtrlMenuItem * self = NULL;
+ gint _tmp0_ = 0;
+ const gchar* _tmp1_ = NULL;
+ gchar* _tmp2_ = NULL;
+ unsigned int _tmp3_ = 0;
+ g_return_val_if_fail (text != NULL, NULL);
+ self = (SpiceCtrlMenuItem*) g_object_new (object_type, NULL);
+ _tmp0_ = id;
+ self->id = _tmp0_;
+ _tmp1_ = text;
+ _tmp2_ = g_strdup (_tmp1_);
+ _g_free0 (self->text);
+ self->text = _tmp2_;
+ _tmp3_ = flags;
+ self->flags = _tmp3_;
+ return self;
+}
+
+
+SpiceCtrlMenuItem* spice_ctrl_menu_item_new (gint id, const gchar* text, unsigned int flags) {
+ return spice_ctrl_menu_item_construct (SPICE_CTRL_TYPE_MENU_ITEM, id, text, flags);
+}
+
+
+SpiceCtrlMenuItem* spice_ctrl_menu_item_construct_from_string (GType object_type, const gchar* str, GError** error) {
+ SpiceCtrlMenuItem * self = NULL;
+ gchar** params = NULL;
+ const gchar* _tmp0_ = NULL;
+ const gchar* _tmp1_ = NULL;
+ gchar** _tmp2_ = NULL;
+ gchar** _tmp3_ = NULL;
+ gint params_length1 = 0;
+ gint _params_size_ = 0;
+ gchar** _tmp4_ = NULL;
+ gint _tmp4__length1 = 0;
+ gboolean _tmp5_ = FALSE;
+ gchar** _tmp7_ = NULL;
+ gint _tmp7__length1 = 0;
+ const gchar* _tmp8_ = NULL;
+ gint _tmp9_ = 0;
+ gchar** _tmp10_ = NULL;
+ gint _tmp10__length1 = 0;
+ const gchar* _tmp11_ = NULL;
+ gint _tmp12_ = 0;
+ gchar** textaccel = NULL;
+ gchar** _tmp13_ = NULL;
+ gint _tmp13__length1 = 0;
+ const gchar* _tmp14_ = NULL;
+ gchar** _tmp15_ = NULL;
+ gchar** _tmp16_ = NULL;
+ gint textaccel_length1 = 0;
+ gint _textaccel_size_ = 0;
+ gchar** _tmp17_ = NULL;
+ gint _tmp17__length1 = 0;
+ const gchar* _tmp18_ = NULL;
+ gchar* _tmp19_ = NULL;
+ gchar** _tmp20_ = NULL;
+ gint _tmp20__length1 = 0;
+ gchar** _tmp24_ = NULL;
+ gint _tmp24__length1 = 0;
+ const gchar* _tmp25_ = NULL;
+ gint _tmp26_ = 0;
+ SpiceCtrlMenu* _tmp27_ = NULL;
+ GError * _inner_error_ = NULL;
+ g_return_val_if_fail (str != NULL, NULL);
+ self = (SpiceCtrlMenuItem*) g_object_new (object_type, NULL);
+ _tmp0_ = str;
+ _tmp1_ = CONTROLLER_MENU_PARAM_DELIMITER;
+ _tmp3_ = _tmp2_ = g_strsplit (_tmp0_, _tmp1_, 0);
+ params = _tmp3_;
+ params_length1 = _vala_array_length (_tmp2_);
+ _params_size_ = params_length1;
+ _tmp4_ = params;
+ _tmp4__length1 = params_length1;
+ _tmp5_ = g_warn_if (_tmp4__length1 != 5);
+ if (_tmp5_) {
+ GError* _tmp6_ = NULL;
+ _tmp6_ = g_error_new_literal (SPICE_CTRL_ERROR, SPICE_CTRL_ERROR_VALUE, "");
+ _inner_error_ = _tmp6_;
+ if (_inner_error_->domain == SPICE_CTRL_ERROR) {
+ g_propagate_error (error, _inner_error_);
+ params = (_vala_array_free (params, params_length1, (GDestroyNotify) g_free), NULL);
+ _g_object_unref0 (self);
+ return NULL;
+ } else {
+ params = (_vala_array_free (params, params_length1, (GDestroyNotify) g_free), NULL);
+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
+ g_clear_error (&_inner_error_);
+ return NULL;
+ }
+ }
+ _tmp7_ = params;
+ _tmp7__length1 = params_length1;
+ _tmp8_ = _tmp7_[0];
+ _tmp9_ = atoi (_tmp8_);
+ self->parent_id = _tmp9_;
+ _tmp10_ = params;
+ _tmp10__length1 = params_length1;
+ _tmp11_ = _tmp10_[1];
+ _tmp12_ = atoi (_tmp11_);
+ self->id = _tmp12_;
+ _tmp13_ = params;
+ _tmp13__length1 = params_length1;
+ _tmp14_ = _tmp13_[2];
+ _tmp16_ = _tmp15_ = g_strsplit (_tmp14_, "\t", 0);
+ textaccel = _tmp16_;
+ textaccel_length1 = _vala_array_length (_tmp15_);
+ _textaccel_size_ = textaccel_length1;
+ _tmp17_ = textaccel;
+ _tmp17__length1 = textaccel_length1;
+ _tmp18_ = _tmp17_[0];
+ _tmp19_ = g_strdup (_tmp18_);
+ _g_free0 (self->text);
+ self->text = _tmp19_;
+ _tmp20_ = textaccel;
+ _tmp20__length1 = textaccel_length1;
+ if (_tmp20__length1 > 1) {
+ gchar** _tmp21_ = NULL;
+ gint _tmp21__length1 = 0;
+ const gchar* _tmp22_ = NULL;
+ gchar* _tmp23_ = NULL;
+ _tmp21_ = textaccel;
+ _tmp21__length1 = textaccel_length1;
+ _tmp22_ = _tmp21_[1];
+ _tmp23_ = g_strdup (_tmp22_);
+ _g_free0 (self->accel);
+ self->accel = _tmp23_;
+ }
+ _tmp24_ = params;
+ _tmp24__length1 = params_length1;
+ _tmp25_ = _tmp24_[3];
+ _tmp26_ = atoi (_tmp25_);
+ self->flags = (unsigned int) _tmp26_;
+ _tmp27_ = spice_ctrl_menu_new ();
+ _g_object_unref0 (self->submenu);
+ self->submenu = _tmp27_;
+ textaccel = (_vala_array_free (textaccel, textaccel_length1, (GDestroyNotify) g_free), NULL);
+ params = (_vala_array_free (params, params_length1, (GDestroyNotify) g_free), NULL);
+ return self;
+}
+
+
+SpiceCtrlMenuItem* spice_ctrl_menu_item_new_from_string (const gchar* str, GError** error) {
+ return spice_ctrl_menu_item_construct_from_string (SPICE_CTRL_TYPE_MENU_ITEM, str, error);
+}
+
+
+static const gchar* string_to_string (const gchar* self) {
+ const gchar* result = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ result = self;
+ return result;
+}
+
+
+static const char* _spice_protocol_controller_menu_flags_to_string (unsigned int value) {
+ switch (value) {
+ case CONTROLLER_MENU_FLAGS_SEPARATOR:
+ return "CONTROLLER_MENU_FLAGS_SEPARATOR";
+ case CONTROLLER_MENU_FLAGS_DISABLED:
+ return "CONTROLLER_MENU_FLAGS_DISABLED";
+ case CONTROLLER_MENU_FLAGS_POPUP:
+ return "CONTROLLER_MENU_FLAGS_POPUP";
+ case CONTROLLER_MENU_FLAGS_CHECKED:
+ return "CONTROLLER_MENU_FLAGS_CHECKED";
+ case CONTROLLER_MENU_FLAGS_GRAYED:
+ return "CONTROLLER_MENU_FLAGS_GRAYED";
+ }
+ return NULL;
+}
+
+
+gchar* spice_ctrl_menu_item_to_string (SpiceCtrlMenuItem* self) {
+ gchar* result = NULL;
+ gchar* sub = NULL;
+ SpiceCtrlMenu* _tmp0_ = NULL;
+ gchar* _tmp1_ = NULL;
+ gchar* str = NULL;
+ gint _tmp2_ = 0;
+ gchar* _tmp3_ = NULL;
+ gchar* _tmp4_ = NULL;
+ gint _tmp5_ = 0;
+ gchar* _tmp6_ = NULL;
+ gchar* _tmp7_ = NULL;
+ const gchar* _tmp8_ = NULL;
+ const gchar* _tmp9_ = NULL;
+ unsigned int _tmp10_ = 0;
+ const gchar* _tmp11_ = NULL;
+ gchar* _tmp12_ = NULL;
+ gchar* _tmp13_ = NULL;
+ const gchar* _tmp14_ = NULL;
+ const gchar* _tmp15_ = NULL;
+ gchar** _tmp16_ = NULL;
+ gchar** _tmp17_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = self->submenu;
+ _tmp1_ = spice_ctrl_menu_to_string (_tmp0_);
+ sub = _tmp1_;
+ _tmp2_ = self->parent_id;
+ _tmp3_ = g_strdup_printf ("%i", _tmp2_);
+ _tmp4_ = _tmp3_;
+ _tmp5_ = self->id;
+ _tmp6_ = g_strdup_printf ("%i", _tmp5_);
+ _tmp7_ = _tmp6_;
+ _tmp8_ = self->text;
+ _tmp9_ = string_to_string (_tmp8_);
+ _tmp10_ = self->flags;
+ _tmp11_ = _spice_protocol_controller_menu_flags_to_string (_tmp10_);
+ _tmp12_ = g_strconcat ("pid: ", _tmp4_, ", id: ", _tmp7_, ", text: \"", _tmp9_, "\", flags: ", _tmp11_, NULL);
+ _tmp13_ = _tmp12_;
+ _g_free0 (_tmp7_);
+ _g_free0 (_tmp4_);
+ str = _tmp13_;
+ _tmp14_ = sub;
+ _tmp15_ = string_to_string (_tmp14_);
+ _tmp17_ = _tmp16_ = g_strsplit (_tmp15_, "\n", 0);
+ {
+ gchar** l_collection = NULL;
+ gint l_collection_length1 = 0;
+ gint _l_collection_size_ = 0;
+ gint l_it = 0;
+ l_collection = _tmp17_;
+ l_collection_length1 = _vala_array_length (_tmp16_);
+ for (l_it = 0; l_it < _vala_array_length (_tmp16_); l_it = l_it + 1) {
+ gchar* _tmp18_ = NULL;
+ gchar* l = NULL;
+ _tmp18_ = g_strdup (l_collection[l_it]);
+ l = _tmp18_;
+ {
+ const gchar* _tmp19_ = NULL;
+ const gchar* _tmp20_ = NULL;
+ const gchar* _tmp21_ = NULL;
+ const gchar* _tmp22_ = NULL;
+ gchar* _tmp23_ = NULL;
+ gchar* _tmp24_ = NULL;
+ gchar* _tmp25_ = NULL;
+ _tmp19_ = l;
+ if (g_strcmp0 (_tmp19_, "") == 0) {
+ _g_free0 (l);
+ continue;
+ }
+ _tmp20_ = str;
+ _tmp21_ = l;
+ _tmp22_ = string_to_string (_tmp21_);
+ _tmp23_ = g_strconcat ("\n ", _tmp22_, NULL);
+ _tmp24_ = _tmp23_;
+ _tmp25_ = g_strconcat (_tmp20_, _tmp24_, NULL);
+ _g_free0 (str);
+ str = _tmp25_;
+ _g_free0 (_tmp24_);
+ _g_free0 (l);
+ }
+ }
+ l_collection = (_vala_array_free (l_collection, l_collection_length1, (GDestroyNotify) g_free), NULL);
+ }
+ result = str;
+ _g_free0 (sub);
+ return result;
+}
+
+
+static void spice_ctrl_menu_item_class_init (SpiceCtrlMenuItemClass * klass) {
+ spice_ctrl_menu_item_parent_class = g_type_class_peek_parent (klass);
+ G_OBJECT_CLASS (klass)->finalize = spice_ctrl_menu_item_finalize;
+}
+
+
+static void spice_ctrl_menu_item_instance_init (SpiceCtrlMenuItem * self) {
+}
+
+
+static void spice_ctrl_menu_item_finalize (GObject* obj) {
+ SpiceCtrlMenuItem * self;
+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, SPICE_CTRL_TYPE_MENU_ITEM, SpiceCtrlMenuItem);
+ _g_object_unref0 (self->submenu);
+ _g_free0 (self->text);
+ _g_free0 (self->accel);
+ G_OBJECT_CLASS (spice_ctrl_menu_item_parent_class)->finalize (obj);
+}
+
+
+GType spice_ctrl_menu_item_get_type (void) {
+ static volatile gsize spice_ctrl_menu_item_type_id__volatile = 0;
+ if (g_once_init_enter (&spice_ctrl_menu_item_type_id__volatile)) {
+ static const GTypeInfo g_define_type_info = { sizeof (SpiceCtrlMenuItemClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) spice_ctrl_menu_item_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SpiceCtrlMenuItem), 0, (GInstanceInitFunc) spice_ctrl_menu_item_instance_init, NULL };
+ GType spice_ctrl_menu_item_type_id;
+ spice_ctrl_menu_item_type_id = g_type_register_static (G_TYPE_OBJECT, "SpiceCtrlMenuItem", &g_define_type_info, 0);
+ g_once_init_leave (&spice_ctrl_menu_item_type_id__volatile, spice_ctrl_menu_item_type_id);
+ }
+ return spice_ctrl_menu_item_type_id__volatile;
+}
+
+
+static void _g_object_unref0_ (gpointer var) {
+ (var == NULL) ? NULL : (var = (g_object_unref (var), NULL));
+}
+
+
+static void _g_list_free__g_object_unref0_ (GList* self) {
+ g_list_foreach (self, (GFunc) _g_object_unref0_, NULL);
+ g_list_free (self);
+}
+
+
+static gpointer _g_object_ref0 (gpointer self) {
+ return self ? g_object_ref (self) : NULL;
+}
+
+
+SpiceCtrlMenu* spice_ctrl_menu_find_id (SpiceCtrlMenu* self, gint id) {
+ SpiceCtrlMenu* result = NULL;
+ gint _tmp0_ = 0;
+ GList* _tmp2_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = id;
+ if (_tmp0_ == 0) {
+ SpiceCtrlMenu* _tmp1_ = NULL;
+ _tmp1_ = _g_object_ref0 (self);
+ result = _tmp1_;
+ return result;
+ }
+ _tmp2_ = self->items;
+ {
+ GList* item_collection = NULL;
+ GList* item_it = NULL;
+ item_collection = _tmp2_;
+ for (item_it = item_collection; item_it != NULL; item_it = item_it->next) {
+ SpiceCtrlMenuItem* _tmp3_ = NULL;
+ SpiceCtrlMenuItem* item = NULL;
+ _tmp3_ = _g_object_ref0 ((SpiceCtrlMenuItem*) item_it->data);
+ item = _tmp3_;
+ {
+ SpiceCtrlMenuItem* _tmp4_ = NULL;
+ gint _tmp5_ = 0;
+ gint _tmp6_ = 0;
+ SpiceCtrlMenu* menu = NULL;
+ SpiceCtrlMenuItem* _tmp10_ = NULL;
+ SpiceCtrlMenu* _tmp11_ = NULL;
+ gint _tmp12_ = 0;
+ SpiceCtrlMenu* _tmp13_ = NULL;
+ SpiceCtrlMenu* _tmp14_ = NULL;
+ _tmp4_ = item;
+ _tmp5_ = _tmp4_->id;
+ _tmp6_ = id;
+ if (_tmp5_ == _tmp6_) {
+ SpiceCtrlMenuItem* _tmp7_ = NULL;
+ SpiceCtrlMenu* _tmp8_ = NULL;
+ SpiceCtrlMenu* _tmp9_ = NULL;
+ _tmp7_ = item;
+ _tmp8_ = _tmp7_->submenu;
+ _tmp9_ = _g_object_ref0 (_tmp8_);
+ result = _tmp9_;
+ _g_object_unref0 (item);
+ return result;
+ }
+ _tmp10_ = item;
+ _tmp11_ = _tmp10_->submenu;
+ _tmp12_ = id;
+ _tmp13_ = spice_ctrl_menu_find_id (_tmp11_, _tmp12_);
+ menu = _tmp13_;
+ _tmp14_ = menu;
+ if (_tmp14_ != NULL) {
+ result = menu;
+ _g_object_unref0 (item);
+ return result;
+ }
+ _g_object_unref0 (menu);
+ _g_object_unref0 (item);
+ }
+ }
+ }
+ result = NULL;
+ return result;
+}
+
+
+SpiceCtrlMenu* spice_ctrl_menu_construct_from_string (GType object_type, const gchar* str) {
+ SpiceCtrlMenu * self = NULL;
+ const gchar* _tmp0_ = NULL;
+ const gchar* _tmp1_ = NULL;
+ gchar** _tmp2_ = NULL;
+ gchar** _tmp3_ = NULL;
+ GError * _inner_error_ = NULL;
+ g_return_val_if_fail (str != NULL, NULL);
+ self = (SpiceCtrlMenu*) g_object_new (object_type, NULL);
+ _tmp0_ = str;
+ _tmp1_ = CONTROLLER_MENU_ITEM_DELIMITER;
+ _tmp3_ = _tmp2_ = g_strsplit (_tmp0_, _tmp1_, 0);
+ {
+ gchar** itemstr_collection = NULL;
+ gint itemstr_collection_length1 = 0;
+ gint _itemstr_collection_size_ = 0;
+ gint itemstr_it = 0;
+ itemstr_collection = _tmp3_;
+ itemstr_collection_length1 = _vala_array_length (_tmp2_);
+ for (itemstr_it = 0; itemstr_it < _vala_array_length (_tmp2_); itemstr_it = itemstr_it + 1) {
+ gchar* _tmp4_ = NULL;
+ gchar* itemstr = NULL;
+ _tmp4_ = g_strdup (itemstr_collection[itemstr_it]);
+ itemstr = _tmp4_;
+ {
+ {
+ const gchar* _tmp5_ = NULL;
+ gint _tmp6_ = 0;
+ gint _tmp7_ = 0;
+ SpiceCtrlMenuItem* item = NULL;
+ const gchar* _tmp8_ = NULL;
+ SpiceCtrlMenuItem* _tmp9_ = NULL;
+ SpiceCtrlMenu* parent = NULL;
+ SpiceCtrlMenuItem* _tmp10_ = NULL;
+ gint _tmp11_ = 0;
+ SpiceCtrlMenu* _tmp12_ = NULL;
+ SpiceCtrlMenu* _tmp13_ = NULL;
+ SpiceCtrlMenu* _tmp15_ = NULL;
+ SpiceCtrlMenuItem* _tmp16_ = NULL;
+ SpiceCtrlMenuItem* _tmp17_ = NULL;
+ _tmp5_ = itemstr;
+ _tmp6_ = strlen (_tmp5_);
+ _tmp7_ = _tmp6_;
+ if (_tmp7_ == 0) {
+ _g_free0 (itemstr);
+ continue;
+ }
+ _tmp8_ = itemstr;
+ _tmp9_ = spice_ctrl_menu_item_new_from_string (_tmp8_, &_inner_error_);
+ item = _tmp9_;
+ if (G_UNLIKELY (_inner_error_ != NULL)) {
+ if (_inner_error_->domain == SPICE_CTRL_ERROR) {
+ goto __catch0_spice_ctrl_error;
+ }
+ _g_free0 (itemstr);
+ itemstr_collection = (_vala_array_free (itemstr_collection, itemstr_collection_length1, (GDestroyNotify) g_free), NULL);
+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
+ g_clear_error (&_inner_error_);
+ return NULL;
+ }
+ _tmp10_ = item;
+ _tmp11_ = _tmp10_->parent_id;
+ _tmp12_ = spice_ctrl_menu_find_id (self, _tmp11_);
+ parent = _tmp12_;
+ _tmp13_ = parent;
+ if (_tmp13_ == NULL) {
+ GError* _tmp14_ = NULL;
+ _tmp14_ = g_error_new_literal (SPICE_CTRL_ERROR, SPICE_CTRL_ERROR_VALUE, "Invalid parent menu id");
+ _inner_error_ = _tmp14_;
+ _g_object_unref0 (parent);
+ _g_object_unref0 (item);
+ if (_inner_error_->domain == SPICE_CTRL_ERROR) {
+ goto __catch0_spice_ctrl_error;
+ }
+ _g_object_unref0 (parent);
+ _g_object_unref0 (item);
+ _g_free0 (itemstr);
+ itemstr_collection = (_vala_array_free (itemstr_collection, itemstr_collection_length1, (GDestroyNotify) g_free), NULL);
+ g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
+ g_clear_error (&_inner_error_);
+ return NULL;
+ }
+ _tmp15_ = parent;
+ _tmp16_ = item;
+ _tmp17_ = _g_object_ref0 (_tmp16_);
+ _tmp15_->items = g_list_append (_tmp15_->items, _tmp17_);
+ _g_object_unref0 (parent);
+ _g_object_unref0 (item);
+ }
+ goto __finally0;
+ __catch0_spice_ctrl_error:
+ {
+ GError* e = NULL;
+ GError* _tmp18_ = NULL;
+ const gchar* _tmp19_ = NULL;
+ e = _inner_error_;
+ _inner_error_ = NULL;
+ _tmp18_ = e;
+ _tmp19_ = _tmp18_->message;
+ g_warning ("menu.vala:95: %s", _tmp19_);
+ _g_error_free0 (e);
+ }
+ __finally0:
+ if (G_UNLIKELY (_inner_error_ != NULL)) {
+ _g_free0 (itemstr);
+ itemstr_collection = (_vala_array_free (itemstr_collection, itemstr_collection_length1, (GDestroyNotify) g_free), NULL);
+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
+ g_clear_error (&_inner_error_);
+ return NULL;
+ }
+ _g_free0 (itemstr);
+ }
+ }
+ itemstr_collection = (_vala_array_free (itemstr_collection, itemstr_collection_length1, (GDestroyNotify) g_free), NULL);
+ }
+ return self;
+}
+
+
+SpiceCtrlMenu* spice_ctrl_menu_new_from_string (const gchar* str) {
+ return spice_ctrl_menu_construct_from_string (SPICE_CTRL_TYPE_MENU, str);
+}
+
+
+gchar* spice_ctrl_menu_to_string (SpiceCtrlMenu* self) {
+ gchar* result = NULL;
+ gchar* str = NULL;
+ gchar* _tmp0_ = NULL;
+ GList* _tmp1_ = NULL;
+ g_return_val_if_fail (self != NULL, NULL);
+ _tmp0_ = g_strdup ("");
+ str = _tmp0_;
+ _tmp1_ = self->items;
+ {
+ GList* i_collection = NULL;
+ GList* i_it = NULL;
+ i_collection = _tmp1_;
+ for (i_it = i_collection; i_it != NULL; i_it = i_it->next) {
+ SpiceCtrlMenuItem* _tmp2_ = NULL;
+ SpiceCtrlMenuItem* i = NULL;
+ _tmp2_ = _g_object_ref0 ((SpiceCtrlMenuItem*) i_it->data);
+ i = _tmp2_;
+ {
+ const gchar* _tmp3_ = NULL;
+ SpiceCtrlMenuItem* _tmp4_ = NULL;
+ gchar* _tmp5_ = NULL;
+ gchar* _tmp6_ = NULL;
+ gchar* _tmp7_ = NULL;
+ gchar* _tmp8_ = NULL;
+ gchar* _tmp9_ = NULL;
+ _tmp3_ = str;
+ _tmp4_ = i;
+ _tmp5_ = spice_ctrl_menu_item_to_string (_tmp4_);
+ _tmp6_ = _tmp5_;
+ _tmp7_ = g_strconcat ("\n", _tmp6_, NULL);
+ _tmp8_ = _tmp7_;
+ _tmp9_ = g_strconcat (_tmp3_, _tmp8_, NULL);
+ _g_free0 (str);
+ str = _tmp9_;
+ _g_free0 (_tmp8_);
+ _g_free0 (_tmp6_);
+ _g_object_unref0 (i);
+ }
+ }
+ }
+ result = str;
+ return result;
+}
+
+
+SpiceCtrlMenu* spice_ctrl_menu_construct (GType object_type) {
+ SpiceCtrlMenu * self = NULL;
+ self = (SpiceCtrlMenu*) g_object_new (object_type, NULL);
+ return self;
+}
+
+
+SpiceCtrlMenu* spice_ctrl_menu_new (void) {
+ return spice_ctrl_menu_construct (SPICE_CTRL_TYPE_MENU);
+}
+
+
+static void spice_ctrl_menu_class_init (SpiceCtrlMenuClass * klass) {
+ spice_ctrl_menu_parent_class = g_type_class_peek_parent (klass);
+ G_OBJECT_CLASS (klass)->finalize = spice_ctrl_menu_finalize;
+}
+
+
+static void spice_ctrl_menu_instance_init (SpiceCtrlMenu * self) {
+}
+
+
+static void spice_ctrl_menu_finalize (GObject* obj) {
+ SpiceCtrlMenu * self;
+ self = G_TYPE_CHECK_INSTANCE_CAST (obj, SPICE_CTRL_TYPE_MENU, SpiceCtrlMenu);
+ __g_list_free__g_object_unref0_0 (self->items);
+ G_OBJECT_CLASS (spice_ctrl_menu_parent_class)->finalize (obj);
+}
+
+
+GType spice_ctrl_menu_get_type (void) {
+ static volatile gsize spice_ctrl_menu_type_id__volatile = 0;
+ if (g_once_init_enter (&spice_ctrl_menu_type_id__volatile)) {
+ static const GTypeInfo g_define_type_info = { sizeof (SpiceCtrlMenuClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) spice_ctrl_menu_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SpiceCtrlMenu), 0, (GInstanceInitFunc) spice_ctrl_menu_instance_init, NULL };
+ GType spice_ctrl_menu_type_id;
+ spice_ctrl_menu_type_id = g_type_register_static (G_TYPE_OBJECT, "SpiceCtrlMenu", &g_define_type_info, 0);
+ g_once_init_leave (&spice_ctrl_menu_type_id__volatile, spice_ctrl_menu_type_id);
+ }
+ return spice_ctrl_menu_type_id__volatile;
+}
+
+
+static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
+ if ((array != NULL) && (destroy_func != NULL)) {
+ int i;
+ for (i = 0; i < array_length; i = i + 1) {
+ if (((gpointer*) array)[i] != NULL) {
+ destroy_func (((gpointer*) array)[i]);
+ }
+ }
+ }
+}
+
+
+static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) {
+ _vala_array_destroy (array, array_length, destroy_func);
+ g_free (array);
+}
+
+
+static gint _vala_array_length (gpointer array) {
+ int length;
+ length = 0;
+ if (array) {
+ while (((gpointer*) array)[length]) {
+ length++;
+ }
+ }
+ return length;
+}
+
+
+
--- /dev/null
+// Copyright (C) 2011 Red Hat, Inc.
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+using GLib;
+using Custom;
+using SpiceProtocol.Controller;
+
+namespace SpiceCtrl {
+
+public class MenuItem: Object {
+
+ public Menu submenu;
+ public int parent_id;
+ public int id;
+ public string text;
+ public string accel;
+ public SpiceProtocol.Controller.MenuFlags flags;
+
+ public MenuItem (int id, string text, SpiceProtocol.Controller.MenuFlags flags) {
+ this.id = id;
+ this.text = text;
+ this.flags = flags;
+ }
+
+ public MenuItem.from_string (string str) throws SpiceCtrl.Error {
+ var params = str.split (SpiceProtocol.Controller.MENU_PARAM_DELIMITER);
+ if (warn_if (params.length != 5))
+ throw new SpiceCtrl.Error.VALUE(""); /* Vala: why is it mandatory to give a string? */
+ parent_id = int.parse (params[0]);
+ id = int.parse (params[1]);
+ var textaccel = params[2].split ("\t");
+ text = textaccel[0];
+ if (textaccel.length > 1)
+ accel = textaccel[1];
+ flags = (SpiceProtocol.Controller.MenuFlags)int.parse (params[3]);
+
+ submenu = new Menu ();
+ }
+
+ public string to_string () {
+ var sub = submenu.to_string ();
+ var str = @"pid: $parent_id, id: $id, text: \"$text\", flags: $flags";
+ foreach (var l in sub.to_string ().split ("\n")) {
+ if (l == "")
+ continue;
+ str += @"\n $l";
+ }
+ return str;
+ }
+}
+
+public class Menu: Object {
+
+ public List<MenuItem> items;
+
+ public Menu? find_id (int id) {
+ if (id == 0)
+ return this;
+
+ foreach (var item in items) {
+ if (item.id == id)
+ return item.submenu;
+
+ var menu = item.submenu.find_id (id);
+ if (menu != null)
+ return menu;
+ }
+
+ return null;
+ }
+
+ public Menu.from_string (string str) {
+ foreach (var itemstr in str.split (SpiceProtocol.Controller.MENU_ITEM_DELIMITER)) {
+ try {
+ if (itemstr.length == 0)
+ continue;
+ var item = new MenuItem.from_string (itemstr);
+ var parent = find_id (item.parent_id);
+ if (parent == null)
+ throw new SpiceCtrl.Error.VALUE("Invalid parent menu id");
+ parent.items.append (item);
+ } catch (SpiceCtrl.Error e) {
+ warning (e.message);
+ }
+ }
+ }
+
+ public string to_string () {
+ var str = "";
+ foreach (var i in items)
+ str += @"\n$i";
+ return str;
+ }
+}
+
+} // SpiceCtrl
--- /dev/null
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+#include "namedpipe.h"
+
+#include <windows.h>
+#include <stdio.h>
+#include <conio.h>
+#include <tchar.h>
+
+static void spice_named_pipe_initable_iface_init (GInitableIface *iface);
+static gboolean spice_named_pipe_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error);
+
+G_DEFINE_TYPE_WITH_CODE (SpiceNamedPipe, spice_named_pipe, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ spice_named_pipe_initable_iface_init));
+
+enum
+{
+ PROP_0,
+ PROP_NAME,
+ PROP_HANDLE,
+};
+
+struct _SpiceNamedPipePrivate
+{
+ gchar * name;
+ GError * construct_error;
+ guint inited : 1;
+ HANDLE handle;
+};
+
+static void
+spice_named_pipe_finalize (GObject *object)
+{
+ SpiceNamedPipe *np = SPICE_NAMED_PIPE (object);
+
+ g_clear_error (&np->priv->construct_error);
+
+ g_free (np->priv->name);
+ np->priv->name = NULL;
+
+ if (np->priv->handle)
+ {
+ CloseHandle (np->priv->handle);
+ np->priv->handle = NULL;
+ }
+
+ if (G_OBJECT_CLASS (spice_named_pipe_parent_class)->finalize)
+ G_OBJECT_CLASS (spice_named_pipe_parent_class)->finalize (object);
+}
+
+#define DEFAULT_PIPE_BUF_SIZE 4096
+
+static void
+spice_named_pipe_constructed (GObject *object)
+{
+ SpiceNamedPipe *np = SPICE_NAMED_PIPE (object);
+
+ if (np->priv->handle)
+ /* TODO: find a way to ensure user provided handle is a named
+ pipe, in overlapped mode */
+ goto end;
+
+ np->priv->handle = CreateNamedPipe (np->priv->name,
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ PIPE_UNLIMITED_INSTANCES,
+ DEFAULT_PIPE_BUF_SIZE, DEFAULT_PIPE_BUF_SIZE,
+ 0, NULL);
+
+ if (np->priv->handle == INVALID_HANDLE_VALUE)
+ {
+ int errsv = GetLastError ();
+ gchar *emsg = g_win32_error_message (errsv);
+
+ g_set_error (&np->priv->construct_error,
+ G_IO_ERROR,
+ g_io_error_from_win32_error (errsv),
+ "Error CreateNamedPipe(): %s",
+ emsg);
+
+ g_free (emsg);
+ return;
+ }
+
+ /* TODO: we could have a client backlog by creating many pipes, the
+ maximum number of outstanding connections.. or we could just let
+ the named_pipe_listener take multiple NamedPipe instances */
+end:
+ g_assert (np->priv->handle != INVALID_HANDLE_VALUE);
+ return;
+}
+
+static void
+spice_named_pipe_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceNamedPipe *np = SPICE_NAMED_PIPE (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ g_value_set_string (value, np->priv->name);
+ break;
+ case PROP_HANDLE:
+ g_value_set_pointer (value, np->priv->handle);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+spice_named_pipe_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceNamedPipe *np = SPICE_NAMED_PIPE (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ g_free (np->priv->name);
+ np->priv->name = g_value_dup_string (value);
+ break;
+ case PROP_HANDLE:
+ np->priv->handle = g_value_get_pointer (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+spice_named_pipe_class_init (SpiceNamedPipeClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (SpiceNamedPipePrivate));
+
+ gobject_class->set_property = spice_named_pipe_set_property;
+ gobject_class->get_property = spice_named_pipe_get_property;
+ gobject_class->finalize = spice_named_pipe_finalize;
+ gobject_class->constructed = spice_named_pipe_constructed;
+
+ g_object_class_install_property (gobject_class, PROP_NAME,
+ g_param_spec_string ("name",
+ "Pipe Name",
+ "The NamedPipe name",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_HANDLE,
+ g_param_spec_pointer ("handle",
+ "Pipe handle",
+ "The pipe handle",
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+spice_named_pipe_init (SpiceNamedPipe *np)
+{
+ np->priv = G_TYPE_INSTANCE_GET_PRIVATE (np,
+ SPICE_TYPE_NAMED_PIPE,
+ SpiceNamedPipePrivate);
+}
+
+static gboolean
+spice_named_pipe_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SpiceNamedPipe *np;
+
+ g_return_val_if_fail (SPICE_IS_NAMED_PIPE (initable), FALSE);
+
+ np = SPICE_NAMED_PIPE (initable);
+
+ if (cancellable != NULL)
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "Cancellable initialization not supported");
+ return FALSE;
+ }
+
+ np->priv->inited = TRUE;
+
+ if (np->priv->construct_error)
+ {
+ if (error)
+ *error = g_error_copy (np->priv->construct_error);
+ return FALSE;
+ }
+
+
+ return TRUE;
+}
+
+static void
+spice_named_pipe_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = spice_named_pipe_initable_init;
+}
+
+SpiceNamedPipe *
+spice_named_pipe_new (const gchar *name, GError **error)
+{
+ return SPICE_NAMED_PIPE (g_initable_new (SPICE_TYPE_NAMED_PIPE,
+ NULL, error,
+ "name", name,
+ NULL));
+}
+
+void *
+spice_named_pipe_get_handle (SpiceNamedPipe *namedpipe)
+{
+ g_return_val_if_fail (SPICE_IS_NAMED_PIPE (namedpipe), NULL);
+
+ return namedpipe->priv->handle;
+}
+
+gboolean
+spice_named_pipe_close (SpiceNamedPipe *np,
+ GError **error)
+{
+ BOOL res;
+
+ g_return_val_if_fail (SPICE_IS_NAMED_PIPE (np), FALSE);
+
+ res = CloseHandle (np->priv->handle);
+ np->priv->handle = NULL;
+ if (!res)
+ {
+ int errsv = GetLastError ();
+ gchar *emsg = g_win32_error_message (errsv);
+
+ g_set_error (error, G_IO_ERROR,
+ g_io_error_from_win32_error (errsv),
+ "Error closing handle: %s",
+ emsg);
+ g_free (emsg);
+ return FALSE;
+ }
+
+ return TRUE;
+}
--- /dev/null
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __NAMED_PIPE_H__
+#define __NAMED_PIPE_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_NAMED_PIPE (spice_named_pipe_get_type ())
+#define SPICE_NAMED_PIPE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+ SPICE_TYPE_NAMED_PIPE, SpiceNamedPipe))
+#define SPICE_NAMED_PIPE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
+ SPICE_TYPE_NAMED_PIPE, SpiceNamedPipeClass))
+#define SPICE_IS_NAMED_PIPE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
+ SPICE_TYPE_NAMED_PIPE))
+#define SPICE_IS_NAMED_PIPE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
+ SPICE_TYPE_NAMED_PIPE))
+#define SPICE_NAMED_PIPE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \
+ SPICE_TYPE_NAMED_PIPE, SpiceNamedPipeClass))
+
+typedef struct _SpiceNamedPipe SpiceNamedPipe;
+typedef struct _SpiceNamedPipePrivate SpiceNamedPipePrivate;
+typedef struct _SpiceNamedPipeClass SpiceNamedPipeClass;
+
+struct _SpiceNamedPipeClass
+{
+ GObjectClass parent_class;
+};
+
+struct _SpiceNamedPipe
+{
+ GObject parent_instance;
+ SpiceNamedPipePrivate *priv;
+};
+
+GType spice_named_pipe_get_type (void) G_GNUC_CONST;
+
+SpiceNamedPipe * spice_named_pipe_new (const gchar *name, GError **error);
+void * spice_named_pipe_get_handle(SpiceNamedPipe *namedpipe);
+gboolean spice_named_pipe_close (SpiceNamedPipe *namedpipe,
+ GError **error);
+G_END_DECLS
+
+#endif /* __NAMED_PIPE_H__ */
--- /dev/null
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+#include "namedpipeconnection.h"
+
+#include <windows.h>
+#include <stdio.h>
+#include <conio.h>
+#include <tchar.h>
+
+#include <gio/gwin32inputstream.h>
+#include <gio/gwin32outputstream.h>
+
+G_DEFINE_TYPE (SpiceNamedPipeConnection, spice_named_pipe_connection,
+ G_TYPE_IO_STREAM)
+
+enum
+{
+ PROP_0,
+ PROP_NAMED_PIPE,
+};
+
+struct _SpiceNamedPipeConnectionPrivate
+{
+ GInputStream *input_stream;
+ GOutputStream *output_stream;
+ SpiceNamedPipe *namedpipe;
+ gboolean in_dispose;
+};
+
+static void
+spice_named_pipe_connection_init (SpiceNamedPipeConnection *connection)
+{
+ connection->priv = G_TYPE_INSTANCE_GET_PRIVATE (connection,
+ SPICE_TYPE_NAMED_PIPE_CONNECTION,
+ SpiceNamedPipeConnectionPrivate);
+}
+
+static void
+spice_named_pipe_connection_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAMED_PIPE:
+ g_return_if_fail (c->priv->namedpipe == NULL);
+ g_value_set_object (value, c->priv->namedpipe);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+spice_named_pipe_connection_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_NAMED_PIPE:
+ c->priv->namedpipe = g_value_get_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static GInputStream *
+spice_named_pipe_connection_get_input_stream (GIOStream *io_stream)
+{
+ SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (io_stream);
+ HANDLE h = spice_named_pipe_get_handle (c->priv->namedpipe);
+
+ g_return_val_if_fail (h != NULL, NULL);
+
+ if (c->priv->input_stream == NULL)
+ c->priv->input_stream = g_win32_input_stream_new (h, FALSE);
+
+ return c->priv->input_stream;
+}
+
+static GOutputStream *
+spice_named_pipe_connection_get_output_stream (GIOStream *io_stream)
+{
+ SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (io_stream);
+ HANDLE h = spice_named_pipe_get_handle (c->priv->namedpipe);
+
+ g_return_val_if_fail (h != NULL, NULL);
+
+ if (c->priv->output_stream == NULL)
+ c->priv->output_stream = g_win32_output_stream_new (h, FALSE);
+
+ return c->priv->output_stream;
+}
+
+static void
+spice_named_pipe_connection_dispose (GObject *object)
+{
+ SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (object);
+
+ c->priv->in_dispose = TRUE;
+
+ if (G_OBJECT_CLASS (spice_named_pipe_connection_parent_class)->dispose)
+ G_OBJECT_CLASS (spice_named_pipe_connection_parent_class)->dispose (object);
+
+ c->priv->in_dispose = FALSE;
+}
+
+static void
+spice_named_pipe_connection_finalize (GObject *object)
+{
+ SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (object);
+
+ if (c->priv->output_stream)
+ {
+ g_object_unref (c->priv->output_stream);
+ c->priv->output_stream = NULL;
+ }
+
+ if (c->priv->input_stream)
+ {
+ g_object_unref (c->priv->input_stream);
+ c->priv->input_stream = NULL;
+ }
+
+ g_object_unref (c->priv->namedpipe);
+
+ if (G_OBJECT_CLASS (spice_named_pipe_connection_parent_class)->finalize)
+ G_OBJECT_CLASS (spice_named_pipe_connection_parent_class)->finalize (object);
+}
+
+static gboolean
+spice_named_pipe_connection_close (GIOStream *stream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SpiceNamedPipeConnection *c = SPICE_NAMED_PIPE_CONNECTION (stream);
+
+ if (c->priv->output_stream)
+ g_output_stream_close (c->priv->output_stream, cancellable, NULL);
+ if (c->priv->input_stream)
+ g_input_stream_close (c->priv->input_stream, cancellable, NULL);
+
+ /* Don't close the underlying socket if this is being called
+ * as part of dispose(); when destroying the GSocketConnection,
+ * we only want to close the socket if we're holding the last
+ * reference on it, and in that case it will close itself when
+ * we unref namedpipe in finalize().
+ */
+ if (c->priv->in_dispose)
+ return TRUE;
+
+ return spice_named_pipe_close (c->priv->namedpipe, error);
+}
+
+static void
+spice_named_pipe_connection_close_async (GIOStream *stream,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ GIOStreamClass *class;
+ GError *error;
+
+ class = G_IO_STREAM_GET_CLASS (stream);
+
+ /* namedpipe close is not blocking, just do it! */
+ error = NULL;
+ if (class->close_fn &&
+ !class->close_fn (stream, cancellable, &error))
+ {
+ g_simple_async_report_take_gerror_in_idle (G_OBJECT (stream),
+ callback, user_data,
+ error);
+ return;
+ }
+
+ res = g_simple_async_result_new (G_OBJECT (stream),
+ callback,
+ user_data,
+ spice_named_pipe_connection_close_async);
+ g_simple_async_result_complete_in_idle (res);
+ g_object_unref (res);
+}
+
+static gboolean
+spice_named_pipe_connection_close_finish (GIOStream *stream,
+ GAsyncResult *result,
+ GError **error)
+{
+ return TRUE;
+}
+
+static void
+spice_named_pipe_connection_class_init (SpiceNamedPipeConnectionClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (SpiceNamedPipeConnectionPrivate));
+
+ gobject_class->set_property = spice_named_pipe_connection_set_property;
+ gobject_class->get_property = spice_named_pipe_connection_get_property;
+ gobject_class->dispose = spice_named_pipe_connection_dispose;
+ gobject_class->finalize = spice_named_pipe_connection_finalize;
+
+ stream_class->get_input_stream = spice_named_pipe_connection_get_input_stream;
+ stream_class->get_output_stream = spice_named_pipe_connection_get_output_stream;
+ stream_class->close_fn = spice_named_pipe_connection_close;
+ stream_class->close_async = spice_named_pipe_connection_close_async;
+ stream_class->close_finish = spice_named_pipe_connection_close_finish;
+
+ g_object_class_install_property (gobject_class, PROP_NAMED_PIPE,
+ g_param_spec_object ("namedpipe",
+ "NamedPipe",
+ "The associated NamedPipe",
+ SPICE_TYPE_NAMED_PIPE,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+}
--- /dev/null
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __NAMED_PIPE_CONNECTION_H__
+#define __NAMED_PIPE_CONNECTION_H__
+
+#include <gio/gio.h>
+#include "namedpipe.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_NAMED_PIPE_CONNECTION (spice_named_pipe_connection_get_type ())
+#define SPICE_NAMED_PIPE_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+ SPICE_TYPE_NAMED_PIPE_CONNECTION, SpiceNamedPipeConnection))
+#define SPICE_NAMED_PIPE_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
+ SPICE_TYPE_NAMED_PIPE_CONNECTION, SpiceNamedPipeConnectionClass))
+#define SPICE_IS_NAMED_PIPE_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
+ SPICE_TYPE_NAMED_PIPE_CONNECTION))
+#define SPICE_IS_NAMED_PIPE_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
+ SPICE_TYPE_NAMED_PIPE_CONNECTION))
+#define SPICE_NAMED_PIPE_CONNECTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \
+ SPICE_TYPE_NAMED_PIPE_CONNECTION, SpiceNamedPipeConnectionClass))
+
+typedef struct _SpiceNamedPipeConnection SpiceNamedPipeConnection;
+typedef struct _SpiceNamedPipeConnectionPrivate SpiceNamedPipeConnectionPrivate;
+typedef struct _SpiceNamedPipeConnectionClass SpiceNamedPipeConnectionClass;
+
+struct _SpiceNamedPipeConnectionClass
+{
+ GIOStreamClass parent_class;
+};
+
+struct _SpiceNamedPipeConnection
+{
+ GIOStream parent_instance;
+ SpiceNamedPipeConnectionPrivate *priv;
+};
+
+GType spice_named_pipe_connection_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __NAMED_PIPE_CONNECTION_H__ */
--- /dev/null
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+#include "namedpipelistener.h"
+
+#include <windows.h>
+#include <stdio.h>
+#include <conio.h>
+#include <tchar.h>
+
+static GSource *g_win32_handle_source_add (HANDLE handle,
+ GSourceFunc callback,
+ gpointer user_data);
+
+G_DEFINE_TYPE (SpiceNamedPipeListener, spice_named_pipe_listener, G_TYPE_OBJECT);
+
+struct _SpiceNamedPipeListenerPrivate
+{
+ GQueue namedpipes;
+};
+
+static void
+spice_named_pipe_listener_dispose (GObject *object)
+{
+ SpiceNamedPipeListener *listener = SPICE_NAMED_PIPE_LISTENER (object);
+ SpiceNamedPipe *p;
+
+ while ((p = g_queue_pop_head (&listener->priv->namedpipes)) != NULL)
+ g_object_unref (p);
+
+ g_return_if_fail (g_queue_get_length (&listener->priv->namedpipes) == 0);
+ g_queue_clear (&listener->priv->namedpipes);
+
+ if (G_OBJECT_CLASS (spice_named_pipe_listener_parent_class)->dispose)
+ G_OBJECT_CLASS (spice_named_pipe_listener_parent_class)->dispose (object);
+}
+
+static void
+spice_named_pipe_listener_class_init (SpiceNamedPipeListenerClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (SpiceNamedPipeListenerPrivate));
+
+ gobject_class->dispose = spice_named_pipe_listener_dispose;
+}
+
+static void
+spice_named_pipe_listener_init (SpiceNamedPipeListener *listener)
+{
+ listener->priv = G_TYPE_INSTANCE_GET_PRIVATE (listener,
+ SPICE_TYPE_NAMED_PIPE_LISTENER,
+ SpiceNamedPipeListenerPrivate);
+
+ g_queue_init (&listener->priv->namedpipes);
+}
+
+void
+spice_named_pipe_listener_add_named_pipe (SpiceNamedPipeListener *listener,
+ SpiceNamedPipe *namedpipe)
+{
+ g_return_if_fail (SPICE_IS_NAMED_PIPE_LISTENER (listener));
+ g_return_if_fail (SPICE_IS_NAMED_PIPE (namedpipe));
+
+ g_queue_push_head (&listener->priv->namedpipes, g_object_ref (namedpipe));
+}
+
+typedef struct {
+ GCancellable *cancellable;
+ GSource *source;
+ GSimpleAsyncResult *async_result;
+ SpiceNamedPipe *np;
+ OVERLAPPED overlapped;
+} ConnectData;
+
+static void
+connect_cancelled (GCancellable *cancellable,
+ gpointer user_data)
+{
+ ConnectData *c = user_data;
+ GError *error = NULL;
+
+ g_source_destroy (c->source);
+ c->source = NULL;
+
+ g_cancellable_set_error_if_cancelled (cancellable, &error);
+ g_simple_async_result_set_from_error (c->async_result, error);
+ g_error_free (error);
+
+ g_simple_async_result_complete (c->async_result);
+ g_object_unref (c->async_result);
+}
+
+static gboolean
+connect_ready (gpointer user_data)
+{
+ ConnectData *c = user_data;
+ gulong cbret;
+ gboolean success;
+
+ /* Now complete the result (assuming it wasn't already completed) */
+ g_return_val_if_fail (c->async_result != NULL, FALSE);
+
+ success = GetOverlappedResult (c->np, &c->overlapped, &cbret, FALSE);
+ if (!success)
+ {
+ int errsv = GetLastError ();
+ gchar *emsg = g_win32_error_message (errsv);
+
+ g_simple_async_result_set_error (c->async_result,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ "GetOverlappedResult(): %s %d",
+ emsg, errsv);
+ g_free (emsg);
+ }
+
+ g_simple_async_result_complete (c->async_result);
+ g_object_unref (c->async_result); /* TODO: that sould free c? */
+
+ return FALSE;
+}
+
+static void
+connect_data_free (gpointer data)
+{
+ ConnectData *c = data;
+
+ if (c->source)
+ {
+ g_source_destroy (c->source);
+ g_source_unref (c->source);
+ c->source = NULL;
+ }
+ if (c->cancellable)
+ {
+ g_signal_handlers_disconnect_by_func (c->cancellable, connect_cancelled, c);
+ g_object_unref (c->cancellable);
+ c->cancellable = NULL;
+ }
+
+ if (c->async_result) /* this is only a weak reference */
+ c->async_result = NULL;
+
+ if (c->overlapped.hEvent != NULL)
+ {
+ CloseHandle (c->overlapped.hEvent);
+ c->overlapped.hEvent = NULL;
+ }
+
+ if (c->np != NULL)
+ {
+ g_object_unref (c->np);
+ c->np = NULL;
+ }
+
+ g_free (c);
+}
+
+void
+spice_named_pipe_listener_accept_async (SpiceNamedPipeListener *listener,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ ConnectData *c;
+ SpiceNamedPipe *namedpipe;
+
+ g_return_if_fail (SPICE_IS_NAMED_PIPE_LISTENER (listener));
+
+ namedpipe = SPICE_NAMED_PIPE (g_queue_pop_head (&listener->priv->namedpipes));
+ /* do not unref, we keep that ref */
+ g_return_if_fail (namedpipe != NULL);
+
+ c = g_new0 (ConnectData, 1);
+ c->np = namedpipe; /* transfer what used to be the avail_namedpipes ref */
+ c->async_result = g_simple_async_result_new (G_OBJECT (listener), callback, user_data,
+ spice_named_pipe_listener_accept_async);
+ c->overlapped.hEvent = CreateEvent (NULL, /* default security attribute */
+ TRUE, /* manual-reset event */
+ TRUE, /* initial state = signaled */
+ NULL); /* unnamed event object */
+ g_simple_async_result_set_op_res_gpointer (c->async_result, c, connect_data_free);
+
+ if (ConnectNamedPipe (spice_named_pipe_get_handle (namedpipe), &c->overlapped) != 0)
+ {
+ /* we shouldn't get there if the listener is in non-blocking */
+ g_warn_if_reached ();
+ }
+
+ switch (GetLastError ())
+ {
+ case ERROR_SUCCESS:
+ case ERROR_IO_PENDING:
+ break;
+ case ERROR_PIPE_CONNECTED:
+ g_simple_async_result_complete_in_idle (c->async_result);
+ g_object_unref (c->async_result);
+ return;
+ default:
+ g_simple_async_report_error_in_idle (G_OBJECT (listener),
+ callback, user_data,
+ G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ "ConnectNamedPipe() failed %ld", GetLastError ());
+ g_object_unref (c->async_result);
+ return;
+ }
+
+ c->source = g_win32_handle_source_add (c->overlapped.hEvent,
+ connect_ready, c);
+
+ if (cancellable)
+ {
+ c->cancellable = g_object_ref (cancellable);
+ g_signal_connect (cancellable, "cancelled",
+ G_CALLBACK (connect_cancelled), c);
+ }
+}
+
+SpiceNamedPipeConnection *
+spice_named_pipe_listener_accept_finish (SpiceNamedPipeListener *listener,
+ GAsyncResult *result,
+ GObject **source_object,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ ConnectData *c;
+ SpiceNamedPipeConnection *connection;
+
+ g_return_val_if_fail (SPICE_IS_NAMED_PIPE_LISTENER (listener), NULL);
+ g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (listener),
+ spice_named_pipe_listener_accept_async),
+ NULL);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ if (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
+
+ c = g_simple_async_result_get_op_res_gpointer (simple);
+
+ connection = g_object_new (SPICE_TYPE_NAMED_PIPE_CONNECTION,
+ "namedpipe", c->np,
+ NULL);
+ return connection;
+}
+
+SpiceNamedPipeListener *
+spice_named_pipe_listener_new (void)
+{
+ return g_object_new (SPICE_TYPE_NAMED_PIPE_LISTENER, NULL);
+}
+
+/* Windows HANDLE GSource - from gio/gwin32resolver.c */
+
+typedef struct {
+ GSource source;
+ GPollFD pollfd;
+} GWin32HandleSource;
+
+static gboolean
+g_win32_handle_source_prepare (GSource *source,
+ gint *timeout)
+{
+ *timeout = -1;
+ return FALSE;
+}
+
+static gboolean
+g_win32_handle_source_check (GSource *source)
+{
+ GWin32HandleSource *hsource = (GWin32HandleSource *)source;
+
+ return hsource->pollfd.revents;
+}
+
+static gboolean
+g_win32_handle_source_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ return (*callback) (user_data);
+}
+
+static void
+g_win32_handle_source_finalize (GSource *source)
+{
+ ;
+}
+
+GSourceFuncs g_win32_handle_source_funcs = {
+ g_win32_handle_source_prepare,
+ g_win32_handle_source_check,
+ g_win32_handle_source_dispatch,
+ g_win32_handle_source_finalize
+};
+
+static GSource *
+g_win32_handle_source_add (HANDLE handle,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ GWin32HandleSource *hsource;
+ GSource *source;
+
+ source = g_source_new (&g_win32_handle_source_funcs, sizeof (GWin32HandleSource));
+ hsource = (GWin32HandleSource *)source;
+ hsource->pollfd.fd = (gint)handle;
+ hsource->pollfd.events = G_IO_IN;
+ hsource->pollfd.revents = 0;
+ g_source_add_poll (source, &hsource->pollfd);
+
+ g_source_set_callback (source, callback, user_data, NULL);
+ g_source_attach (source, g_main_context_get_thread_default ());
+ return source;
+}
--- /dev/null
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __NAMED_PIPE_LISTENER_H__
+#define __NAMED_PIPE_LISTENER_H__
+
+#include <gio/gio.h>
+
+#include "namedpipe.h"
+#include "namedpipeconnection.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_NAMED_PIPE_LISTENER (spice_named_pipe_listener_get_type ())
+#define SPICE_NAMED_PIPE_LISTENER(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+ SPICE_TYPE_NAMED_PIPE_LISTENER, SpiceNamedPipeListener))
+#define SPICE_NAMED_PIPE_LISTENER_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
+ SPICE_TYPE_NAMED_PIPE_LISTENER, SpiceNamedPipeListenerClass))
+#define SPICE_IS_NAMED_PIPE_LISTENER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
+ SPICE_TYPE_NAMED_PIPE_LISTENER))
+#define SPICE_IS_NAMED_PIPE_LISTENER_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
+ SPICE_TYPE_NAMED_PIPE_LISTENER))
+#define SPICE_NAMED_PIPE_LISTENER_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \
+ SPICE_TYPE_NAMED_PIPE_LISTENER, SpiceNamedPipeListenerClass))
+
+typedef struct _SpiceNamedPipeListener SpiceNamedPipeListener;
+typedef struct _SpiceNamedPipeListenerPrivate SpiceNamedPipeListenerPrivate;
+typedef struct _SpiceNamedPipeListenerClass SpiceNamedPipeListenerClass;
+
+struct _SpiceNamedPipeListenerClass
+{
+ GObjectClass parent_class;
+};
+
+struct _SpiceNamedPipeListener
+{
+ GObject parent_instance;
+ SpiceNamedPipeListenerPrivate *priv;
+};
+
+GType spice_named_pipe_listener_get_type (void) G_GNUC_CONST;
+
+SpiceNamedPipeListener * spice_named_pipe_listener_new (void);
+void spice_named_pipe_listener_add_named_pipe (SpiceNamedPipeListener *listener,
+ SpiceNamedPipe *namedpipe);
+void spice_named_pipe_listener_accept_async (SpiceNamedPipeListener *listener,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+SpiceNamedPipeConnection * spice_named_pipe_listener_accept_finish (SpiceNamedPipeListener *listener,
+ GAsyncResult *result,
+ GObject **source_object,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __NAMED_PIPE_LISTENER_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "spice-controller-listener.h"
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include "namedpipe.h"
+#include "namedpipelistener.h"
+#include "win32-util.h"
+#endif
+
+#ifdef G_OS_UNIX
+#include <gio/gunixsocketaddress.h>
+#endif
+
+/**
+ * SpiceControllerListenerError:
+ * @SPICE_CONTROLLER_LISTENER_ERROR_VALUE: invalid value.
+ *
+ * Possible errors of controller listener related functions.
+ **/
+
+/**
+ * SPICE_CONTROLLER_LISTENER_ERROR:
+ *
+ * The error domain of the controller listener subsystem.
+ **/
+GQuark
+spice_controller_listener_error_quark (void)
+{
+ return g_quark_from_static_string ("spice-controller-listener-error");
+}
+
+GObject*
+spice_controller_listener_new (const gchar *address, GError **error)
+{
+ GObject *listener = NULL;
+ gchar *addr = NULL;
+
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ addr = g_strdup (address);
+
+#ifdef G_OS_WIN32
+ if (addr == NULL)
+ addr = g_strdup (g_getenv ("SPICE_XPI_NAMEDPIPE"));
+ if (addr == NULL)
+ addr = g_strdup_printf ("\\\\.\\pipe\\SpiceController-%" G_GUINT64_FORMAT, (guint64)GetCurrentProcessId ());
+#else
+ if (addr == NULL)
+ addr = g_strdup (g_getenv ("SPICE_XPI_SOCKET"));
+#endif
+ if (addr == NULL) {
+ g_set_error (error,
+ SPICE_CONTROLLER_LISTENER_ERROR,
+ SPICE_CONTROLLER_LISTENER_ERROR_VALUE,
+#ifdef G_OS_WIN32
+ "Missing namedpipe address"
+#else
+ "Missing socket address"
+#endif
+ );
+ goto end;
+ }
+
+ g_unlink (addr);
+
+#ifdef G_OS_WIN32
+ {
+ SpiceNamedPipe *np;
+
+ listener = G_OBJECT (spice_named_pipe_listener_new ());
+
+ np = spice_win32_user_pipe_new (addr, error);
+ if (!np) {
+ g_object_unref (listener);
+ listener = NULL;
+ goto end;
+ }
+
+ spice_named_pipe_listener_add_named_pipe (SPICE_NAMED_PIPE_LISTENER (listener), np);
+ }
+#else
+ {
+ listener = G_OBJECT (g_socket_listener_new ());
+
+ if (!g_socket_listener_add_address (G_SOCKET_LISTENER (listener),
+ G_SOCKET_ADDRESS (g_unix_socket_address_new (addr)),
+ G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_DEFAULT,
+ NULL,
+ NULL,
+ error))
+ g_warning ("failed to add address");
+ }
+#endif
+
+end:
+ g_free (addr);
+ return listener;
+}
+
+void
+spice_controller_listener_accept_async (GObject *listener,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail(G_IS_OBJECT(listener));
+
+#ifdef G_OS_WIN32
+ spice_named_pipe_listener_accept_async (SPICE_NAMED_PIPE_LISTENER (listener), cancellable, callback, user_data);
+#else
+ g_socket_listener_accept_async (G_SOCKET_LISTENER (listener), cancellable, callback, user_data);
+#endif
+}
+
+GIOStream*
+spice_controller_listener_accept_finish (GObject *listener,
+ GAsyncResult *result,
+ GObject **source_object,
+ GError **error)
+{
+ g_return_val_if_fail(G_IS_OBJECT(listener), NULL);
+
+#ifdef G_OS_WIN32
+ SpiceNamedPipeConnection *np;
+ np = spice_named_pipe_listener_accept_finish (SPICE_NAMED_PIPE_LISTENER (listener), result, source_object, error);
+ if (np)
+ return G_IO_STREAM (np);
+#else
+ GSocketConnection *socket;
+ socket = g_socket_listener_accept_finish (G_SOCKET_LISTENER (listener), result, source_object, error);
+ if (socket)
+ return G_IO_STREAM (socket);
+#endif
+
+ return NULL;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CONTROLLER_LISTENER_H__
+#define __SPICE_CONTROLLER_LISTENER_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define SPICE_CONTROLLER_LISTENER_ERROR spice_controller_listener_error_quark ()
+GQuark spice_controller_listener_error_quark (void);
+
+typedef enum
+{
+ SPICE_CONTROLLER_LISTENER_ERROR_VALUE /* incorrect value */
+} SpiceControllerListenerError;
+
+
+GObject* spice_controller_listener_new (const gchar *address, GError **error);
+
+void spice_controller_listener_accept_async (GObject *listener,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GIOStream* spice_controller_listener_accept_finish (GObject *listener,
+ GAsyncResult *result,
+ GObject **source_object,
+ GError **error);
+G_END_DECLS
+
+#endif /* __SPICE_CONTROLLER_LISTENER_H__ */
--- /dev/null
+/* spice-controller.h generated by valac 0.32.1, the Vala compiler, do not modify */
+
+
+#ifndef __SPICE_CONTROLLER_H__
+#define __SPICE_CONTROLLER_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <stdlib.h>
+#include <string.h>
+#include <spice/controller_prot.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+
+#define SPICE_CTRL_TYPE_MENU_ITEM (spice_ctrl_menu_item_get_type ())
+#define SPICE_CTRL_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_CTRL_TYPE_MENU_ITEM, SpiceCtrlMenuItem))
+#define SPICE_CTRL_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_CTRL_TYPE_MENU_ITEM, SpiceCtrlMenuItemClass))
+#define SPICE_CTRL_IS_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_CTRL_TYPE_MENU_ITEM))
+#define SPICE_CTRL_IS_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_CTRL_TYPE_MENU_ITEM))
+#define SPICE_CTRL_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_CTRL_TYPE_MENU_ITEM, SpiceCtrlMenuItemClass))
+
+typedef struct _SpiceCtrlMenuItem SpiceCtrlMenuItem;
+typedef struct _SpiceCtrlMenuItemClass SpiceCtrlMenuItemClass;
+typedef struct _SpiceCtrlMenuItemPrivate SpiceCtrlMenuItemPrivate;
+
+#define SPICE_CTRL_TYPE_MENU (spice_ctrl_menu_get_type ())
+#define SPICE_CTRL_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_CTRL_TYPE_MENU, SpiceCtrlMenu))
+#define SPICE_CTRL_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_CTRL_TYPE_MENU, SpiceCtrlMenuClass))
+#define SPICE_CTRL_IS_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_CTRL_TYPE_MENU))
+#define SPICE_CTRL_IS_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_CTRL_TYPE_MENU))
+#define SPICE_CTRL_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_CTRL_TYPE_MENU, SpiceCtrlMenuClass))
+
+typedef struct _SpiceCtrlMenu SpiceCtrlMenu;
+typedef struct _SpiceCtrlMenuClass SpiceCtrlMenuClass;
+typedef struct _SpiceCtrlMenuPrivate SpiceCtrlMenuPrivate;
+
+#define SPICE_CTRL_TYPE_CONTROLLER (spice_ctrl_controller_get_type ())
+#define SPICE_CTRL_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_CTRL_TYPE_CONTROLLER, SpiceCtrlController))
+#define SPICE_CTRL_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_CTRL_TYPE_CONTROLLER, SpiceCtrlControllerClass))
+#define SPICE_CTRL_IS_CONTROLLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_CTRL_TYPE_CONTROLLER))
+#define SPICE_CTRL_IS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_CTRL_TYPE_CONTROLLER))
+#define SPICE_CTRL_CONTROLLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_CTRL_TYPE_CONTROLLER, SpiceCtrlControllerClass))
+
+typedef struct _SpiceCtrlController SpiceCtrlController;
+typedef struct _SpiceCtrlControllerClass SpiceCtrlControllerClass;
+typedef struct _SpiceCtrlControllerPrivate SpiceCtrlControllerPrivate;
+
+#define SPICE_CTRL_TYPE_FOREIGN_MENU (spice_ctrl_foreign_menu_get_type ())
+#define SPICE_CTRL_FOREIGN_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_CTRL_TYPE_FOREIGN_MENU, SpiceCtrlForeignMenu))
+#define SPICE_CTRL_FOREIGN_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_CTRL_TYPE_FOREIGN_MENU, SpiceCtrlForeignMenuClass))
+#define SPICE_CTRL_IS_FOREIGN_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_CTRL_TYPE_FOREIGN_MENU))
+#define SPICE_CTRL_IS_FOREIGN_MENU_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_CTRL_TYPE_FOREIGN_MENU))
+#define SPICE_CTRL_FOREIGN_MENU_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_CTRL_TYPE_FOREIGN_MENU, SpiceCtrlForeignMenuClass))
+
+typedef struct _SpiceCtrlForeignMenu SpiceCtrlForeignMenu;
+typedef struct _SpiceCtrlForeignMenuClass SpiceCtrlForeignMenuClass;
+typedef struct _SpiceCtrlForeignMenuPrivate SpiceCtrlForeignMenuPrivate;
+
+struct _SpiceCtrlMenuItem {
+ GObject parent_instance;
+ SpiceCtrlMenuItemPrivate * priv;
+ SpiceCtrlMenu* submenu;
+ gint parent_id;
+ gint id;
+ gchar* text;
+ gchar* accel;
+ unsigned int flags;
+};
+
+struct _SpiceCtrlMenuItemClass {
+ GObjectClass parent_class;
+};
+
+typedef enum {
+ SPICE_CTRL_ERROR_VALUE
+} SpiceCtrlError;
+#define SPICE_CTRL_ERROR spice_ctrl_error_quark ()
+struct _SpiceCtrlMenu {
+ GObject parent_instance;
+ SpiceCtrlMenuPrivate * priv;
+ GList* items;
+};
+
+struct _SpiceCtrlMenuClass {
+ GObjectClass parent_class;
+};
+
+struct _SpiceCtrlController {
+ GObject parent_instance;
+ SpiceCtrlControllerPrivate * priv;
+};
+
+struct _SpiceCtrlControllerClass {
+ GObjectClass parent_class;
+};
+
+struct _SpiceCtrlForeignMenu {
+ GObject parent_instance;
+ SpiceCtrlForeignMenuPrivate * priv;
+};
+
+struct _SpiceCtrlForeignMenuClass {
+ GObjectClass parent_class;
+};
+
+
+GType spice_ctrl_menu_item_get_type (void) G_GNUC_CONST;
+GType spice_ctrl_menu_get_type (void) G_GNUC_CONST;
+SpiceCtrlMenuItem* spice_ctrl_menu_item_new (gint id, const gchar* text, unsigned int flags);
+SpiceCtrlMenuItem* spice_ctrl_menu_item_construct (GType object_type, gint id, const gchar* text, unsigned int flags);
+GQuark spice_ctrl_error_quark (void);
+SpiceCtrlMenuItem* spice_ctrl_menu_item_new_from_string (const gchar* str, GError** error);
+SpiceCtrlMenuItem* spice_ctrl_menu_item_construct_from_string (GType object_type, const gchar* str, GError** error);
+gchar* spice_ctrl_menu_item_to_string (SpiceCtrlMenuItem* self);
+SpiceCtrlMenu* spice_ctrl_menu_find_id (SpiceCtrlMenu* self, gint id);
+SpiceCtrlMenu* spice_ctrl_menu_new_from_string (const gchar* str);
+SpiceCtrlMenu* spice_ctrl_menu_construct_from_string (GType object_type, const gchar* str);
+gchar* spice_ctrl_menu_to_string (SpiceCtrlMenu* self);
+SpiceCtrlMenu* spice_ctrl_menu_new (void);
+SpiceCtrlMenu* spice_ctrl_menu_construct (GType object_type);
+GType spice_ctrl_controller_get_type (void) G_GNUC_CONST;
+void spice_ctrl_controller_menu_item_click_msg (SpiceCtrlController* self, gint32 item_id);
+void spice_ctrl_controller_send_msg (SpiceCtrlController* self, guint8* p, int p_length1, GAsyncReadyCallback _callback_, gpointer _user_data_);
+gboolean spice_ctrl_controller_send_msg_finish (SpiceCtrlController* self, GAsyncResult* _res_, GError** error);
+SpiceCtrlController* spice_ctrl_controller_new (void);
+SpiceCtrlController* spice_ctrl_controller_construct (GType object_type);
+void spice_ctrl_controller_listen (SpiceCtrlController* self, const gchar* addr, GAsyncReadyCallback _callback_, gpointer _user_data_);
+void spice_ctrl_controller_listen_finish (SpiceCtrlController* self, GAsyncResult* _res_, GError** error);
+const gchar* spice_ctrl_controller_get_host (SpiceCtrlController* self);
+guint32 spice_ctrl_controller_get_port (SpiceCtrlController* self);
+guint32 spice_ctrl_controller_get_sport (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_password (SpiceCtrlController* self);
+unsigned int spice_ctrl_controller_get_display_flags (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_tls_ciphers (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_host_subject (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_ca_file (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_title (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_hotkeys (SpiceCtrlController* self);
+gchar** spice_ctrl_controller_get_secure_channels (SpiceCtrlController* self, int* result_length1);
+gchar** spice_ctrl_controller_get_disable_channels (SpiceCtrlController* self, int* result_length1);
+SpiceCtrlMenu* spice_ctrl_controller_get_menu (SpiceCtrlController* self);
+gboolean spice_ctrl_controller_get_enable_smartcard (SpiceCtrlController* self);
+gboolean spice_ctrl_controller_get_send_cad (SpiceCtrlController* self);
+gchar** spice_ctrl_controller_get_disable_effects (SpiceCtrlController* self, int* result_length1);
+guint32 spice_ctrl_controller_get_color_depth (SpiceCtrlController* self);
+gboolean spice_ctrl_controller_get_enable_usbredir (SpiceCtrlController* self);
+gboolean spice_ctrl_controller_get_enable_usb_autoshare (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_usb_filter (SpiceCtrlController* self);
+const gchar* spice_ctrl_controller_get_proxy (SpiceCtrlController* self);
+GType spice_ctrl_foreign_menu_get_type (void) G_GNUC_CONST;
+SpiceCtrlForeignMenu* spice_ctrl_foreign_menu_new (void);
+SpiceCtrlForeignMenu* spice_ctrl_foreign_menu_construct (GType object_type);
+void spice_ctrl_foreign_menu_menu_item_click_msg (SpiceCtrlForeignMenu* self, gint32 item_id);
+void spice_ctrl_foreign_menu_menu_item_checked_msg (SpiceCtrlForeignMenu* self, gint32 item_id, gboolean checked);
+void spice_ctrl_foreign_menu_app_activated_msg (SpiceCtrlForeignMenu* self, gboolean activated);
+void spice_ctrl_foreign_menu_send_msg (SpiceCtrlForeignMenu* self, guint8* p, int p_length1, GAsyncReadyCallback _callback_, gpointer _user_data_);
+gboolean spice_ctrl_foreign_menu_send_msg_finish (SpiceCtrlForeignMenu* self, GAsyncResult* _res_, GError** error);
+void spice_ctrl_foreign_menu_listen (SpiceCtrlForeignMenu* self, const gchar* addr, GAsyncReadyCallback _callback_, gpointer _user_data_);
+void spice_ctrl_foreign_menu_listen_finish (SpiceCtrlForeignMenu* self, GAsyncResult* _res_, GError** error);
+SpiceCtrlMenu* spice_ctrl_foreign_menu_get_menu (SpiceCtrlForeignMenu* self);
+const gchar* spice_ctrl_foreign_menu_get_title (SpiceCtrlForeignMenu* self);
+void spice_ctrl_input_stream_read (GInputStream* stream, guint8* buffer, int buffer_length1, GAsyncReadyCallback _callback_, gpointer _user_data_);
+void spice_ctrl_input_stream_read_finish (GAsyncResult* _res_, GError** error);
+void spice_ctrl_output_stream_write (GOutputStream* stream, guint8* buffer, int buffer_length1, GAsyncReadyCallback _callback_, gpointer _user_data_);
+void spice_ctrl_output_stream_write_finish (GAsyncResult* _res_, GError** error);
+
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "spice-foreign-menu-listener.h"
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include "namedpipe.h"
+#include "namedpipelistener.h"
+#include "win32-util.h"
+#endif
+
+#ifdef G_OS_UNIX
+#include <gio/gunixsocketaddress.h>
+#endif
+
+/**
+ * SpiceForeignMenuListenerError:
+ * @SPICE_FOREIGN_MENU_LISTENER_ERROR_VALUE: invalid value.
+ *
+ * Possible errors of foreign menu listener related functions.
+ **/
+
+/**
+ * SPICE_FOREIGN_MENU_LISTENER_ERROR:
+ *
+ * The error domain of the foreign menu listener subsystem.
+ **/
+GQuark
+spice_foreign_menu_listener_error_quark (void)
+{
+ return g_quark_from_static_string ("spice-foreign-menu-listener-error");
+}
+
+GObject*
+spice_foreign_menu_listener_new (const gchar *address, GError **error)
+{
+ GObject *listener = NULL;
+ gchar *addr = NULL;
+
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ addr = g_strdup (address);
+
+#ifdef G_OS_WIN32
+ if (addr == NULL)
+ addr = g_strdup (g_getenv ("SPICE_FOREIGN_MENU_NAMEDPIPE"));
+ if (addr == NULL)
+ addr = g_strdup_printf ("\\\\.\\pipe\\SpiceForeignMenu-%" G_GUINT64_FORMAT, (guint64)GetCurrentProcessId ());
+#else
+ if (addr == NULL)
+ addr = g_strdup (g_getenv ("SPICE_FOREIGN_MENU_SOCKET"));
+ if (addr == NULL)
+ addr = g_strdup_printf ("/tmp/SpiceForeignMenu-%" G_GUINT64_FORMAT ".uds", (guint64)getpid ());
+#endif
+ if (addr == NULL) {
+ g_set_error (error,
+ SPICE_FOREIGN_MENU_LISTENER_ERROR,
+ SPICE_FOREIGN_MENU_LISTENER_ERROR_VALUE,
+#ifdef G_OS_WIN32
+ "Missing namedpipe address"
+#else
+ "Missing socket address"
+#endif
+ );
+ goto end;
+ }
+
+ g_unlink (addr);
+
+#ifdef G_OS_WIN32
+ {
+ SpiceNamedPipe *np;
+
+ listener = G_OBJECT (spice_named_pipe_listener_new ());
+
+ np = spice_win32_user_pipe_new (addr, error);
+ if (!np) {
+ g_object_unref (listener);
+ listener = NULL;
+ goto end;
+ }
+
+ spice_named_pipe_listener_add_named_pipe (SPICE_NAMED_PIPE_LISTENER (listener), np);
+ }
+#else
+ {
+ listener = G_OBJECT (g_socket_listener_new ());
+
+ if (!g_socket_listener_add_address (G_SOCKET_LISTENER (listener),
+ G_SOCKET_ADDRESS (g_unix_socket_address_new (addr)),
+ G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_DEFAULT,
+ NULL,
+ NULL,
+ error))
+ g_warning ("failed to add address");
+ }
+#endif
+
+end:
+ g_free (addr);
+ return listener;
+}
+
+void
+spice_foreign_menu_listener_accept_async (GObject *listener,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail(G_IS_OBJECT(listener));
+
+#ifdef G_OS_WIN32
+ spice_named_pipe_listener_accept_async (SPICE_NAMED_PIPE_LISTENER (listener), cancellable, callback, user_data);
+#else
+ g_socket_listener_accept_async (G_SOCKET_LISTENER (listener), cancellable, callback, user_data);
+#endif
+}
+
+GIOStream*
+spice_foreign_menu_listener_accept_finish (GObject *listener,
+ GAsyncResult *result,
+ GObject **source_object,
+ GError **error)
+{
+ g_return_val_if_fail(G_IS_OBJECT(listener), NULL);
+
+#ifdef G_OS_WIN32
+ SpiceNamedPipeConnection *np;
+ np = spice_named_pipe_listener_accept_finish (SPICE_NAMED_PIPE_LISTENER (listener), result, source_object, error);
+ if (np)
+ return G_IO_STREAM (np);
+#else
+ GSocketConnection *socket;
+ socket = g_socket_listener_accept_finish (G_SOCKET_LISTENER (listener), result, source_object, error);
+ if (socket)
+ return G_IO_STREAM (socket);
+#endif
+
+ return NULL;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_FOREIGN_MENU_LISTENER_H__
+#define __SPICE_FOREIGN_MENU_LISTENER_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define SPICE_FOREIGN_MENU_LISTENER_ERROR spice_foreign_menu_listener_error_quark ()
+GQuark spice_foreign_menu_listener_error_quark (void);
+
+typedef enum
+{
+ SPICE_FOREIGN_MENU_LISTENER_ERROR_VALUE /* incorrect value */
+} SpiceForeignMenuListenerError;
+
+
+GObject* spice_foreign_menu_listener_new (const gchar *address, GError **error);
+
+void spice_foreign_menu_listener_accept_async (GObject *listener,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GIOStream* spice_foreign_menu_listener_accept_finish (GObject *listener,
+ GAsyncResult *result,
+ GObject **source_object,
+ GError **error);
+G_END_DECLS
+
+#endif /* __SPICE_FOREIGN_MENU_LISTENER_H__ */
--- /dev/null
+/* Copyright (C) 2011 Red Hat, Inc. */
+
+/* This library is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU Lesser General Public */
+/* License as published by the Free Software Foundation; either */
+/* version 2.1 of the License, or (at your option) any later version. */
+
+/* This library is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* Lesser General Public License for more details. */
+
+/* You should have received a copy of the GNU Lesser General Public */
+/* License along with this library; if not, see <http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <spice/controller_prot.h>
+
+#include "spice-controller.h"
+
+#ifdef WIN32
+#include <windows.h>
+#define PIPE_NAME TEXT("\\\\.\\pipe\\SpiceController-%lu")
+static HANDLE pipe = INVALID_HANDLE_VALUE;
+#else
+
+#include <sys/socket.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <sys/un.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#define PIPE_NAME "/tmp/test"
+static int sock = -1;
+
+#endif
+
+#define PIPE_NAME_MAX_LEN 256
+
+void write_to_pipe (const void* data, size_t len)
+{
+#ifdef WIN32
+ DWORD written;
+ if (!WriteFile (pipe, data, len, &written, NULL) || written != len) {
+ printf("Write to pipe failed %lu\n", GetLastError());
+ }
+#else
+ if (send (sock, data, len, 0) != len) {
+ printf ("send failed, (%d) %s\n", errno, strerror(errno));
+ }
+#endif
+}
+
+gboolean send_init (void)
+{
+ ControllerInit msg = {
+ { CONTROLLER_MAGIC, CONTROLLER_VERSION, sizeof (msg) },
+ 0,
+ CONTROLLER_FLAG_EXCLUSIVE
+ };
+
+ write_to_pipe(&msg, sizeof (msg));
+ return FALSE;
+}
+
+void send_msg (uint32_t id)
+{
+ ControllerMsg msg = {
+ id, sizeof (msg)
+ };
+
+ write_to_pipe (&msg, sizeof (msg));
+}
+
+void send_value (uint32_t id, uint32_t value)
+{
+ ControllerValue msg = {
+ { id, sizeof(msg) },
+ value
+ };
+
+ write_to_pipe (&msg, sizeof (msg));
+}
+
+void send_data (uint32_t id, uint8_t* data, size_t data_size)
+{
+ size_t size = sizeof (ControllerData) + data_size;
+ ControllerData* msg = (ControllerData*)g_malloc0 (size);
+
+ msg->base.id = id;
+ msg->base.size = (uint32_t)size;
+ memcpy (msg->data, data, data_size);
+ write_to_pipe (msg, size);
+ g_free (msg);
+}
+
+ssize_t read_from_pipe (void* data, size_t size)
+{
+ ssize_t read;
+#ifdef WIN32
+ DWORD bytes;
+ if (!ReadFile (pipe, data, size, &bytes, NULL)) {
+ printf ("Read from pipe failed %lu\n", GetLastError());
+ }
+ read = bytes;
+#else
+ read = recv (sock, data, size, 0);
+ if ((read == -1 || read == 0)) {
+ printf ("recv failed, (%d) %s\n", errno, strerror (errno));
+ }
+#endif
+ return read;
+}
+
+#define HOST "localhost"
+#define PORT 5931
+#define SPORT 0
+#define PWD "P@s5w0rd"
+#define SECURE_CHANNELS "main,inputs,playback"
+#define DISABLED_CHANNELS "playback,record"
+#define TITLE "Hello from controller"
+#define HOTKEYS "toggle-fullscreen=shift+f1,release-cursor=shift+f2"
+#define MENU "0\r4864\rS&end Ctrl+Alt+Del\tCtrl+Alt+End\r0\r\n" \
+ "0\r5120\r&Toggle full screen\tShift+F11\r0\r\n" \
+ "0\r1\r&Special keys\r4\r\n" \
+ "1\r5376\r&Send Shift+F11\r0\r\n" \
+ "1\r5632\r&Send Shift+F12\r0\r\n" \
+ "1\r5888\r&Send Ctrl+Alt+End\r0\r\n" \
+ "0\r1\r-\r1\r\n" \
+ "0\r2\rChange CD\r4\r\n" \
+ "2\r3\rNo CDs\r0\r\n" \
+ "2\r4\r[Eject]\r0\r\n" \
+ "0\r5\r-\r1\r\n" \
+ "0\r6\rPlay\r0\r\n" \
+ "0\r7\rSuspend\r0\r\n" \
+ "0\r8\rStop\r0\r\n"
+
+#define TLS_CIPHERS "TLS_C1PHERS"
+#define CA_FILE "C@_FILE"
+#define HOST_SUBJECT "Host_SUBJ3CT"
+
+SpiceCtrlController *ctrl;
+GMainLoop *loop;
+
+void signaled (GObject *gobject, const gchar *signal_name)
+{
+ g_message ("signaled: %s", signal_name);
+ if (g_str_equal (signal_name, "hide")) {
+ spice_ctrl_controller_menu_item_click_msg (ctrl, 42);
+ g_timeout_add (1000, (GSourceFunc)g_main_loop_quit, loop);
+ }
+}
+
+void notified (GObject *gobject, GParamSpec *pspec,
+ gpointer user_data)
+{
+ GValue value = { 0, };
+ GValue strvalue = { 0, };
+
+ g_return_if_fail (gobject != NULL);
+ g_return_if_fail (pspec != NULL);
+
+ g_value_init (&value, pspec->value_type);
+ g_value_init (&strvalue, G_TYPE_STRING);
+ g_object_get_property (gobject, pspec->name, &value);
+
+ if (pspec->value_type == G_TYPE_STRV) {
+ gchar** p = (gchar **)g_value_get_boxed (&value);
+ g_message ("notify::%s == ", pspec->name);
+ while (*p)
+ g_message ("%s", *p++);
+ } else if (G_TYPE_IS_OBJECT(pspec->value_type)) {
+ GObject *o = g_value_get_object (&value);
+ g_message ("notify::%s == %s", pspec->name, o ? G_OBJECT_TYPE_NAME (o) : "null");
+ } else {
+ g_value_transform (&value, &strvalue);
+ g_message ("notify::%s = %s", pspec->name, g_value_get_string (&strvalue));
+ }
+
+ g_value_unset (&value);
+ g_value_unset (&strvalue);
+}
+
+void connect_signals (gpointer obj)
+{
+ guint i, n_ids = 0;
+ guint *ids = NULL;
+ GType type = G_OBJECT_TYPE (obj);
+
+ ids = g_signal_list_ids (type, &n_ids);
+ for (i = 0; i < n_ids; i++) {
+ const gchar *name = g_signal_name (ids[i]);
+ g_signal_connect (obj, name, G_CALLBACK (signaled), (gpointer)name);
+ }
+}
+
+int main (int argc, char *argv[])
+{
+#ifdef WIN32
+ int spicec_pid = (argc > 1 ? atoi (argv[1]) : 0);
+#endif
+ char* host = (argc > 2 ? argv[2] : (char*)HOST);
+ int port = (argc > 3 ? atoi (argv[3]) : PORT);
+ char pipe_name[PIPE_NAME_MAX_LEN];
+ ControllerValue msg;
+ ssize_t read;
+
+ ctrl = spice_ctrl_controller_new ();
+ loop = g_main_loop_new (NULL, FALSE);
+ g_signal_connect (ctrl, "notify", G_CALLBACK (notified), NULL);
+ connect_signals (ctrl);
+
+#ifdef WIN32
+ snprintf (pipe_name, PIPE_NAME_MAX_LEN, PIPE_NAME, spicec_pid);
+ spice_ctrl_controller_listen (ctrl, pipe_name, NULL, NULL);
+
+ printf ("Creating Spice controller connection %s\n", pipe_name);
+ pipe = CreateFile (pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (pipe == INVALID_HANDLE_VALUE) {
+ printf ("Could not open pipe %lu\n", GetLastError());
+ return -1;
+ }
+#else
+ spice_ctrl_controller_listen (ctrl, PIPE_NAME, NULL, NULL);
+
+ snprintf (pipe_name, PIPE_NAME_MAX_LEN, PIPE_NAME);
+ printf ("Creating a controller connection %s\n", pipe_name);
+ struct sockaddr_un remote;
+ if ((sock = socket (AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ printf ("Could not open socket, (%d) %s\n", errno, strerror(errno));
+ return -1;
+ }
+ remote.sun_family = AF_UNIX;
+ strcpy (remote.sun_path, pipe_name);
+ if (connect (sock, (struct sockaddr *)&remote,
+ strlen (remote.sun_path) + sizeof(remote.sun_family)) == -1) {
+ printf ("Socket connect failed, (%d) %s\n", errno, strerror(errno));
+ close (sock);
+ return -1;
+ }
+#endif
+
+ /* TODO: we rely on socket / pipe buffer... which is lame :) */
+ send_init ();
+
+ send_data (CONTROLLER_HOST, (uint8_t*)host, strlen(host) + 1);
+ send_value (CONTROLLER_PORT, port);
+ send_value (CONTROLLER_SPORT, SPORT);
+ send_data (CONTROLLER_PASSWORD, (uint8_t*)PWD, strlen(PWD) + 1);
+ send_data (CONTROLLER_SECURE_CHANNELS, (uint8_t*)SECURE_CHANNELS, strlen(SECURE_CHANNELS) + 1);
+ send_data (CONTROLLER_DISABLE_CHANNELS, (uint8_t*)DISABLED_CHANNELS, strlen(DISABLED_CHANNELS) + 1);
+ send_data (CONTROLLER_TLS_CIPHERS, (uint8_t*)TLS_CIPHERS, strlen(TLS_CIPHERS) + 1);
+ send_data (CONTROLLER_CA_FILE, (uint8_t*)CA_FILE, strlen(CA_FILE) + 1);
+ send_data (CONTROLLER_HOST_SUBJECT, (uint8_t*)HOST_SUBJECT, strlen(HOST_SUBJECT) + 1);
+ send_data (CONTROLLER_SET_TITLE, (uint8_t*)TITLE, strlen(TITLE) + 1);
+ send_data (CONTROLLER_HOTKEYS, (uint8_t*)HOTKEYS, strlen(HOTKEYS) + 1);
+ send_data (CONTROLLER_CREATE_MENU, (uint8_t*)MENU, strlen(MENU));
+
+ send_value (CONTROLLER_FULL_SCREEN, /*CONTROLLER_SET_FULL_SCREEN |*/ CONTROLLER_AUTO_DISPLAY_RES);
+
+ send_msg (CONTROLLER_SHOW);
+ send_msg (CONTROLLER_CONNECT);
+ send_msg (CONTROLLER_SHOW);
+ send_msg (CONTROLLER_DELETE_MENU);
+ send_msg (CONTROLLER_HIDE);
+
+ g_main_loop_run (loop);
+
+ while ((read = read_from_pipe (&msg, sizeof(msg))) == sizeof(msg)) {
+ printf ("Received id %u, size %u, value %u\n", msg.base.id, msg.base.size, msg.value);
+ if (msg.value == 42)
+ break;
+ }
+
+#ifdef WIN32
+ CloseHandle (pipe);
+#else
+ close (sock);
+#endif
+ g_object_unref (ctrl);
+ return 0;
+}
--- /dev/null
+/* util.c generated by valac 0.32.1, the Vala compiler
+ * generated from util.vala, do not modify */
+
+/* Copyright (C) 2012 Red Hat, Inc.*/
+/* This library is free software; you can redistribute it and/or*/
+/* modify it under the terms of the GNU Lesser General Public*/
+/* License as published by the Free Software Foundation; either*/
+/* version 2.1 of the License, or (at your option) any later version.*/
+/* This library is distributed in the hope that it will be useful,*/
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU*/
+/* Lesser General Public License for more details.*/
+/* You should have received a copy of the GNU Lesser General Public*/
+/* License along with this library; if not, see <http://www.gnu.org/licenses/>.*/
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
+typedef struct _SpiceCtrlInputStreamReadData SpiceCtrlInputStreamReadData;
+typedef struct _SpiceCtrlOutputStreamWriteData SpiceCtrlOutputStreamWriteData;
+
+struct _SpiceCtrlInputStreamReadData {
+ int _state_;
+ GObject* _source_object_;
+ GAsyncResult* _res_;
+ GSimpleAsyncResult* _async_result;
+ GInputStream* stream;
+ guint8* buffer;
+ gint buffer_length1;
+ gint length;
+ guint8* _tmp0_;
+ gint _tmp0__length1;
+ gssize i;
+ gssize _tmp1_;
+ gint _tmp2_;
+ gssize n;
+ GInputStream* _tmp3_;
+ guint8* _tmp4_;
+ gint _tmp4__length1;
+ gssize _tmp5_;
+ gint _tmp6_;
+ gssize _tmp7_;
+ gssize _tmp8_;
+ GError* _tmp9_;
+ gssize _tmp10_;
+ gssize _tmp11_;
+ GError * _inner_error_;
+};
+
+struct _SpiceCtrlOutputStreamWriteData {
+ int _state_;
+ GObject* _source_object_;
+ GAsyncResult* _res_;
+ GSimpleAsyncResult* _async_result;
+ GOutputStream* stream;
+ guint8* buffer;
+ gint buffer_length1;
+ gint length;
+ guint8* _tmp0_;
+ gint _tmp0__length1;
+ gssize i;
+ gssize _tmp1_;
+ gint _tmp2_;
+ gssize n;
+ GOutputStream* _tmp3_;
+ guint8* _tmp4_;
+ gint _tmp4__length1;
+ gssize _tmp5_;
+ gint _tmp6_;
+ gssize _tmp7_;
+ gssize _tmp8_;
+ GError* _tmp9_;
+ gssize _tmp10_;
+ gssize _tmp11_;
+ GError * _inner_error_;
+};
+
+
+
+static void spice_ctrl_input_stream_read_data_free (gpointer _data);
+void spice_ctrl_input_stream_read (GInputStream* stream, guint8* buffer, int buffer_length1, GAsyncReadyCallback _callback_, gpointer _user_data_);
+void spice_ctrl_input_stream_read_finish (GAsyncResult* _res_, GError** error);
+static gboolean spice_ctrl_input_stream_read_co (SpiceCtrlInputStreamReadData* _data_);
+static void spice_ctrl_input_stream_read_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
+static void spice_ctrl_output_stream_write_data_free (gpointer _data);
+void spice_ctrl_output_stream_write (GOutputStream* stream, guint8* buffer, int buffer_length1, GAsyncReadyCallback _callback_, gpointer _user_data_);
+void spice_ctrl_output_stream_write_finish (GAsyncResult* _res_, GError** error);
+static gboolean spice_ctrl_output_stream_write_co (SpiceCtrlOutputStreamWriteData* _data_);
+static void spice_ctrl_output_stream_write_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_);
+
+
+static void spice_ctrl_input_stream_read_data_free (gpointer _data) {
+ SpiceCtrlInputStreamReadData* _data_;
+ _data_ = _data;
+ _g_object_unref0 (_data_->stream);
+ g_slice_free (SpiceCtrlInputStreamReadData, _data_);
+}
+
+
+static gpointer _g_object_ref0 (gpointer self) {
+ return self ? g_object_ref (self) : NULL;
+}
+
+
+void spice_ctrl_input_stream_read (GInputStream* stream, guint8* buffer, int buffer_length1, GAsyncReadyCallback _callback_, gpointer _user_data_) {
+ SpiceCtrlInputStreamReadData* _data_;
+ GInputStream* _tmp0_ = NULL;
+ GInputStream* _tmp1_ = NULL;
+ guint8* _tmp2_ = NULL;
+ gint _tmp2__length1 = 0;
+ _data_ = g_slice_new0 (SpiceCtrlInputStreamReadData);
+ _data_->_async_result = g_simple_async_result_new (NULL, _callback_, _user_data_, spice_ctrl_input_stream_read);
+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, spice_ctrl_input_stream_read_data_free);
+ _tmp0_ = stream;
+ _tmp1_ = _g_object_ref0 (_tmp0_);
+ _g_object_unref0 (_data_->stream);
+ _data_->stream = _tmp1_;
+ _tmp2_ = buffer;
+ _tmp2__length1 = buffer_length1;
+ _data_->buffer = _tmp2_;
+ _data_->buffer_length1 = _tmp2__length1;
+ spice_ctrl_input_stream_read_co (_data_);
+}
+
+
+void spice_ctrl_input_stream_read_finish (GAsyncResult* _res_, GError** error) {
+ SpiceCtrlInputStreamReadData* _data_;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
+ return;
+ }
+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
+}
+
+
+static void spice_ctrl_input_stream_read_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
+ SpiceCtrlInputStreamReadData* _data_;
+ _data_ = _user_data_;
+ _data_->_source_object_ = source_object;
+ _data_->_res_ = _res_;
+ spice_ctrl_input_stream_read_co (_data_);
+}
+
+
+static gboolean spice_ctrl_input_stream_read_co (SpiceCtrlInputStreamReadData* _data_) {
+ switch (_data_->_state_) {
+ case 0:
+ goto _state_0;
+ case 1:
+ goto _state_1;
+ default:
+ g_assert_not_reached ();
+ }
+ _state_0:
+ _data_->_tmp0_ = NULL;
+ _data_->_tmp0__length1 = 0;
+ _data_->_tmp0_ = _data_->buffer;
+ _data_->_tmp0__length1 = _data_->buffer_length1;
+ _data_->length = _data_->_tmp0__length1;
+ _data_->i = (gssize) 0;
+ while (TRUE) {
+ _data_->_tmp1_ = 0L;
+ _data_->_tmp1_ = _data_->i;
+ _data_->_tmp2_ = 0;
+ _data_->_tmp2_ = _data_->length;
+ if (!(_data_->_tmp1_ < ((gssize) _data_->_tmp2_))) {
+ break;
+ }
+ _data_->_tmp3_ = NULL;
+ _data_->_tmp3_ = _data_->stream;
+ _data_->_tmp4_ = NULL;
+ _data_->_tmp4__length1 = 0;
+ _data_->_tmp4_ = _data_->buffer;
+ _data_->_tmp4__length1 = _data_->buffer_length1;
+ _data_->_tmp5_ = 0L;
+ _data_->_tmp5_ = _data_->i;
+ _data_->_tmp6_ = 0;
+ _data_->_tmp6_ = _data_->length;
+ _data_->_state_ = 1;
+ g_input_stream_read_async (_data_->_tmp3_, _data_->_tmp4_ + ((gint) _data_->_tmp5_), (gsize) (_data_->_tmp6_ - ((gint) _data_->_tmp5_)), G_PRIORITY_DEFAULT, NULL, spice_ctrl_input_stream_read_ready, _data_);
+ return FALSE;
+ _state_1:
+ _data_->_tmp7_ = 0L;
+ _data_->_tmp7_ = g_input_stream_read_finish (_data_->_tmp3_, _data_->_res_, &_data_->_inner_error_);
+ _data_->n = _data_->_tmp7_;
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ if (_data_->_inner_error_->domain == G_IO_ERROR) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ } else {
+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error_->message, g_quark_to_string (_data_->_inner_error_->domain), _data_->_inner_error_->code);
+ g_clear_error (&_data_->_inner_error_);
+ return FALSE;
+ }
+ }
+ _data_->_tmp8_ = 0L;
+ _data_->_tmp8_ = _data_->n;
+ if (_data_->_tmp8_ == ((gssize) 0)) {
+ _data_->_tmp9_ = NULL;
+ _data_->_tmp9_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CLOSED, "closed stream");
+ _data_->_inner_error_ = _data_->_tmp9_;
+ if (_data_->_inner_error_->domain == G_IO_ERROR) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ } else {
+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error_->message, g_quark_to_string (_data_->_inner_error_->domain), _data_->_inner_error_->code);
+ g_clear_error (&_data_->_inner_error_);
+ return FALSE;
+ }
+ }
+ _data_->_tmp10_ = 0L;
+ _data_->_tmp10_ = _data_->i;
+ _data_->_tmp11_ = 0L;
+ _data_->_tmp11_ = _data_->n;
+ _data_->i = _data_->_tmp10_ + _data_->_tmp11_;
+ }
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+}
+
+
+static void spice_ctrl_output_stream_write_data_free (gpointer _data) {
+ SpiceCtrlOutputStreamWriteData* _data_;
+ _data_ = _data;
+ _g_object_unref0 (_data_->stream);
+ _data_->buffer = (g_free (_data_->buffer), NULL);
+ g_slice_free (SpiceCtrlOutputStreamWriteData, _data_);
+}
+
+
+void spice_ctrl_output_stream_write (GOutputStream* stream, guint8* buffer, int buffer_length1, GAsyncReadyCallback _callback_, gpointer _user_data_) {
+ SpiceCtrlOutputStreamWriteData* _data_;
+ GOutputStream* _tmp0_ = NULL;
+ GOutputStream* _tmp1_ = NULL;
+ _data_ = g_slice_new0 (SpiceCtrlOutputStreamWriteData);
+ _data_->_async_result = g_simple_async_result_new (NULL, _callback_, _user_data_, spice_ctrl_output_stream_write);
+ g_simple_async_result_set_op_res_gpointer (_data_->_async_result, _data_, spice_ctrl_output_stream_write_data_free);
+ _tmp0_ = stream;
+ _tmp1_ = _g_object_ref0 (_tmp0_);
+ _g_object_unref0 (_data_->stream);
+ _data_->stream = _tmp1_;
+ _data_->buffer = (g_free (_data_->buffer), NULL);
+ _data_->buffer = buffer;
+ _data_->buffer_length1 = buffer_length1;
+ spice_ctrl_output_stream_write_co (_data_);
+}
+
+
+void spice_ctrl_output_stream_write_finish (GAsyncResult* _res_, GError** error) {
+ SpiceCtrlOutputStreamWriteData* _data_;
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (_res_), error)) {
+ return;
+ }
+ _data_ = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (_res_));
+}
+
+
+static void spice_ctrl_output_stream_write_ready (GObject* source_object, GAsyncResult* _res_, gpointer _user_data_) {
+ SpiceCtrlOutputStreamWriteData* _data_;
+ _data_ = _user_data_;
+ _data_->_source_object_ = source_object;
+ _data_->_res_ = _res_;
+ spice_ctrl_output_stream_write_co (_data_);
+}
+
+
+static gboolean spice_ctrl_output_stream_write_co (SpiceCtrlOutputStreamWriteData* _data_) {
+ switch (_data_->_state_) {
+ case 0:
+ goto _state_0;
+ case 1:
+ goto _state_1;
+ default:
+ g_assert_not_reached ();
+ }
+ _state_0:
+ _data_->_tmp0_ = NULL;
+ _data_->_tmp0__length1 = 0;
+ _data_->_tmp0_ = _data_->buffer;
+ _data_->_tmp0__length1 = _data_->buffer_length1;
+ _data_->length = _data_->_tmp0__length1;
+ _data_->i = (gssize) 0;
+ while (TRUE) {
+ _data_->_tmp1_ = 0L;
+ _data_->_tmp1_ = _data_->i;
+ _data_->_tmp2_ = 0;
+ _data_->_tmp2_ = _data_->length;
+ if (!(_data_->_tmp1_ < ((gssize) _data_->_tmp2_))) {
+ break;
+ }
+ _data_->_tmp3_ = NULL;
+ _data_->_tmp3_ = _data_->stream;
+ _data_->_tmp4_ = NULL;
+ _data_->_tmp4__length1 = 0;
+ _data_->_tmp4_ = _data_->buffer;
+ _data_->_tmp4__length1 = _data_->buffer_length1;
+ _data_->_tmp5_ = 0L;
+ _data_->_tmp5_ = _data_->i;
+ _data_->_tmp6_ = 0;
+ _data_->_tmp6_ = _data_->length;
+ _data_->_state_ = 1;
+ g_output_stream_write_async (_data_->_tmp3_, _data_->_tmp4_ + ((gint) _data_->_tmp5_), (gsize) (_data_->_tmp6_ - ((gint) _data_->_tmp5_)), G_PRIORITY_DEFAULT, NULL, spice_ctrl_output_stream_write_ready, _data_);
+ return FALSE;
+ _state_1:
+ _data_->_tmp7_ = 0L;
+ _data_->_tmp7_ = g_output_stream_write_finish (_data_->_tmp3_, _data_->_res_, &_data_->_inner_error_);
+ _data_->n = _data_->_tmp7_;
+ if (G_UNLIKELY (_data_->_inner_error_ != NULL)) {
+ if (_data_->_inner_error_->domain == G_IO_ERROR) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _data_->buffer = (g_free (_data_->buffer), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ } else {
+ _data_->buffer = (g_free (_data_->buffer), NULL);
+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error_->message, g_quark_to_string (_data_->_inner_error_->domain), _data_->_inner_error_->code);
+ g_clear_error (&_data_->_inner_error_);
+ return FALSE;
+ }
+ }
+ _data_->_tmp8_ = 0L;
+ _data_->_tmp8_ = _data_->n;
+ if (_data_->_tmp8_ == ((gssize) 0)) {
+ _data_->_tmp9_ = NULL;
+ _data_->_tmp9_ = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CLOSED, "closed stream");
+ _data_->_inner_error_ = _data_->_tmp9_;
+ if (_data_->_inner_error_->domain == G_IO_ERROR) {
+ g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_);
+ g_error_free (_data_->_inner_error_);
+ _data_->buffer = (g_free (_data_->buffer), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+ } else {
+ _data_->buffer = (g_free (_data_->buffer), NULL);
+ g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error_->message, g_quark_to_string (_data_->_inner_error_->domain), _data_->_inner_error_->code);
+ g_clear_error (&_data_->_inner_error_);
+ return FALSE;
+ }
+ }
+ _data_->_tmp10_ = 0L;
+ _data_->_tmp10_ = _data_->i;
+ _data_->_tmp11_ = 0L;
+ _data_->_tmp11_ = _data_->n;
+ _data_->i = _data_->_tmp10_ + _data_->_tmp11_;
+ }
+ _data_->buffer = (g_free (_data_->buffer), NULL);
+ if (_data_->_state_ == 0) {
+ g_simple_async_result_complete_in_idle (_data_->_async_result);
+ } else {
+ g_simple_async_result_complete (_data_->_async_result);
+ }
+ g_object_unref (_data_->_async_result);
+ return FALSE;
+}
+
+
+
--- /dev/null
+// Copyright (C) 2012 Red Hat, Inc.
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+namespace SpiceCtrl {
+
+ public async void input_stream_read (InputStream stream, uint8[] buffer) throws GLib.IOError {
+ var length = buffer.length;
+ ssize_t i = 0;
+
+ while (i < length) {
+ var n = yield stream.read_async (buffer[i:length]);
+ if (n == 0)
+ throw new GLib.IOError.CLOSED ("closed stream") ;
+ i += n;
+ }
+ }
+
+ public async void output_stream_write (OutputStream stream, owned uint8[] buffer) throws GLib.IOError {
+ var length = buffer.length;
+ ssize_t i = 0;
+
+ while (i < length) {
+ var n = yield stream.write_async (buffer[i:length]);
+ if (n == 0)
+ throw new GLib.IOError.CLOSED ("closed stream") ;
+ i += n;
+ }
+ }
+
+}
--- /dev/null
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+#include "win32-util.h"
+#include <windows.h>
+#include <sddl.h>
+#include <aclapi.h>
+
+gboolean
+spice_win32_set_low_integrity (void* handle, GError **error)
+{
+ g_return_val_if_fail (handle != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ /* see also http://msdn.microsoft.com/en-us/library/bb625960.aspx */
+ PSECURITY_DESCRIPTOR psd = NULL;
+ PACL psacl = NULL;
+ BOOL sacl_present = FALSE;
+ BOOL sacl_defaulted = FALSE;
+ char *emsg;
+ int errsv;
+ gboolean success = FALSE;
+
+ if (!ConvertStringSecurityDescriptorToSecurityDescriptor ("S:(ML;;NW;;;LW)",
+ SDDL_REVISION_1, &psd, NULL))
+ goto failed;
+
+ if (!GetSecurityDescriptorSacl (psd, &sacl_present, &psacl, &sacl_defaulted))
+ goto failed;
+
+ if (SetSecurityInfo (handle, SE_KERNEL_OBJECT, LABEL_SECURITY_INFORMATION,
+ NULL, NULL, NULL, psacl) != ERROR_SUCCESS)
+ goto failed;
+
+ success = TRUE;
+ goto end;
+
+failed:
+ errsv = GetLastError ();
+ emsg = g_win32_error_message (errsv);
+ g_set_error (error, G_IO_ERROR,
+ g_io_error_from_win32_error (errsv),
+ "Error setting integrity: %s",
+ emsg);
+ g_free (emsg);
+
+end:
+ if (psd != NULL)
+ LocalFree (psd);
+
+ return success;
+}
+
+static gboolean
+get_user_security_attributes (SECURITY_ATTRIBUTES* psa, SECURITY_DESCRIPTOR* psd, PACL* ppdacl)
+{
+ EXPLICIT_ACCESS ea;
+ TRUSTEE trst;
+ DWORD ret = 0;
+
+ ZeroMemory (psa, sizeof (*psa));
+ ZeroMemory (psd, sizeof (*psd));
+ psa->nLength = sizeof (*psa);
+ psa->bInheritHandle = FALSE;
+ psa->lpSecurityDescriptor = psd;
+
+ ZeroMemory (&trst, sizeof (trst));
+ trst.pMultipleTrustee = NULL;
+ trst.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
+ trst.TrusteeForm = TRUSTEE_IS_NAME;
+ trst.TrusteeType = TRUSTEE_IS_USER;
+ trst.ptstrName = "CURRENT_USER";
+
+ ZeroMemory (&ea, sizeof (ea));
+ ea.grfAccessPermissions = GENERIC_WRITE | GENERIC_READ;
+ ea.grfAccessMode = SET_ACCESS;
+ ea.grfInheritance = NO_INHERITANCE;
+ ea.Trustee = trst;
+
+ ret = SetEntriesInAcl (1, &ea, NULL, ppdacl);
+ if (ret != ERROR_SUCCESS)
+ return FALSE;
+
+ if (!InitializeSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION))
+ return FALSE;
+
+ if (!SetSecurityDescriptorDacl (psd, TRUE, *ppdacl, FALSE))
+ return FALSE;
+
+ return TRUE;
+}
+
+#define DEFAULT_PIPE_BUF_SIZE 4096
+
+SpiceNamedPipe*
+spice_win32_user_pipe_new (gchar *name, GError **error)
+{
+ SECURITY_ATTRIBUTES sa;
+ SECURITY_DESCRIPTOR sd;
+ PACL dacl = NULL;
+ HANDLE pipe;
+ SpiceNamedPipe *np = NULL;
+
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (error != NULL, NULL);
+
+ if (!get_user_security_attributes (&sa, &sd, &dacl))
+ return NULL;
+
+ pipe = CreateNamedPipe (name,
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
+ /* FIXME: why is FILE_FLAG_FIRST_PIPE_INSTANCE needed for WRITE_DAC
+ * (apparently needed by SetSecurityInfo). This will prevent
+ * multiple pipe listener....?! */
+ FILE_FLAG_FIRST_PIPE_INSTANCE | WRITE_DAC,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ PIPE_UNLIMITED_INSTANCES,
+ DEFAULT_PIPE_BUF_SIZE, DEFAULT_PIPE_BUF_SIZE,
+ 0, &sa);
+
+ if (pipe == INVALID_HANDLE_VALUE) {
+ int errsv = GetLastError ();
+ gchar *emsg = g_win32_error_message (errsv);
+
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_win32_error (errsv),
+ "Error CreateNamedPipe(): %s",
+ emsg);
+
+ g_free (emsg);
+ goto end;
+ }
+
+ /* lower integrity on Vista/Win7+ */
+ if ((LOBYTE (g_win32_get_windows_version()) > 0x05) &&
+ !spice_win32_set_low_integrity (pipe, error))
+ goto end;
+
+ np = SPICE_NAMED_PIPE (g_initable_new (SPICE_TYPE_NAMED_PIPE,
+ NULL, error, "handle", pipe, NULL));
+
+end:
+ LocalFree (dacl);
+
+ return np;
+}
--- /dev/null
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __WIN32_UTIL_H__
+#define __WIN32_UTIL_H__
+
+#include <gio/gio.h>
+#include "namedpipe.h"
+
+G_BEGIN_DECLS
+
+gboolean spice_win32_set_low_integrity (void* handle, GError **error);
+SpiceNamedPipe* spice_win32_user_pipe_new (gchar *name, GError **error);
+
+G_END_DECLS
+
+#endif /* __WIN32_UTIL_H__ */
--- /dev/null
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.0 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _COROUTINE_H_
+#define _COROUTINE_H_
+
+#include "config.h"
+
+#if WITH_UCONTEXT
+#include "continuation.h"
+#elif WITH_WINFIBER
+#include <windows.h>
+#else
+#include <glib.h>
+#endif
+
+struct coroutine
+{
+ size_t stack_size;
+ void *(*entry)(void *);
+ int (*release)(struct coroutine *);
+
+ /* read-only */
+ int exited;
+
+ /* private */
+ struct coroutine *caller;
+ void *data;
+
+#if WITH_UCONTEXT
+ struct continuation cc;
+#elif WITH_WINFIBER
+ LPVOID fiber;
+ int ret;
+#else
+ GThread *thread;
+ gboolean runnable;
+#endif
+};
+
+void coroutine_init(struct coroutine *co);
+
+int coroutine_release(struct coroutine *co);
+
+void *coroutine_swap(struct coroutine *from, struct coroutine *to, void *arg);
+
+struct coroutine *coroutine_self(void);
+
+void *coroutine_yieldto(struct coroutine *to, void *arg);
+
+void *coroutine_yield(void *arg);
+
+gboolean coroutine_is_main(struct coroutine *co);
+
+static inline gboolean coroutine_self_is_main(void) {
+ return coroutine_self() == NULL || coroutine_is_main(coroutine_self());
+}
+
+#endif
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
--- /dev/null
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.0 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "coroutine.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static GCond *run_cond;
+static GMutex *run_lock;
+static struct coroutine *current;
+static struct coroutine leader;
+
+#if 0
+#define CO_DEBUG(OP) fprintf(stderr, "%s %p %s %d\n", OP, g_thread_self(), __FUNCTION__, __LINE__)
+#else
+#define CO_DEBUG(OP)
+#endif
+
+static void coroutine_system_init(void)
+{
+ if (!g_thread_supported()) {
+ CO_DEBUG("INIT");
+ g_thread_init(NULL);
+ }
+
+
+ run_cond = g_cond_new();
+ run_lock = g_mutex_new();
+ CO_DEBUG("LOCK");
+ g_mutex_lock(run_lock);
+
+ /* The thread that creates the first coroutine is the system coroutine
+ * so let's fill out a structure for it */
+ leader.entry = NULL;
+ leader.release = NULL;
+ leader.stack_size = 0;
+ leader.exited = 0;
+ leader.thread = g_thread_self();
+ leader.runnable = TRUE; /* we're the one running right now */
+ leader.caller = NULL;
+ leader.data = NULL;
+
+ current = &leader;
+}
+
+static gpointer coroutine_thread(gpointer opaque)
+{
+ struct coroutine *co = opaque;
+ CO_DEBUG("LOCK");
+ g_mutex_lock(run_lock);
+ while (!co->runnable) {
+ CO_DEBUG("WAIT");
+ g_cond_wait(run_cond, run_lock);
+ }
+
+ CO_DEBUG("RUNNABLE");
+ current = co;
+ co->caller->data = co->entry(co->data);
+ co->exited = 1;
+
+ co->caller->runnable = TRUE;
+ CO_DEBUG("BROADCAST");
+ g_cond_broadcast(run_cond);
+ CO_DEBUG("UNLOCK");
+ g_mutex_unlock(run_lock);
+
+ return NULL;
+}
+
+void coroutine_init(struct coroutine *co)
+{
+ GError *err = NULL;
+
+ if (run_cond == NULL)
+ coroutine_system_init();
+
+ CO_DEBUG("NEW");
+ co->thread = g_thread_create_full(coroutine_thread, co, co->stack_size,
+ FALSE, TRUE,
+ G_THREAD_PRIORITY_NORMAL,
+ &err);
+ if (err != NULL)
+ g_error("g_thread_create_full() failed: %s", err->message);
+
+ co->exited = 0;
+ co->runnable = FALSE;
+ co->caller = NULL;
+}
+
+int coroutine_release(struct coroutine *co G_GNUC_UNUSED)
+{
+ return 0;
+}
+
+void *coroutine_swap(struct coroutine *from, struct coroutine *to, void *arg)
+{
+ from->runnable = FALSE;
+ to->runnable = TRUE;
+ to->data = arg;
+ to->caller = from;
+ CO_DEBUG("BROADCAST");
+ g_cond_broadcast(run_cond);
+ CO_DEBUG("UNLOCK");
+ g_mutex_unlock(run_lock);
+ CO_DEBUG("LOCK");
+ g_mutex_lock(run_lock);
+ while (!from->runnable) {
+ CO_DEBUG("WAIT");
+ g_cond_wait(run_cond, run_lock);
+ }
+ current = from;
+ to->caller = NULL;
+
+ CO_DEBUG("SWAPPED");
+ return from->data;
+}
+
+struct coroutine *coroutine_self(void)
+{
+ if (run_cond == NULL)
+ coroutine_system_init();
+
+ return current;
+}
+
+void *coroutine_yieldto(struct coroutine *to, void *arg)
+{
+ g_return_val_if_fail(!to->caller, NULL);
+ g_return_val_if_fail(!to->exited, NULL);
+
+ CO_DEBUG("SWAP");
+ return coroutine_swap(coroutine_self(), to, arg);
+}
+
+void *coroutine_yield(void *arg)
+{
+ struct coroutine *to = coroutine_self()->caller;
+ if (!to) {
+ fprintf(stderr, "Co-routine is yielding to no one\n");
+ abort();
+ }
+
+ CO_DEBUG("SWAP");
+ coroutine_self()->caller = NULL;
+ return coroutine_swap(coroutine_self(), to, arg);
+}
+
+gboolean coroutine_is_main(struct coroutine *co)
+{
+ return (co == &leader);
+}
--- /dev/null
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.0 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <glib.h>
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <sys/mman.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "coroutine.h"
+
+#ifndef MAP_ANONYMOUS
+# define MAP_ANONYMOUS MAP_ANON
+#endif
+
+int coroutine_release(struct coroutine *co)
+{
+ return cc_release(&co->cc);
+}
+
+static int _coroutine_release(struct continuation *cc)
+{
+ struct coroutine *co = container_of(cc, struct coroutine, cc);
+
+ if (co->release) {
+ int ret = co->release(co);
+ if (ret < 0)
+ return ret;
+ }
+
+ munmap(co->cc.stack, co->cc.stack_size);
+
+ co->caller = NULL;
+
+ return 0;
+}
+
+static void coroutine_trampoline(struct continuation *cc)
+{
+ struct coroutine *co = container_of(cc, struct coroutine, cc);
+ co->data = co->entry(co->data);
+}
+
+void coroutine_init(struct coroutine *co)
+{
+ if (co->stack_size == 0)
+ co->stack_size = 16 << 20;
+
+ co->cc.stack_size = co->stack_size;
+ co->cc.stack = mmap(0, co->stack_size,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1, 0);
+ if (co->cc.stack == MAP_FAILED)
+ g_error("mmap(%" G_GSIZE_FORMAT ") failed: %s",
+ co->stack_size, g_strerror(errno));
+
+ co->cc.entry = coroutine_trampoline;
+ co->cc.release = _coroutine_release;
+ co->exited = 0;
+
+ cc_init(&co->cc);
+}
+
+#if 0
+static __thread struct coroutine leader;
+static __thread struct coroutine *current;
+#else
+static struct coroutine leader;
+static struct coroutine *current;
+#endif
+
+struct coroutine *coroutine_self(void)
+{
+ if (current == NULL)
+ current = &leader;
+ return current;
+}
+
+void *coroutine_swap(struct coroutine *from, struct coroutine *to, void *arg)
+{
+ int ret;
+ to->data = arg;
+ current = to;
+ ret = cc_swap(&from->cc, &to->cc);
+ if (ret == 0)
+ return from->data;
+ else if (ret == 1) {
+ coroutine_release(to);
+ current = from;
+ to->exited = 1;
+ return to->data;
+ }
+
+ return NULL;
+}
+
+void *coroutine_yieldto(struct coroutine *to, void *arg)
+{
+ g_return_val_if_fail(!to->caller, NULL);
+ g_return_val_if_fail(!to->exited, NULL);
+
+ to->caller = coroutine_self();
+ return coroutine_swap(coroutine_self(), to, arg);
+}
+
+void *coroutine_yield(void *arg)
+{
+ struct coroutine *to = coroutine_self()->caller;
+ if (!to) {
+ fprintf(stderr, "Co-routine is yielding to no one\n");
+ abort();
+ }
+ coroutine_self()->caller = NULL;
+ return coroutine_swap(coroutine_self(), to, arg);
+}
+
+gboolean coroutine_is_main(struct coroutine *co)
+{
+ return (co == &leader);
+}
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
--- /dev/null
+/*
+ * SpiceGtk coroutine with Windows fibers
+ *
+ * Copyright (C) 2011 Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.0 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <glib.h>
+
+#include "coroutine.h"
+
+static struct coroutine leader = { 0, };
+static struct coroutine *current = NULL;
+static struct coroutine *caller = NULL;
+
+int coroutine_release(struct coroutine *co)
+{
+ DeleteFiber(co->fiber);
+ return 0;
+}
+
+static void WINAPI coroutine_trampoline(LPVOID lpParameter)
+{
+ struct coroutine *co = (struct coroutine *)lpParameter;
+
+ co->data = co->entry(co->data);
+
+ if (co->release)
+ co->ret = co->release(co);
+ else
+ co->ret = 0;
+
+ co->caller = NULL;
+
+ // and switch back to caller
+ co->ret = 1;
+ SwitchToFiber(caller->fiber);
+}
+
+void coroutine_init(struct coroutine *co)
+{
+ if (leader.fiber == NULL) {
+ leader.fiber = ConvertThreadToFiber(&leader);
+ if (leader.fiber == NULL)
+ g_error("ConvertThreadToFiber() failed");
+ }
+
+ co->exited = 0;
+ co->fiber = CreateFiber(0, &coroutine_trampoline, co);
+ if (co->fiber == NULL)
+ g_error("CreateFiber() failed");
+
+ co->ret = 0;
+}
+
+struct coroutine *coroutine_self(void)
+{
+ if (current == NULL)
+ current = &leader;
+ return current;
+}
+
+void *coroutine_swap(struct coroutine *from, struct coroutine *to, void *arg)
+{
+ to->data = arg;
+ current = to;
+ caller = from;
+ SwitchToFiber(to->fiber);
+ if (to->ret == 0)
+ return from->data;
+ else if (to->ret == 1) {
+ coroutine_release(to);
+ current = &leader;
+ to->exited = 1;
+ return to->data;
+ }
+
+ return NULL;
+}
+
+void *coroutine_yieldto(struct coroutine *to, void *arg)
+{
+ g_return_val_if_fail(!to->caller, NULL);
+ g_return_val_if_fail(!to->exited, NULL);
+
+ to->caller = coroutine_self();
+ return coroutine_swap(coroutine_self(), to, arg);
+}
+
+void *coroutine_yield(void *arg)
+{
+ struct coroutine *to = coroutine_self()->caller;
+ if (!to) {
+ fprintf(stderr, "Co-routine is yielding to no one\n");
+ abort();
+ }
+ coroutine_self()->caller = NULL;
+ return coroutine_swap(coroutine_self(), to, arg);
+}
+
+gboolean coroutine_is_main(struct coroutine *co)
+{
+ return (co == &leader);
+}
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
--- /dev/null
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+// External defines: PLT, RGBX/PLTXX/ALPHA, TO_RGB32.
+// If PLT4/1 and TO_RGB32 are defined, we need CAST_PLT_DISTANCE (
+// because then the number of pixels differ from the units used in the compression)
+
+/*
+ For each output pixel type the following macros are defined:
+ OUT_PIXEL - the output pixel type
+ COPY_PIXEL(p, out) - assigns the pixel to the place pointed by out and
+ increases out. Used in RLE.
+ Need special handling because in alpha we copy only
+ the pad byte.
+ COPY_REF_PIXEL(ref, out) - copies the pixel pointed by ref to the pixel pointed by out.
+ Increases ref and out.
+ COPY_COMP_PIXEL(encoder, out) - copies pixel from the compressed buffer to the decompressed
+ buffer. Increases out.
+*/
+
+#if !defined(LZ_RGB_ALPHA)
+#define COPY_PIXEL(p, out) (*(out++) = p)
+#define COPY_REF_PIXEL(ref, out) (*(out++) = *(ref++))
+#endif
+
+// decompressing plt to plt
+#ifdef LZ_PLT
+#ifndef TO_RGB32
+#define OUT_PIXEL one_byte_pixel_t
+#define FNAME(name) glz_plt_##name
+#define COPY_COMP_PIXEL(in, out) {(out)->a = *(in++); out++;}
+#else // TO_RGB32
+#define OUT_PIXEL rgb32_pixel_t
+#define COPY_PLT_ENTRY(ent, out) {\
+ (out)->b = ent; (out)->g = (ent >> 8); (out)->r = (ent >> 16); (out)->pad = 0;}
+#ifdef PLT8
+#define FNAME(name) glz_plt8_to_rgb32_##name
+#define COPY_COMP_PIXEL(in, out, palette) { \
+ uint32_t rgb = palette->ents[*(in++)]; \
+ COPY_PLT_ENTRY(rgb, out); \
+ out++; \
+}
+#elif defined(PLT4_BE)
+#define FNAME(name) glz_plt4_be_to_rgb32_##name
+#define COPY_COMP_PIXEL(in, out, palette){ \
+ uint8_t byte = *(in++); \
+ uint32_t rgb = palette->ents[((byte >> 4) & 0x0f) % (palette->num_ents)]; \
+ COPY_PLT_ENTRY(rgb, out); \
+ out++; \
+ rgb = palette->ents[(byte & 0x0f) % (palette->num_ents)]; \
+ COPY_PLT_ENTRY(rgb, out); \
+ out++; \
+}
+#define CAST_PLT_DISTANCE(dist) (dist*2)
+#elif defined(PLT4_LE)
+#define FNAME(name) glz_plt4_le_to_rgb32_##name
+#define COPY_COMP_PIXEL(in, out, palette){ \
+ uint8_t byte = *(in++); \
+ uint32_t rgb = palette->ents[(byte & 0x0f) % (palette->num_ents)]; \
+ COPY_PLT_ENTRY(rgb, out); \
+ out++; \
+ rgb = palette->ents[((byte >> 4) & 0x0f) % (palette->num_ents)]; \
+ COPY_PLT_ENTRY(rgb, out); \
+ out++; \
+}
+#define CAST_PLT_DISTANCE(dist) (dist*2)
+#elif defined(PLT1_BE) // TODO store palette entries for direct access
+#define FNAME(name) glz_plt1_be_to_rgb32_##name
+#define COPY_COMP_PIXEL(in, out, palette){ \
+ uint8_t byte = *(in++); \
+ int i; \
+ uint32_t fore = palette->ents[1]; \
+ uint32_t back = palette->ents[0]; \
+ for (i = 7; i >= 0; i--) \
+ { \
+ if ((byte >> i) & 1) { \
+ COPY_PLT_ENTRY(fore, out); \
+ } else { \
+ COPY_PLT_ENTRY(back, out); \
+ } \
+ out++; \
+ } \
+}
+#define CAST_PLT_DISTANCE(dist) (dist*8)
+#elif defined(PLT1_LE)
+#define FNAME(name) glz_plt1_le_to_rgb32_##name
+#define COPY_COMP_PIXEL(in, out, palette){ \
+ uint8_t byte = *(in++); \
+ int i; \
+ uint32_t fore = palette->ents[1]; \
+ uint32_t back = palette->ents[0]; \
+ for (i = 0; i < 8; i++) \
+ { \
+ if ((byte >> i) & 1) { \
+ COPY_PLT_ENTRY(fore, out); \
+ } else { \
+ COPY_PLT_ENTRY(back, out); \
+ } \
+ out++; \
+ } \
+}
+#define CAST_PLT_DISTANCE(dist) (dist*8)
+#endif // PLT Type
+#endif // TO_RGB32
+#endif
+
+#ifdef LZ_RGB16
+#ifndef TO_RGB32
+#define OUT_PIXEL rgb16_pixel_t
+#define FNAME(name) glz_rgb16_##name
+#define COPY_COMP_PIXEL(in, out) {*out = (*(in++)) << 8; *out |= *(in++); out++;}
+#else
+#define OUT_PIXEL rgb32_pixel_t
+#define FNAME(name) glz_rgb16_to_rgb32_##name
+#define COPY_COMP_PIXEL(in, out) {out->r = *(in++); out->b= *(in++); \
+ out->g = (((out->r) << 6) | ((out->b) >> 2)) & ~0x07; \
+ out->g |= (out->g >> 5); \
+ out->r = ((out->r << 1) & ~0x07) | ((out->r >> 4) & 0x07) ; \
+ out->b = (out->b << 3) | ((out->b >> 2) & 0x07); \
+ out->pad = 0; \
+ out++; \
+}
+#endif
+#endif
+
+#ifdef LZ_RGB24
+#define OUT_PIXEL rgb24_pixel_t
+#define FNAME(name) glz_rgb24_##name
+#define COPY_COMP_PIXEL(in, out) { \
+ out->b = *(in++); \
+ out->g = *(in++); \
+ out->r = *(in++); \
+ out++; \
+}
+#endif
+
+#ifdef LZ_RGB32
+#define OUT_PIXEL rgb32_pixel_t
+#define FNAME(name) glz_rgb32_##name
+#define COPY_COMP_PIXEL(in, out) { \
+ out->b = *(in++); \
+ out->g = *(in++); \
+ out->r = *(in++); \
+ out->pad = 0; \
+ out++; \
+}
+#endif
+
+#ifdef LZ_RGB_ALPHA
+#define OUT_PIXEL rgb32_pixel_t
+#define FNAME(name) glz_rgb_alpha_##name
+#define COPY_PIXEL(p, out) {out->pad = p.pad; out++;}
+#define COPY_REF_PIXEL(ref, out) {out->pad = ref->pad; out++; ref++;}
+#define COPY_COMP_PIXEL(in, out) {out->pad = *(in++); out++;}
+#endif
+
+// TODO: separate into routines that decode to dist,len. and to a routine that
+// actually copies the data.
+
+/* returns num of bytes read from in buf.
+ size should be in PIXEL */
+static size_t FNAME(decode)(SpiceGlzDecoderWindow *window,
+ uint8_t* in_buf, uint8_t *out_buf, int size,
+ uint64_t image_id, SpicePalette *plt)
+{
+ uint8_t *ip = in_buf;
+ OUT_PIXEL *out_pix_buf = (OUT_PIXEL *)out_buf;
+ OUT_PIXEL *op = out_pix_buf;
+ OUT_PIXEL *op_limit = out_pix_buf + size;
+
+ uint32_t ctrl = *(ip++);
+ int loop = true;
+
+ do {
+ if (ctrl >= MAX_COPY) { // reference (dictionary/RLE)
+ OUT_PIXEL *ref = op;
+ uint32_t len = ctrl >> 5;
+ uint8_t pixel_flag = (ctrl >> 4) & 0x01;
+ uint32_t pixel_ofs = (ctrl & 0x0f);
+ uint8_t image_flag;
+ uint32_t image_dist;
+
+ /* retrieving the referenced images, the offset of the first pixel,
+ and the match length */
+
+ uint8_t code;
+ //len--; // TODO: why do we do this?
+
+ if (len == 7) { // match length is bigger than 7
+ do {
+ code = *(ip++);
+ len += code;
+ } while (code == 255); // remaining of len
+ }
+ code = *(ip++);
+ pixel_ofs += (code << 4);
+
+ code = *(ip++);
+ image_flag = (code >> 6) & 0x03;
+ if (!pixel_flag) { // short pixel offset
+ int i;
+ image_dist = code & 0x3f;
+ for (i = 0; i < image_flag; i++) {
+ code = *(ip++);
+ image_dist += (code << (6 + (8 * i)));
+ }
+ } else {
+ int i;
+ pixel_flag = (code >> 5) & 0x01;
+ pixel_ofs += (code & 0x1f) << 12;
+ image_dist = 0;
+ for (i = 0; i < image_flag; i++) {
+ code = *(ip++);
+ image_dist += (code << 8 * i);
+ }
+
+
+ if (pixel_flag) { // very long pixel offset
+ code = *(ip++);
+ pixel_ofs += code << 17;
+ }
+ }
+
+#if defined(LZ_PLT) || defined(LZ_RGB_ALPHA)
+ len += 2; // length is biased by 2 (fixing bias)
+#elif defined(LZ_RGB16)
+ len += 1; // length is biased by 1 (fixing bias)
+#endif
+ if (!image_dist) {
+ pixel_ofs += 1; // offset is biased by 1 (fixing bias)
+ }
+
+#if defined(TO_RGB32)
+#if defined(PLT4_BE) || defined(PLT4_LE) || defined(PLT1_BE) || defined(PLT1_LE)
+ pixel_ofs = CAST_PLT_DISTANCE(pixel_ofs);
+ len = CAST_PLT_DISTANCE(len);
+#endif
+#endif
+
+ if (!image_dist) { // reference is inside the same image
+ ref -= pixel_ofs;
+ g_return_val_if_fail(ref + len <= op_limit, 0);
+ g_return_val_if_fail(ref >= out_pix_buf, 0);
+ } else {
+ ref = glz_decoder_window_bits(window, image_id,
+ image_dist, pixel_ofs);
+ }
+
+ g_return_val_if_fail(ref != NULL, 0);
+ g_return_val_if_fail(op + len <= op_limit, 0);
+
+ /* copying the match*/
+
+ if (ref == (op - 1)) { // run (this will never be called in PLT4/1_TO_RGB because the
+ // number of pixel copied is larger then one...
+ /* optimize copy for a run */
+ OUT_PIXEL b = *ref;
+ for (; len; --len) {
+ COPY_PIXEL(b, op);
+ g_return_val_if_fail(op <= op_limit, 0);
+ }
+ } else {
+ for (; len; --len) {
+ COPY_REF_PIXEL(ref, op);
+ g_return_val_if_fail(op <= op_limit, 0);
+ }
+ }
+ } else { // copy
+ ctrl++; // copy count is biased by 1
+#if defined(TO_RGB32) && (defined(PLT4_BE) || defined(PLT4_LE) || defined(PLT1_BE) || \
+ defined(PLT1_LE))
+ g_return_val_if_fail(op + CAST_PLT_DISTANCE(ctrl) <= op_limit, 0);
+#else
+ g_return_val_if_fail(op + ctrl <= op_limit, 0);
+#endif
+
+#if defined(TO_RGB32) && defined(LZ_PLT)
+ g_return_val_if_fail(plt, 0);
+ COPY_COMP_PIXEL(ip, op, plt);
+#else
+ COPY_COMP_PIXEL(ip, op);
+#endif
+ g_return_val_if_fail(op <= op_limit, 0);
+
+ for (--ctrl; ctrl; ctrl--) {
+#if defined(TO_RGB32) && defined(LZ_PLT)
+ g_return_val_if_fail(plt, 0);
+ COPY_COMP_PIXEL(ip, op, plt);
+#else
+ COPY_COMP_PIXEL(ip, op);
+#endif
+ g_return_val_if_fail(op <= op_limit, 0);
+ }
+ } // END REF/COPY
+
+ if (LZ_EXPECT_CONDITIONAL(op < op_limit)) {
+ ctrl = *(ip++);
+ } else {
+ loop = false;
+ }
+ } while (LZ_EXPECT_CONDITIONAL(loop));
+
+ return (ip - in_buf);
+}
+#undef LZ_PLT
+#undef PLT8
+#undef PLT4_BE
+#undef PLT4_LE
+#undef PLT1_BE
+#undef PLT1_LE
+#undef LZ_RGB16
+#undef LZ_RGB24
+#undef LZ_RGB32
+#undef LZ_RGB_ALPHA
+#undef TO_RGB32
+#undef OUT_PIXEL
+#undef FNAME
+#undef COPY_PIXEL
+#undef COPY_REF_PIXEL
+#undef COPY_COMP_PIXEL
+#undef COPY_PLT_ENTRY
+#undef CAST_PLT_DISTANCE
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+#include <glib.h>
+
+#include "gio-coroutine.h"
+#include "spice-util.h"
+#include "decode.h"
+
+#include "common/canvas_utils.h"
+
+struct glz_image_hdr {
+ uint64_t id;
+ LzImageType type;
+ uint32_t width;
+ uint32_t height;
+ uint32_t gross_pixels;
+ bool top_down;
+ uint32_t win_head_dist;
+};
+
+struct glz_image {
+ struct glz_image_hdr hdr;
+ pixman_image_t *surface;
+ uint8_t *data;
+};
+
+static struct glz_image *glz_image_new(struct glz_image_hdr *hdr,
+ int type, void *opaque)
+{
+ struct glz_image *img;
+
+ g_return_val_if_fail(type == LZ_IMAGE_TYPE_RGB32 || type == LZ_IMAGE_TYPE_RGBA, NULL);
+
+ img = g_new0(struct glz_image, 1);
+ img->hdr = *hdr;
+ img->surface = alloc_lz_image_surface
+ (opaque, type == LZ_IMAGE_TYPE_RGBA ? PIXMAN_LE_a8r8g8b8 : PIXMAN_LE_x8r8g8b8,
+ img->hdr.width, img->hdr.height, img->hdr.gross_pixels, img->hdr.top_down);
+ pixman_image_ref(img->surface);
+ img->data = (uint8_t *)pixman_image_get_data(img->surface);
+ if (!img->hdr.top_down) {
+ img->data = img->data - img->hdr.width * (img->hdr.height - 1) * 4;
+ }
+ return img;
+}
+
+static void glz_image_destroy(struct glz_image *img)
+{
+ if (img == NULL)
+ return;
+
+ pixman_image_unref(img->surface);
+ free(img);
+}
+
+/* ------------------------------------------------------------------ */
+
+#define INIT_IMAGES_CAPACITY 100
+#define WIN_OVERFLOW_FACTOR 1.5
+#define WIN_REALLOC_FACTOR 1.5
+
+struct SpiceGlzDecoderWindow {
+ struct glz_image **images;
+ uint32_t nimages;
+ uint64_t oldest;
+ uint64_t tail_gap;
+};
+
+static void glz_decoder_window_resize(SpiceGlzDecoderWindow *w)
+{
+ struct glz_image **new_images;
+ int i, new_slot;
+
+ SPICE_DEBUG("%s: array resize %u -> %u", __FUNCTION__,
+ w->nimages, w->nimages * 2);
+ new_images = g_new0(struct glz_image*, w->nimages * 2);
+ for (i = 0; i < w->nimages; i++) {
+ if (w->images[i] == NULL) {
+ /*
+ * We can have empty slots when images come in out of order, this
+ * can happen when a vm has multiple displays, since each display
+ * uses its own socket there is no guarantee that images
+ * originating from different displays are received in id order.
+ */
+ continue;
+ }
+ new_slot = w->images[i]->hdr.id % (w->nimages * 2);
+ new_images[new_slot] = w->images[i];
+ }
+ free(w->images);
+ w->images = new_images;
+ w->nimages *= 2;
+}
+
+static void glz_decoder_window_add(SpiceGlzDecoderWindow *w,
+ struct glz_image *img)
+{
+ int slot = img->hdr.id % w->nimages;
+
+ if (w->images[slot]) {
+ /* need more space */
+ glz_decoder_window_resize(w);
+ slot = img->hdr.id % w->nimages;
+ }
+
+ w->images[slot] = img;
+
+ /* close the gap */
+ while (w->tail_gap <= img->hdr.id && w->images[w->tail_gap % w->nimages] != NULL)
+ w->tail_gap++;
+}
+
+struct wait_for_image_data {
+ SpiceGlzDecoderWindow *window;
+ uint64_t id;
+};
+
+static gboolean wait_for_image(gpointer data)
+{
+ struct wait_for_image_data *wait = data;
+ int slot = wait->id % wait->window->nimages;
+ struct glz_image *image = wait->window->images[slot];
+ gboolean ready = image && image->hdr.id == wait->id;
+
+ return ready;
+}
+
+static void *glz_decoder_window_bits(SpiceGlzDecoderWindow *w, uint64_t id,
+ uint32_t dist, uint32_t offset)
+{
+ struct wait_for_image_data data = {
+ .window = w,
+ .id = id - dist,
+ };
+
+ if (!g_coroutine_condition_wait(g_coroutine_self(), wait_for_image, &data))
+ SPICE_DEBUG("wait for image cancelled");
+
+ int slot = (id - dist) % w->nimages;
+
+ g_return_val_if_fail(w->images[slot] != NULL, NULL);
+ g_return_val_if_fail(w->images[slot]->hdr.id == id - dist, NULL);
+ g_return_val_if_fail(w->images[slot]->hdr.gross_pixels >= offset, NULL);
+
+ return w->images[slot]->data + offset * 4;
+}
+
+static void glz_decoder_window_release(SpiceGlzDecoderWindow *w,
+ uint64_t oldest)
+{
+ int slot;
+
+ while (w->oldest < oldest) {
+ slot = w->oldest % w->nimages;
+ g_clear_pointer(&w->images[slot], glz_image_destroy);
+ w->oldest++;
+ }
+}
+
+/* ------------------------------------------------------------------ */
+
+typedef struct GlibGlzDecoder {
+ SpiceGlzDecoder base;
+ uint8_t *in_start;
+ uint8_t *in_now;
+ SpiceGlzDecoderWindow *window;
+ struct glz_image_hdr image;
+} GlibGlzDecoder;
+
+/*
+ * Give hints to the compiler for branch prediction optimization.
+ */
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#define LZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
+#define LZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
+#else
+#define LZ_EXPECT_CONDITIONAL(c) (c)
+#define LZ_UNEXPECT_CONDITIONAL(c) (c)
+#endif
+
+
+#ifdef __GNUC__
+#define ATTR_PACKED __attribute__ ((__packed__))
+#else
+#define ATTR_PACKED
+#pragma pack(push)
+#pragma pack(1)
+#endif
+
+/*
+ * the palette images will be treated as one byte pixels. Their width
+ * should be transformed accordingly.
+ */
+typedef struct ATTR_PACKED one_byte_pixel_t {
+ uint8_t a;
+} one_byte_pixel_t;
+
+typedef struct ATTR_PACKED rgb32_pixel_t {
+ uint8_t b;
+ uint8_t g;
+ uint8_t r;
+ uint8_t pad;
+} rgb32_pixel_t;
+
+typedef struct ATTR_PACKED rgb24_pixel_t {
+ uint8_t b;
+ uint8_t g;
+ uint8_t r;
+} rgb24_pixel_t;
+
+typedef uint16_t rgb16_pixel_t;
+
+#ifndef __GNUC__
+#pragma pack(pop)
+#endif
+
+#undef ATTR_PACKED
+
+#define LZ_PLT
+#include "decode-glz-tmpl.c"
+
+#define LZ_PLT
+#define PLT8
+#define TO_RGB32
+#include "decode-glz-tmpl.c"
+
+#define LZ_PLT
+#define PLT4_BE
+#define TO_RGB32
+#include "decode-glz-tmpl.c"
+
+#define LZ_PLT
+#define PLT4_LE
+#define TO_RGB32
+#include "decode-glz-tmpl.c"
+
+#define LZ_PLT
+#define PLT1_BE
+#define TO_RGB32
+#include "decode-glz-tmpl.c"
+
+#define LZ_PLT
+#define PLT1_LE
+#define TO_RGB32
+#include "decode-glz-tmpl.c"
+
+
+#define LZ_RGB16
+#include "decode-glz-tmpl.c"
+#define LZ_RGB16
+#define TO_RGB32
+#include "decode-glz-tmpl.c"
+
+#define LZ_RGB24
+#include "decode-glz-tmpl.c"
+
+#define LZ_RGB32
+#include "decode-glz-tmpl.c"
+
+#define LZ_RGB_ALPHA
+#include "decode-glz-tmpl.c"
+
+#undef LZ_UNEXPECT_CONDITIONAL
+#undef LZ_EXPECT_CONDITIONAL
+
+typedef size_t (*decode_function)(SpiceGlzDecoderWindow *window,
+ uint8_t* in_buf, uint8_t *out_buf, int size,
+ uint64_t id, SpicePalette *plt);
+
+// ordered according to LZ_IMAGE_TYPE
+const decode_function DECODE_TO_RGB32[] = {
+ NULL,
+ glz_plt1_le_to_rgb32_decode,
+ glz_plt1_be_to_rgb32_decode,
+ glz_plt4_le_to_rgb32_decode,
+ glz_plt4_be_to_rgb32_decode,
+ glz_plt8_to_rgb32_decode,
+ glz_rgb16_to_rgb32_decode,
+ glz_rgb32_decode,
+ glz_rgb32_decode,
+ glz_rgb32_decode
+};
+
+const decode_function DECODE_TO_SAME[] = {
+ NULL,
+ glz_plt_decode,
+ glz_plt_decode,
+ glz_plt_decode,
+ glz_plt_decode,
+ glz_plt_decode,
+ glz_rgb16_decode,
+ glz_rgb24_decode,
+ glz_rgb32_decode,
+ glz_rgb32_decode
+};
+
+static uint32_t decode_32(GlibGlzDecoder *d)
+{
+ uint32_t word = 0;
+ word |= *(d->in_now++);
+ word <<= 8;
+ word |= *(d->in_now++);
+ word <<= 8;
+ word |= *(d->in_now++);
+ word <<= 8;
+ word |= *(d->in_now++);
+ return word;
+}
+
+static uint64_t decode_64(GlibGlzDecoder *d)
+{
+ uint64_t long_word = decode_32(d);
+ long_word <<= 32;
+ long_word |= decode_32(d);
+ return long_word;
+}
+
+static void decode_header(GlibGlzDecoder *d)
+{
+ uint32_t magic;
+ uint32_t version;
+ uint32_t stride;
+ uint8_t tmp;
+
+ magic = decode_32(d);
+ g_return_if_fail(magic == LZ_MAGIC);
+
+ version = decode_32(d);
+ g_return_if_fail(version == LZ_VERSION);
+
+ tmp = *(d->in_now++);
+
+ d->image.type = (LzImageType)(tmp & LZ_IMAGE_TYPE_MASK);
+ d->image.top_down = (tmp >> LZ_IMAGE_TYPE_LOG) ? true : false;
+ d->image.width = decode_32(d);
+ d->image.height = decode_32(d);
+ stride = decode_32(d);
+
+ if (IS_IMAGE_TYPE_PLT[d->image.type]) {
+ d->image.gross_pixels = stride * PLT_PIXELS_PER_BYTE[d->image.type]
+ * d->image.height;
+ } else {
+ d->image.gross_pixels = d->image.width * d->image.height;
+ }
+
+ d->image.id = decode_64(d);
+ d->image.win_head_dist = decode_32(d);
+
+ SPICE_DEBUG("%s: %ux%u, id %" PRIu64 ", ref %" PRIu64,
+ __FUNCTION__,
+ d->image.width, d->image.height, d->image.id,
+ d->image.id - d->image.win_head_dist);
+}
+
+static void decode(SpiceGlzDecoder *decoder,
+ uint8_t *data, SpicePalette *palette,
+ void *usr_data)
+{
+ GlibGlzDecoder *d = SPICE_CONTAINEROF(decoder, GlibGlzDecoder, base);
+ LzImageType decoded_type;
+ struct glz_image *decoded_image;
+ size_t n_in_bytes_decoded;
+
+ d->in_start = data;
+ d->in_now = data;
+
+ decode_header(d);
+
+ if (d->image.type == LZ_IMAGE_TYPE_RGBA) {
+ decoded_type = LZ_IMAGE_TYPE_RGBA;
+ } else {
+ decoded_type = LZ_IMAGE_TYPE_RGB32;
+ }
+
+ decoded_image = glz_image_new(&d->image, decoded_type, usr_data);
+
+ n_in_bytes_decoded = DECODE_TO_RGB32[d->image.type]
+ (d->window, d->in_now, decoded_image->data,
+ d->image.gross_pixels, d->image.id, palette);
+
+ d->in_now += n_in_bytes_decoded;
+
+ if (d->image.type == LZ_IMAGE_TYPE_RGBA) {
+ glz_rgb_alpha_decode(d->window, d->in_now, decoded_image->data,
+ d->image.gross_pixels, d->image.id, palette);
+ }
+
+ glz_decoder_window_add(d->window, decoded_image);
+
+ { /* release old images from last tail_gap, only if the gap is closed */
+ uint64_t oldest;
+ struct glz_image *image = d->window->images[(d->window->tail_gap - 1) % d->window->nimages];
+
+ g_return_if_fail(image != NULL);
+
+ oldest = image->hdr.id - image->hdr.win_head_dist;
+ glz_decoder_window_release(d->window, oldest);
+ }
+}
+
+/* ------------------------------------------------------------------ */
+
+static SpiceGlzDecoderOps glz_decoder_ops = {
+ .decode = decode,
+};
+
+void glz_decoder_window_clear(SpiceGlzDecoderWindow *w)
+{
+ int i;
+
+ g_return_if_fail(w->nimages == 0 || w->images != NULL);
+
+ for (i = 0; i < w->nimages; i++) {
+ if (w->images[i]) {
+ glz_image_destroy(w->images[i]);
+ }
+ }
+
+ w->nimages = 16;
+ g_free(w->images);
+ w->images = g_new0(struct glz_image*, w->nimages);
+ w->tail_gap = 0;
+}
+
+SpiceGlzDecoderWindow *glz_decoder_window_new(void)
+{
+ SpiceGlzDecoderWindow *w = g_new0(SpiceGlzDecoderWindow, 1);
+ glz_decoder_window_clear(w);
+ return w;
+}
+
+void glz_decoder_window_destroy(SpiceGlzDecoderWindow *w)
+{
+ if (w == NULL)
+ return;
+
+ glz_decoder_window_clear(w);
+ free(w->images);
+ free(w);
+}
+
+SpiceGlzDecoder *glz_decoder_new(SpiceGlzDecoderWindow *w)
+{
+ GlibGlzDecoder *d = g_new0(GlibGlzDecoder, 1);
+ d->base.ops = &glz_decoder_ops;
+ d->window = w;
+ return &d->base;
+}
+
+void glz_decoder_destroy(SpiceGlzDecoder *d)
+{
+ free(d);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "decode.h"
+
+#ifdef G_OS_WIN32
+/* We need some hacks to avoid warnings from the jpeg headers, ex: */
+/* #define HAVE_BOOLEAN */
+#define XMD_H
+/* #undef FAR */
+/* but they are not compatible: uchar vs int........!@@(#$$??!@! */
+/* fix this with UGLY HACK! */
+/* #define boolean spice_jpeg_boolean */
+/* #define INT32 spice_jpeg_int32 */
+#endif
+
+#include <stdio.h>
+#include <jpeglib.h>
+
+typedef struct GlibJpegDecoder
+{
+ SpiceJpegDecoder base;
+ struct jpeg_decompress_struct _cinfo;
+ struct jpeg_error_mgr _jerr;
+ struct jpeg_source_mgr _jsrc;
+
+ uint8_t* _data;
+ int _data_size;
+ int _width;
+ int _height;
+} GlibJpegDecoder;
+
+static void begin_decode(SpiceJpegDecoder *decoder,
+ uint8_t* data, int data_size,
+ int* out_width, int* out_height)
+{
+ GlibJpegDecoder *d = SPICE_CONTAINEROF(decoder, GlibJpegDecoder, base);
+
+ g_return_if_fail(data != NULL);
+ g_return_if_fail(data_size != 0);
+
+ if (d->_data)
+ jpeg_abort_decompress(&d->_cinfo);
+
+ d->_data = data;
+ d->_data_size = data_size;
+
+ d->_cinfo.src->next_input_byte = d->_data;
+ d->_cinfo.src->bytes_in_buffer = d->_data_size;
+
+ jpeg_read_header(&d->_cinfo, TRUE);
+
+ d->_cinfo.out_color_space = JCS_RGB;
+ d->_width = d->_cinfo.image_width;
+ d->_height = d->_cinfo.image_height;
+
+ *out_width = d->_width;
+ *out_height = d->_height;
+}
+
+/* TODO: move it elsewhere and reuse it in get_pixbuf(), optimize? */
+typedef void (*converter_rgb_t)(uint8_t* src, uint8_t* dest, int width);
+
+static void convert_rgb_to_bgr(uint8_t* src, uint8_t* dest, int width)
+{
+ int x;
+
+ for (x = 0; x < width; x++) {
+ *dest++ = src[2];
+ *dest++ = src[1];
+ *dest++ = src[0];
+ src += 3;
+ }
+}
+
+static void convert_rgb_to_bgrx(uint8_t* src, uint8_t* dest, int width)
+{
+ int x;
+
+ for (x = 0; x < width; x++) {
+ *dest++ = src[2];
+ *dest++ = src[1];
+ *dest++ = src[0];
+ *dest++ = 0;
+ src += 3;
+ }
+}
+
+static void decode(SpiceJpegDecoder *decoder,
+ uint8_t* dest, int stride, int format)
+{
+ GlibJpegDecoder *d = SPICE_CONTAINEROF(decoder, GlibJpegDecoder, base);
+ uint8_t* scan_line = g_alloca(d->_width * 3);
+ converter_rgb_t converter = NULL;
+ int row;
+
+ switch (format) {
+ case SPICE_BITMAP_FMT_24BIT:
+ converter = convert_rgb_to_bgr;
+ break;
+ case SPICE_BITMAP_FMT_32BIT:
+ converter = convert_rgb_to_bgrx;
+ break;
+ default:
+ g_warning("bad bitmap format, %d", format);
+ return;
+ }
+
+ g_return_if_fail(converter != NULL);
+
+ jpeg_start_decompress(&d->_cinfo);
+
+ for (row = 0; row < d->_height; row++) {
+ jpeg_read_scanlines(&d->_cinfo, &scan_line, 1);
+ converter(scan_line, dest, d->_width);
+ dest += stride;
+ }
+
+ jpeg_finish_decompress(&d->_cinfo);
+}
+
+static SpiceJpegDecoderOps jpeg_decoder_ops = {
+ .begin_decode = begin_decode,
+ .decode = decode,
+};
+
+static void jpeg_decoder_init_source(j_decompress_ptr cinfo)
+{
+}
+
+static boolean jpeg_decoder_fill_input_buffer(j_decompress_ptr cinfo)
+{
+ g_warning("no more data for jpeg");
+ return FALSE;
+}
+
+static void jpeg_decoder_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
+{
+ g_return_if_fail(num_bytes < (long)cinfo->src->bytes_in_buffer);
+
+ cinfo->src->next_input_byte += num_bytes;
+ cinfo->src->bytes_in_buffer -= num_bytes;
+}
+
+static void jpeg_decoder_term_source (j_decompress_ptr cinfo)
+{
+ return;
+}
+
+SpiceJpegDecoder *jpeg_decoder_new(void)
+{
+ GlibJpegDecoder *d = g_new0(GlibJpegDecoder, 1);
+
+ d->_cinfo.err = jpeg_std_error(&d->_jerr);
+ jpeg_create_decompress(&d->_cinfo);
+
+ d->_cinfo.src = &d->_jsrc;
+ d->_cinfo.src->init_source = jpeg_decoder_init_source;
+ d->_cinfo.src->fill_input_buffer = jpeg_decoder_fill_input_buffer;
+ d->_cinfo.src->skip_input_data = jpeg_decoder_skip_input_data;
+ d->_cinfo.src->resync_to_restart = jpeg_resync_to_restart;
+ d->_cinfo.src->term_source = jpeg_decoder_term_source;
+
+ d->base.ops = &jpeg_decoder_ops;
+
+ return &d->base;
+}
+
+void jpeg_decoder_destroy(SpiceJpegDecoder *decoder)
+{
+ GlibJpegDecoder *d = SPICE_CONTAINEROF(decoder, GlibJpegDecoder, base);
+
+ jpeg_destroy_decompress(&d->_cinfo);
+ free(d);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "decode.h"
+
+#ifndef __GNUC__
+#define ZLIB_WINAPI
+#endif
+
+#include <zlib.h>
+
+typedef struct GlibZlibDecoder
+{
+ SpiceZlibDecoder base;
+ z_stream _z_strm;
+} GlibZlibDecoder;
+
+static void decode(SpiceZlibDecoder *decoder,
+ uint8_t *data, int data_size,
+ uint8_t *dest, int dest_size)
+{
+ GlibZlibDecoder *d = SPICE_CONTAINEROF(decoder, GlibZlibDecoder, base);
+ int z_ret;
+
+ inflateReset(&d->_z_strm);
+ d->_z_strm.next_in = data;
+ d->_z_strm.avail_in = data_size;
+ d->_z_strm.next_out = dest;
+ d->_z_strm.avail_out = dest_size;
+
+ z_ret = inflate(&d->_z_strm, Z_FINISH);
+
+ if (z_ret != Z_STREAM_END) {
+ g_warning("zlib inflate failed, error %d", z_ret);
+ }
+}
+
+static SpiceZlibDecoderOps zlib_decoder_ops = {
+ .decode = decode,
+};
+
+SpiceZlibDecoder *zlib_decoder_new(void)
+{
+ GlibZlibDecoder *d = g_new0(GlibZlibDecoder, 1);
+ int z_ret;
+
+ d->_z_strm.zalloc = Z_NULL;
+ d->_z_strm.zfree = Z_NULL;
+ d->_z_strm.opaque = Z_NULL;
+ d->_z_strm.next_in = Z_NULL;
+ d->_z_strm.avail_in = 0;
+ z_ret = inflateInit(&d->_z_strm);
+ if (z_ret != Z_OK) {
+ g_warning("zlib decoder init failed, error %d", z_ret);
+ goto fail;
+ }
+
+ d->base.ops = &zlib_decoder_ops;
+
+ return &d->base;
+
+fail:
+ free(d);
+ return NULL;
+}
+
+void zlib_decoder_destroy(SpiceZlibDecoder *decoder)
+{
+ GlibZlibDecoder *d = SPICE_CONTAINEROF(decoder, GlibZlibDecoder, base);
+
+ inflateEnd(&d->_z_strm);
+ free(d);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef SPICEGTK_DECODE_H_
+# define SPICEGTK_DECODE_H_
+
+#include <glib.h>
+
+#include "client_sw_canvas.h"
+
+G_BEGIN_DECLS
+
+typedef struct SpiceGlzDecoderWindow SpiceGlzDecoderWindow;
+
+SpiceGlzDecoderWindow *glz_decoder_window_new(void);
+void glz_decoder_window_clear(SpiceGlzDecoderWindow *w);
+void glz_decoder_window_destroy(SpiceGlzDecoderWindow *w);
+
+SpiceGlzDecoder *glz_decoder_new(SpiceGlzDecoderWindow *w);
+void glz_decoder_destroy(SpiceGlzDecoder *d);
+
+SpiceZlibDecoder *zlib_decoder_new(void);
+void zlib_decoder_destroy(SpiceZlibDecoder *d);
+
+SpiceJpegDecoder *jpeg_decoder_new(void);
+void jpeg_decoder_destroy(SpiceJpegDecoder *d);
+
+G_END_DECLS
+
+#endif // SPICEGTK_DECODE_H_
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include <glib-object.h>
+
+#include "spice-session-priv.h"
+#include "desktop-integration.h"
+
+#include <glib/gi18n-lib.h>
+
+#define GNOME_SESSION_INHIBIT_AUTOMOUNT 16
+
+/* ------------------------------------------------------------------ */
+/* gobject glue */
+
+#define SPICE_DESKTOP_INTEGRATION_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SPICE_TYPE_DESKTOP_INTEGRATION, SpiceDesktopIntegrationPrivate))
+
+struct _SpiceDesktopIntegrationPrivate {
+#if defined(USE_GDBUS)
+ GDBusProxy *gnome_session_proxy;
+#else
+ GObject *gnome_session_proxy; /* dummy */
+#endif
+ guint gnome_automount_inhibit_cookie;
+};
+
+G_DEFINE_TYPE(SpiceDesktopIntegration, spice_desktop_integration, G_TYPE_OBJECT);
+
+/* ------------------------------------------------------------------ */
+/* Gnome specific code */
+
+static void handle_dbus_call_error(const char *call, GError **_error)
+{
+ GError *error = *_error;
+ const char *message = error->message;
+
+ g_warning("Error calling '%s': %s", call, message);
+ g_clear_error(_error);
+}
+
+static gboolean gnome_integration_init(SpiceDesktopIntegration *self)
+{
+ G_GNUC_UNUSED SpiceDesktopIntegrationPrivate *priv = self->priv;
+ GError *error = NULL;
+ gboolean success = TRUE;
+
+#if defined(USE_GDBUS)
+ gchar *name_owner = NULL;
+ priv->gnome_session_proxy =
+ g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "org.gnome.SessionManager",
+ "/org/gnome/SessionManager",
+ "org.gnome.SessionManager",
+ NULL,
+ &error);
+ if (!error &&
+ (name_owner = g_dbus_proxy_get_name_owner(priv->gnome_session_proxy)) == NULL) {
+ g_clear_object(&priv->gnome_session_proxy);
+ success = FALSE;
+ }
+ g_free(name_owner);
+#else
+ success = FALSE;
+#endif
+
+ if (error) {
+ g_warning("Could not create org.gnome.SessionManager dbus proxy: %s",
+ error->message);
+ g_clear_error(&error);
+ return FALSE;
+ }
+
+ return success;
+}
+
+static void gnome_integration_inhibit_automount(SpiceDesktopIntegration *self)
+{
+ SpiceDesktopIntegrationPrivate *priv = self->priv;
+ GError *error = NULL;
+ G_GNUC_UNUSED const gchar *reason =
+ _("Automounting has been inhibited for USB auto-redirecting");
+
+ if (!priv->gnome_session_proxy)
+ return;
+
+ g_return_if_fail(priv->gnome_automount_inhibit_cookie == 0);
+
+#if defined(USE_GDBUS)
+ GVariant *v = g_dbus_proxy_call_sync(priv->gnome_session_proxy,
+ "Inhibit",
+ g_variant_new("(susu)",
+ g_get_prgname(),
+ 0,
+ reason,
+ GNOME_SESSION_INHIBIT_AUTOMOUNT),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (v)
+ g_variant_get(v, "(u)", &priv->gnome_automount_inhibit_cookie);
+
+ g_clear_pointer(&v, g_variant_unref);
+#endif
+ if (error)
+ handle_dbus_call_error("org.gnome.SessionManager.Inhibit", &error);
+}
+
+static void gnome_integration_uninhibit_automount(SpiceDesktopIntegration *self)
+{
+ SpiceDesktopIntegrationPrivate *priv = self->priv;
+ GError *error = NULL;
+
+ if (!priv->gnome_session_proxy)
+ return;
+
+ /* Cookie is 0 when we failed to inhibit (and when called from dispose) */
+ if (priv->gnome_automount_inhibit_cookie == 0)
+ return;
+
+#if defined(USE_GDBUS)
+ GVariant *v = g_dbus_proxy_call_sync(priv->gnome_session_proxy,
+ "Uninhibit",
+ g_variant_new("(u)",
+ priv->gnome_automount_inhibit_cookie),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ g_clear_pointer(&v, g_variant_unref);
+#endif
+ if (error)
+ handle_dbus_call_error("org.gnome.SessionManager.Uninhibit", &error);
+
+ priv->gnome_automount_inhibit_cookie = 0;
+}
+
+static void gnome_integration_dispose(SpiceDesktopIntegration *self)
+{
+ SpiceDesktopIntegrationPrivate *priv = self->priv;
+
+ g_clear_object(&priv->gnome_session_proxy);
+}
+
+/* ------------------------------------------------------------------ */
+/* gobject glue */
+
+static void spice_desktop_integration_init(SpiceDesktopIntegration *self)
+{
+ SpiceDesktopIntegrationPrivate *priv;
+
+ priv = SPICE_DESKTOP_INTEGRATION_GET_PRIVATE(self);
+ self->priv = priv;
+
+ if (!gnome_integration_init(self))
+ g_warning("Warning no automount-inhibiting implementation available");
+}
+
+static void spice_desktop_integration_dispose(GObject *gobject)
+{
+ SpiceDesktopIntegration *self = SPICE_DESKTOP_INTEGRATION(gobject);
+
+ gnome_integration_dispose(self);
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_desktop_integration_parent_class)->dispose)
+ G_OBJECT_CLASS(spice_desktop_integration_parent_class)->dispose(gobject);
+}
+
+static void spice_desktop_integration_class_init(SpiceDesktopIntegrationClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->dispose = spice_desktop_integration_dispose;
+
+ g_type_class_add_private(klass, sizeof(SpiceDesktopIntegrationPrivate));
+}
+
+SpiceDesktopIntegration *spice_desktop_integration_get(SpiceSession *session)
+{
+ SpiceDesktopIntegration *self;
+ static GMutex mutex;
+
+ g_return_val_if_fail(session != NULL, NULL);
+
+ g_mutex_lock(&mutex);
+ self = g_object_get_data(G_OBJECT(session), "spice-desktop");
+ if (self == NULL) {
+ self = g_object_new(SPICE_TYPE_DESKTOP_INTEGRATION, NULL);
+ g_object_set_data_full(G_OBJECT(session), "spice-desktop", self, g_object_unref);
+ }
+ g_mutex_unlock(&mutex);
+
+ return self;
+}
+
+void spice_desktop_integration_inhibit_automount(SpiceDesktopIntegration *self)
+{
+ gnome_integration_inhibit_automount(self);
+}
+
+void spice_desktop_integration_uninhibit_automount(SpiceDesktopIntegration *self)
+{
+ gnome_integration_uninhibit_automount(self);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_DESKTOP_INTEGRATION_H__
+#define __SPICE_DESKTOP_INTEGRATION_H__
+
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_DESKTOP_INTEGRATION (spice_desktop_integration_get_type ())
+#define SPICE_DESKTOP_INTEGRATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_DESKTOP_INTEGRATION, SpiceDesktopIntegration))
+#define SPICE_DESKTOP_INTEGRATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_DESKTOP_INTEGRATION, SpiceDesktopIntegrationClass))
+#define SPICE_IS_DESKTOP_INTEGRATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_DESKTOP_INTEGRATION))
+#define SPICE_IS_DESKTOP_INTEGRATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_DESKTOP_INTEGRATION))
+#define SPICE_DESKTOP_INTEGRATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_DESKTOP_INTEGRATION, SpiceDesktopIntegrationClass))
+
+typedef struct _SpiceDesktopIntegration SpiceDesktopIntegration;
+typedef struct _SpiceDesktopIntegrationClass SpiceDesktopIntegrationClass;
+typedef struct _SpiceDesktopIntegrationPrivate SpiceDesktopIntegrationPrivate;
+
+/*
+ * SpiceDesktopIntegration offers helper-functions to do desktop environment
+ * and/or platform specific tasks like disabling automount, disabling the
+ * screen-saver, etc. SpiceDesktopIntegration is for internal spice-gtk usage
+ * only!
+ */
+struct _SpiceDesktopIntegration
+{
+ GObject parent;
+
+ SpiceDesktopIntegrationPrivate *priv;
+};
+
+struct _SpiceDesktopIntegrationClass
+{
+ GObjectClass parent_class;
+};
+
+GType spice_desktop_integration_get_type(void);
+SpiceDesktopIntegration *spice_desktop_integration_get(SpiceSession *session);
+void spice_desktop_integration_inhibit_automount(SpiceDesktopIntegration *self);
+void spice_desktop_integration_uninhibit_automount(SpiceDesktopIntegration *self);
+
+G_END_DECLS
+
+#endif /* __SPICE_DESKTOP_INTEGRATION_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+ Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+ Copyright (C) 2009-2010 Daniel P. Berrange <dan@berrange.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.0 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+#include "config.h"
+
+#include "gio-coroutine.h"
+
+typedef struct _GConditionWaitSource
+{
+ GCoroutine *self;
+ GSource src;
+ GConditionWaitFunc func;
+ gpointer data;
+} GConditionWaitSource;
+
+GCoroutine* g_coroutine_self(void)
+{
+ return (GCoroutine*)coroutine_self();
+}
+
+/* Main loop helper functions */
+static gboolean g_io_wait_helper(GSocket *sock G_GNUC_UNUSED,
+ GIOCondition cond,
+ gpointer data)
+{
+ struct coroutine *to = data;
+ coroutine_yieldto(to, &cond);
+ return FALSE;
+}
+
+GIOCondition g_coroutine_socket_wait(GCoroutine *self,
+ GSocket *sock,
+ GIOCondition cond)
+{
+ GIOCondition *ret, val = 0;
+ GSource *src;
+
+ g_return_val_if_fail(self != NULL, 0);
+ g_return_val_if_fail(self->wait_id == 0, 0);
+ g_return_val_if_fail(sock != NULL, 0);
+
+ src = g_socket_create_source(sock, cond | G_IO_HUP | G_IO_ERR | G_IO_NVAL, NULL);
+ g_source_set_callback(src, (GSourceFunc)g_io_wait_helper, self, NULL);
+ self->wait_id = g_source_attach(src, NULL);
+ ret = coroutine_yield(NULL);
+ g_source_unref(src);
+
+ if (ret != NULL)
+ val = *ret;
+ else
+ g_source_remove(self->wait_id);
+
+ self->wait_id = 0;
+ return val;
+}
+
+void g_coroutine_condition_cancel(GCoroutine *coroutine)
+{
+ g_return_if_fail(coroutine != NULL);
+
+ if (coroutine->condition_id == 0)
+ return;
+
+ g_source_remove(coroutine->condition_id);
+ coroutine->condition_id = 0;
+}
+
+void g_coroutine_wakeup(GCoroutine *coroutine)
+{
+ g_return_if_fail(coroutine != NULL);
+ g_return_if_fail(coroutine != g_coroutine_self());
+
+ if (coroutine->wait_id)
+ coroutine_yieldto(&coroutine->coroutine, NULL);
+}
+
+/*
+ * Call immediately before the main loop does an iteration. Returns
+ * true if the condition we're checking is ready for dispatch
+ */
+static gboolean g_condition_wait_prepare(GSource *src,
+ int *timeout) {
+ GConditionWaitSource *vsrc = (GConditionWaitSource *)src;
+ *timeout = -1;
+ return vsrc->func(vsrc->data);
+}
+
+/*
+ * Call immediately after the main loop does an iteration. Returns
+ * true if the condition we're checking is ready for dispatch
+ */
+static gboolean g_condition_wait_check(GSource *src)
+{
+ GConditionWaitSource *vsrc = (GConditionWaitSource *)src;
+ return vsrc->func(vsrc->data);
+}
+
+static gboolean g_condition_wait_dispatch(GSource *src G_GNUC_UNUSED,
+ GSourceFunc cb,
+ gpointer data) {
+ return cb(data);
+}
+
+GSourceFuncs waitFuncs = {
+ .prepare = g_condition_wait_prepare,
+ .check = g_condition_wait_check,
+ .dispatch = g_condition_wait_dispatch,
+};
+
+static gboolean g_condition_wait_helper(gpointer data)
+{
+ GCoroutine *self = (GCoroutine *)data;
+ coroutine_yieldto(&self->coroutine, NULL);
+ return FALSE;
+}
+
+/*
+ * g_coroutine_condition_wait:
+ * @coroutine: the coroutine to wait on
+ * @func: the condition callback
+ * @data: the user data passed to @func callback
+ *
+ * This function will wait on caller coroutine until @func returns %TRUE.
+ *
+ * @func is called when entering the main loop from the main context (coroutine).
+ *
+ * The condition can be cancelled by calling g_coroutine_wakeup()
+ *
+ * Returns: %TRUE if condition reached, %FALSE if not and cancelled
+ */
+gboolean g_coroutine_condition_wait(GCoroutine *self, GConditionWaitFunc func, gpointer data)
+{
+ GSource *src;
+ GConditionWaitSource *vsrc;
+
+ g_return_val_if_fail(self != NULL, FALSE);
+ g_return_val_if_fail(self->condition_id == 0, FALSE);
+ g_return_val_if_fail(func != NULL, FALSE);
+
+ /* Short-circuit check in case we've got it ahead of time */
+ if (func(data))
+ return TRUE;
+
+ /*
+ * Don't have it, so yield to the main loop, checking the condition
+ * on each iteration of the main loop
+ */
+ src = g_source_new(&waitFuncs, sizeof(GConditionWaitSource));
+ vsrc = (GConditionWaitSource *)src;
+
+ vsrc->func = func;
+ vsrc->data = data;
+ vsrc->self = self;
+
+ self->condition_id = g_source_attach(src, NULL);
+ g_source_set_callback(src, g_condition_wait_helper, self, NULL);
+ coroutine_yield(NULL);
+ g_source_unref(src);
+
+ /* it got woked up / cancelled? */
+ if (self->condition_id == 0)
+ return func(data);
+
+ self->condition_id = 0;
+ return TRUE;
+}
+
+struct signal_data
+{
+ gpointer instance;
+ struct coroutine *caller;
+ guint signal_id;
+ GQuark detail;
+ const gchar *propname;
+ gboolean notified;
+ va_list var_args;
+};
+
+static gboolean emit_main_context(gpointer opaque)
+{
+ struct signal_data *signal = opaque;
+
+ g_signal_emit_valist(signal->instance, signal->signal_id,
+ signal->detail, signal->var_args);
+ signal->notified = TRUE;
+
+ coroutine_yieldto(signal->caller, NULL);
+
+ return FALSE;
+}
+
+void
+g_coroutine_signal_emit(gpointer instance, guint signal_id,
+ GQuark detail, ...)
+{
+ struct signal_data data = {
+ .instance = instance,
+ .signal_id = signal_id,
+ .detail = detail,
+ .caller = coroutine_self(),
+ };
+
+ va_start (data.var_args, detail);
+
+ if (coroutine_self_is_main()) {
+ g_signal_emit_valist(instance, signal_id, detail, data.var_args);
+ } else {
+ g_object_ref(instance);
+ g_idle_add(emit_main_context, &data);
+ coroutine_yield(NULL);
+ g_warn_if_fail(data.notified);
+ g_object_unref(instance);
+ }
+
+ va_end (data.var_args);
+}
+
+
+static gboolean notify_main_context(gpointer opaque)
+{
+ struct signal_data *signal = opaque;
+
+ g_object_notify(signal->instance, signal->propname);
+ signal->notified = TRUE;
+
+ coroutine_yieldto(signal->caller, NULL);
+
+ return FALSE;
+}
+
+/* coroutine -> main context */
+void g_coroutine_object_notify(GObject *object,
+ const gchar *property_name)
+{
+ struct signal_data data;
+
+ if (coroutine_self_is_main()) {
+ g_object_notify(object, property_name);
+ } else {
+
+ data.instance = g_object_ref(object);
+ data.caller = coroutine_self();
+ data.propname = (gpointer)property_name;
+ data.notified = FALSE;
+
+ g_idle_add(notify_main_context, &data);
+
+ /* This switches to the system coroutine context, lets
+ * the idle function run to dispatch the signal, and
+ * finally returns once complete. ie this is synchronous
+ * from the POV of the coroutine despite there being
+ * an idle function involved
+ */
+ coroutine_yield(NULL);
+ g_warn_if_fail(data.notified);
+ g_object_unref(object);
+ }
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+ Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+ Copyright (C) 2009-2010 Daniel P. Berrange <dan@berrange.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.0 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+#ifndef __GIO_COROUTINE_H__
+#define __GIO_COROUTINE_H__
+
+#include <gio/gio.h>
+#include "coroutine.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GCoroutine GCoroutine;
+
+struct _GCoroutine
+{
+ struct coroutine coroutine;
+ guint wait_id;
+ guint condition_id;
+};
+
+/*
+ * A special GSource impl which allows us to wait on a certain
+ * condition to be satisfied. This is effectively a boolean test
+ * run on each iteration of the main loop. So whenever a file has
+ * new I/O, or a timer occurs, etc we'll do the check. This is
+ * pretty efficient compared to a normal GLib Idle func which has
+ * to busy wait on a timeout, since our condition is only checked
+ * when some other source's state changes
+ */
+typedef gboolean (*GConditionWaitFunc)(gpointer);
+
+typedef void (*GSignalEmitMainFunc)(GObject *object, int signum, gpointer params);
+
+GCoroutine* g_coroutine_self (void);
+void g_coroutine_wakeup (GCoroutine *coroutine);
+GIOCondition g_coroutine_socket_wait (GCoroutine *coroutine,
+ GSocket *sock, GIOCondition cond);
+gboolean g_coroutine_condition_wait (GCoroutine *coroutine,
+ GConditionWaitFunc func, gpointer data);
+void g_coroutine_condition_cancel(GCoroutine *coroutine);
+
+void g_coroutine_signal_emit (gpointer instance, guint signal_id,
+ GQuark detail, ...);
+
+void g_coroutine_object_notify(GObject *object, const gchar *property_name);
+
+G_END_DECLS
+
+#endif /* __GIO_COROUTINE_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2015 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include <errno.h>
+
+#include "giopipe.h"
+
+#define TYPE_PIPE_INPUT_STREAM (pipe_input_stream_get_type ())
+#define PIPE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_PIPE_INPUT_STREAM, PipeInputStream))
+#define PIPE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), TYPE_PIPE_INPUT_STREAM, PipeInputStreamClass))
+#define IS_PIPE_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_PIPE_INPUT_STREAM))
+#define IS_PIPE_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_PIPE_INPUT_STREAM))
+#define PIPE_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_PIPE_INPUT_STREAM, PipeInputStreamClass))
+
+typedef struct _PipeInputStreamClass PipeInputStreamClass;
+typedef struct _PipeInputStream PipeInputStream;
+typedef struct _PipeOutputStream PipeOutputStream;
+
+struct _PipeInputStream
+{
+ GInputStream parent_instance;
+
+ PipeOutputStream *peer;
+ gssize read;
+
+ /* GIOstream:closed is protected against pending operations, so we
+ * use an additional close flag to cancel those when the peer is
+ * closing.
+ */
+ gboolean peer_closed;
+ GList *sources;
+};
+
+struct _PipeInputStreamClass
+{
+ GInputStreamClass parent_class;
+};
+
+#define TYPE_PIPE_OUTPUT_STREAM (pipe_output_stream_get_type ())
+#define PIPE_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_PIPE_OUTPUT_STREAM, PipeOutputStream))
+#define PIPE_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), TYPE_PIPE_OUTPUT_STREAM, PipeOutputStreamClass))
+#define IS_PIPE_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_PIPE_OUTPUT_STREAM))
+#define IS_PIPE_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_PIPE_OUTPUT_STREAM))
+#define PIPE_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_PIPE_OUTPUT_STREAM, PipeOutputStreamClass))
+
+typedef struct _PipeOutputStreamClass PipeOutputStreamClass;
+
+struct _PipeOutputStream
+{
+ GOutputStream parent_instance;
+
+ PipeInputStream *peer;
+ const gchar *buffer;
+ gsize count;
+ gboolean peer_closed;
+ GList *sources;
+};
+
+struct _PipeOutputStreamClass
+{
+ GOutputStreamClass parent_class;
+};
+
+static void pipe_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface);
+static void pipe_input_stream_check_source (PipeInputStream *self);
+static void pipe_output_stream_check_source (PipeOutputStream *self);
+
+static GType pipe_input_stream_get_type(void);
+
+G_DEFINE_TYPE_WITH_CODE (PipeInputStream, pipe_input_stream, G_TYPE_INPUT_STREAM,
+ G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM,
+ pipe_input_stream_pollable_iface_init))
+
+static gssize
+pipe_input_stream_read (GInputStream *stream,
+ void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ PipeInputStream *self = PIPE_INPUT_STREAM (stream);
+
+ g_return_val_if_fail(count > 0, -1);
+
+ if (g_input_stream_is_closed (stream) || self->peer_closed) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
+ "Stream is already closed");
+ return -1;
+ }
+
+ if (!self->peer->buffer) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
+ g_strerror(EAGAIN));
+ return -1;
+ }
+
+ count = MIN(self->peer->count, count);
+ memcpy(buffer, self->peer->buffer, count);
+ self->read = count;
+ self->peer->buffer = NULL;
+
+ //g_debug("read %p :%"G_GSIZE_FORMAT, self->peer, count);
+ /* schedule peer source */
+ pipe_output_stream_check_source(self->peer);
+
+ return count;
+}
+
+static GList *
+set_all_sources_ready (GList *sources)
+{
+ GList *it = sources;
+ while (it != NULL) {
+ GSource *s = it->data;
+ GList *next = it->next;
+
+ if (s == NULL || g_source_is_destroyed(s)) {
+ /* remove */
+ sources = g_list_delete_link(sources, it);
+ g_source_unref(s);
+ } else {
+ /* dispatch */
+ g_source_set_ready_time(s, 0);
+ }
+ it = next;
+ }
+ return sources;
+}
+
+static void
+pipe_input_stream_check_source (PipeInputStream *self)
+{
+ if (g_pollable_input_stream_is_readable(G_POLLABLE_INPUT_STREAM(self)))
+ self->sources = set_all_sources_ready(self->sources);
+}
+
+static gboolean
+pipe_input_stream_close (GInputStream *stream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ PipeInputStream *self;
+
+ self = PIPE_INPUT_STREAM(stream);
+
+ if (self->peer) {
+ /* ignore any pending errors */
+ self->peer->peer_closed = TRUE;
+ g_output_stream_close(G_OUTPUT_STREAM(self->peer), cancellable, NULL);
+ pipe_output_stream_check_source(self->peer);
+ }
+
+ return TRUE;
+}
+
+static void
+pipe_input_stream_close_async (GInputStream *stream,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer data)
+{
+ GTask *task;
+
+ task = g_task_new (stream, cancellable, callback, data);
+
+ /* will always return TRUE */
+ pipe_input_stream_close (stream, cancellable, NULL);
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static gboolean
+pipe_input_stream_close_finish (GInputStream *stream,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static void
+pipe_input_stream_init (PipeInputStream *self)
+{
+ self->read = -1;
+}
+
+static void
+pipe_input_stream_dispose(GObject *object)
+{
+ PipeInputStream *self;
+
+ self = PIPE_INPUT_STREAM(object);
+
+ if (self->peer) {
+ g_object_remove_weak_pointer(G_OBJECT(self->peer), (gpointer*)&self->peer);
+ self->peer = NULL;
+ }
+
+ g_list_free_full (self->sources, (GDestroyNotify) g_source_unref);
+ self->sources = NULL;
+
+ G_OBJECT_CLASS(pipe_input_stream_parent_class)->dispose (object);
+}
+
+static void
+pipe_input_stream_class_init (PipeInputStreamClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GInputStreamClass *istream_class = G_INPUT_STREAM_CLASS (klass);
+
+ istream_class->read_fn = pipe_input_stream_read;
+ istream_class->close_fn = pipe_input_stream_close;
+ istream_class->close_async = pipe_input_stream_close_async;
+ istream_class->close_finish = pipe_input_stream_close_finish;
+
+ gobject_class->dispose = pipe_input_stream_dispose;
+}
+
+static gboolean
+pipe_input_stream_is_readable (GPollableInputStream *stream)
+{
+ PipeInputStream *self = PIPE_INPUT_STREAM (stream);
+ gboolean readable;
+
+ readable = (self->peer && self->peer->buffer && self->read == -1) || self->peer_closed;
+ //g_debug("readable %p %d", self->peer, readable);
+
+ return readable;
+}
+
+static GSource *
+pipe_input_stream_create_source (GPollableInputStream *stream,
+ GCancellable *cancellable)
+{
+ PipeInputStream *self = PIPE_INPUT_STREAM(stream);
+ GSource *pollable_source;
+
+ pollable_source = g_pollable_source_new_full (self, NULL, cancellable);
+ self->sources = g_list_prepend (self->sources, g_source_ref (pollable_source));
+
+ return pollable_source;
+}
+
+static void
+pipe_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface)
+{
+ iface->is_readable = pipe_input_stream_is_readable;
+ iface->create_source = pipe_input_stream_create_source;
+}
+
+static void pipe_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface);
+
+static GType pipe_output_stream_get_type(void);
+
+G_DEFINE_TYPE_WITH_CODE (PipeOutputStream, pipe_output_stream, G_TYPE_OUTPUT_STREAM,
+ G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_OUTPUT_STREAM,
+ pipe_output_stream_pollable_iface_init))
+
+static gssize
+pipe_output_stream_write (GOutputStream *stream,
+ const void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ PipeOutputStream *self = PIPE_OUTPUT_STREAM(stream);
+ PipeInputStream *peer = self->peer;
+
+ //g_debug("write %p :%"G_GSIZE_FORMAT, stream, count);
+ if (g_output_stream_is_closed (stream) || self->peer_closed) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
+ "Stream is already closed");
+ return -1;
+ }
+
+ /* this abuses pollable stream, writing sync would likely lead to
+ crashes, since the buffer pointer would become invalid, a
+ generic solution would need a copy..
+ */
+ g_return_val_if_fail(self->buffer == buffer || self->buffer == NULL, -1);
+ self->buffer = buffer;
+ self->count = count;
+
+ pipe_input_stream_check_source(self->peer);
+
+ if (peer->read < 0) {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
+ g_strerror (EAGAIN));
+ return -1;
+ }
+
+ g_assert(peer->read <= self->count);
+ count = peer->read;
+
+ self->buffer = NULL;
+ self->count = 0;
+ peer->read = -1;
+
+ return count;
+}
+
+static void
+pipe_output_stream_init (PipeOutputStream *stream)
+{
+}
+
+static void
+pipe_output_stream_dispose(GObject *object)
+{
+ PipeOutputStream *self;
+
+ self = PIPE_OUTPUT_STREAM(object);
+
+ if (self->peer) {
+ g_object_remove_weak_pointer(G_OBJECT(self->peer), (gpointer*)&self->peer);
+ self->peer = NULL;
+ }
+
+ g_list_free_full (self->sources, (GDestroyNotify) g_source_unref);
+ self->sources = NULL;
+
+ G_OBJECT_CLASS(pipe_output_stream_parent_class)->dispose (object);
+}
+
+static void
+pipe_output_stream_check_source (PipeOutputStream *self)
+{
+ if (g_pollable_output_stream_is_writable(G_POLLABLE_OUTPUT_STREAM(self)))
+ self->sources = set_all_sources_ready(self->sources);
+}
+
+static gboolean
+pipe_output_stream_close (GOutputStream *stream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ PipeOutputStream *self;
+
+ self = PIPE_OUTPUT_STREAM(stream);
+
+ if (self->peer) {
+ /* ignore any pending errors */
+ self->peer->peer_closed = TRUE;
+ g_input_stream_close(G_INPUT_STREAM(self->peer), cancellable, NULL);
+ pipe_input_stream_check_source(self->peer);
+ }
+
+ return TRUE;
+}
+
+static void
+pipe_output_stream_close_async (GOutputStream *stream,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer data)
+{
+ GTask *task;
+
+ task = g_task_new (stream, cancellable, callback, data);
+
+ /* will always return TRUE */
+ pipe_output_stream_close (stream, cancellable, NULL);
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static gboolean
+pipe_output_stream_close_finish (GOutputStream *stream,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+
+static void
+pipe_output_stream_class_init (PipeOutputStreamClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GOutputStreamClass *ostream_class = G_OUTPUT_STREAM_CLASS (klass);
+
+ ostream_class->write_fn = pipe_output_stream_write;
+ ostream_class->close_fn = pipe_output_stream_close;
+ ostream_class->close_async = pipe_output_stream_close_async;
+ ostream_class->close_finish = pipe_output_stream_close_finish;
+
+ gobject_class->dispose = pipe_output_stream_dispose;
+}
+
+static gboolean
+pipe_output_stream_is_writable (GPollableOutputStream *stream)
+{
+ PipeOutputStream *self = PIPE_OUTPUT_STREAM(stream);
+ gboolean writable;
+
+ writable = self->buffer == NULL || self->peer->read >= 0;
+ //g_debug("writable %p %d", self, writable);
+
+ return writable;
+}
+
+static GSource *
+pipe_output_stream_create_source (GPollableOutputStream *stream,
+ GCancellable *cancellable)
+{
+ PipeOutputStream *self = PIPE_OUTPUT_STREAM(stream);
+ GSource *pollable_source;
+
+ pollable_source = g_pollable_source_new_full (self, NULL, cancellable);
+ self->sources = g_list_prepend (self->sources, g_source_ref (pollable_source));
+
+ return pollable_source;
+}
+
+static void
+pipe_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface)
+{
+ iface->is_writable = pipe_output_stream_is_writable;
+ iface->create_source = pipe_output_stream_create_source;
+}
+
+static void
+make_gio_pipe(GInputStream **input, GOutputStream **output)
+{
+ PipeInputStream *in;
+ PipeOutputStream *out;
+
+ g_return_if_fail(input != NULL && *input == NULL);
+ g_return_if_fail(output != NULL && *output == NULL);
+
+ in = g_object_new(TYPE_PIPE_INPUT_STREAM, NULL);
+ out = g_object_new(TYPE_PIPE_OUTPUT_STREAM, NULL);
+
+ out->peer = in;
+ g_object_add_weak_pointer(G_OBJECT(in), (gpointer*)&out->peer);
+
+ in->peer = out;
+ g_object_add_weak_pointer(G_OBJECT(out), (gpointer*)&in->peer);
+
+ *input = G_INPUT_STREAM(in);
+ *output = G_OUTPUT_STREAM(out);
+}
+
+G_GNUC_INTERNAL void
+spice_make_pipe(GIOStream **p1, GIOStream **p2)
+{
+ GInputStream *in1 = NULL, *in2 = NULL;
+ GOutputStream *out1 = NULL, *out2 = NULL;
+
+ g_return_if_fail(p1 != NULL);
+ g_return_if_fail(p2 != NULL);
+ g_return_if_fail(*p1 == NULL);
+ g_return_if_fail(*p2 == NULL);
+
+ make_gio_pipe(&in1, &out2);
+ make_gio_pipe(&in2, &out1);
+
+ *p1 = g_simple_io_stream_new(in1, out1);
+ *p2 = g_simple_io_stream_new(in2, out2);
+
+ g_object_unref(in1);
+ g_object_unref(in2);
+ g_object_unref(out1);
+ g_object_unref(out2);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2015 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_GIO_PIPE_H__
+#define __SPICE_GIO_PIPE_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+void spice_make_pipe(GIOStream **p1, GIOStream **p2);
+
+G_END_DECLS
+
+#endif /* __SPICE_GIO_PIPE_H__ */
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Text::CSV;
+
+my %names = (
+ linux => [],
+ osx => []
+);
+
+my %namecolumns = (
+ linux => 0,
+ osx => 2,
+ win32 => 10,
+ x11 => 14,
+ );
+
+# Base data sources:
+#
+# linux: Linux: linux/input.h (master set)
+# osx: OS-X: Carbon/HIToolbox/Events.h (manually mapped)
+# atset1: AT Set 1: linux/drivers/input/keyboard/atkbd.c (atkbd_set2_keycode + atkbd_unxlate_table)
+# atset2: AT Set 2: linux/drivers/input/keyboard/atkbd.c (atkbd_set2_keycode)
+# atset3: AT Set 3: linux/drivers/input/keyboard/atkbd.c (atkbd_set3_keycode)
+# xt: XT: linux/drivers/input/keyboard/xt.c (xtkbd_keycode)
+# xtkbd: Linux RAW: linux/drivers/char/keyboard.c (x86_keycodes)
+# usb: USB HID: linux/drivers/hid/usbhid/usbkbd.c (usb_kbd_keycode)
+# win32: Win32: mingw32/winuser.h (manually mapped)
+# xwinxt: XWin XT: xorg-server/hw/xwin/{winkeybd.c,winkeynames.h} (xt + manually transcribed)
+# xkbdxt: XKBD XT: xf86-input-keyboard/src/at_scancode.c
+#(xt + manually transcribed)
+# x11: X11 keysyms: http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
+#
+# Derived data sources
+#
+# xorgevdev: Xorg + evdev: linux + an offset
+# xorgkbd: Xorg + kbd: xkbdxt + an offset
+# xorgxquartz: Xorg + OS-X: osx + an offset
+# xorgxwin: Xorg + Cygwin: xwinxt + an offset
+# rfb: XT over RFB: xtkbd + special re-encoding of high bit
+
+my @basemaps = qw(linux osx atset1 atset2 atset3 xt xtkbd usb win32 xwinxt xkbdxt x11);
+my @derivedmaps = qw(xorgevdev xorgkbd xorgxquartz xorgxwin rfb);
+my @maps = (@basemaps, @derivedmaps);
+
+my %maps;
+
+foreach my $map (@maps) {
+ $maps{$map} = [ [], [] ];
+}
+my %mapcolumns = (
+ osx => 3,
+ atset1 => 4,
+ atset2 => 5,
+ atset3 => 6,
+ xt => 7,
+ xtkbd => 8,
+ usb => 9,
+ win32 => 11,
+ xwinxt => 12,
+ xkbdxt => 13,
+ x11 => 15
+ );
+
+sub help {
+ my $msg = shift;
+ print $msg;
+ print "\n";
+ print "Valid keymaps are:\n";
+ print "\n";
+ foreach my $name (sort { $a cmp $b } keys %maps) {
+ print " $name\n";
+ }
+ print "\n";
+ exit (1);
+}
+
+if ($#ARGV != 2) {
+ help("syntax: $0 KEYMAPS SRCMAP DSTMAP\n");
+}
+
+my $keymaps = shift @ARGV;
+my $src = shift @ARGV;
+my $dst = shift @ARGV;
+
+help("$src is not a known keymap\n") unless exists $maps{$src};
+help("$dst is not a known keymap\n") unless exists $maps{$dst};
+
+
+open CSV, $keymaps
+ or die "cannot read $keymaps: $!";
+
+my $csv = Text::CSV->new();
+# Discard column headings
+$csv->getline(\*CSV);
+
+my $row;
+while ($row = $csv->getline(\*CSV)) {
+ my $linux = $row->[1];
+
+ $linux = hex($linux) if $linux =~ /0x/;
+
+ my $to = $maps{linux}->[0];
+ my $from = $maps{linux}->[1];
+ $to->[$linux] = $linux;
+ $from->[$linux] = $linux;
+
+ foreach my $name (keys %namecolumns) {
+ my $col = $namecolumns{$name};
+ my $val = $row->[$col];
+
+ $val = "" unless defined $val;
+
+ $names{$name}->[$linux] = $val;
+ }
+
+ foreach my $name (keys %mapcolumns) {
+ my $col = $mapcolumns{$name};
+ my $val = $row->[$col];
+
+ next unless defined $val && $val ne "";
+ $val = hex($val) if $val =~ /0x/;
+
+ $to = $maps{$name}->[0];
+ $from = $maps{$name}->[1];
+ $to->[$linux] = $val;
+ $from->[$val] = $linux;
+ }
+
+ # XXX there are some special cases in kbd to handle
+ # Xorg KBD driver is the Xorg KBD XT codes offset by +8
+ # The XKBD XT codes are the same as normal XT codes
+ # for values <= 83, and completely made up for extended
+ # scancodes :-(
+ ($to, $from) = @{$maps{xorgkbd}};
+ if (defined $maps{xkbdxt}->[0]->[$linux]) {
+ $to->[$linux] = $maps{xkbdxt}->[0]->[$linux] + 8;
+ $from->[$to->[$linux]] = $linux;
+ }
+
+ # Xorg evdev is simply Linux keycodes offset by +8
+ ($to, $from) = @{$maps{xorgevdev}};
+ $to->[$linux] = $linux + 8;
+ $from->[$to->[$linux]] = $linux;
+
+ # Xorg XQuartz is simply OS-X keycodes offset by +8
+ ($to, $from) = @{$maps{xorgxquartz}};
+ if (defined $maps{osx}->[0]->[$linux]) {
+ $to->[$linux] = $maps{osx}->[0]->[$linux] + 8;
+ $from->[$to->[$linux]] = $linux;
+ }
+
+ # RFB keycodes are XT kbd keycodes with a slightly
+ # different encoding of 0xe0 scan codes. RFB uses
+ # the high bit of the first byte, instead of the low
+ # bit of the second byte.
+ ($to, $from) = @{$maps{rfb}};
+ my $xtkbd = $maps{xtkbd}->[0]->[$linux];
+ if (defined $xtkbd) {
+ $to->[$linux] = $xtkbd ? (($xtkbd & 0x100)>>1) | ($xtkbd & 0x7f) : 0;
+ $from->[$to->[$linux]] = $linux;
+ }
+
+ # Xorg Cygwin is the Xorg Cygwin XT codes offset by +8
+ # The Cygwin XT codes are the same as normal XT codes
+ # for values <= 83, and completely made up for extended
+ # scancodes :-(
+ ($to, $from) = @{$maps{xorgxwin}};
+ if (defined $maps{xwinxt}->[0]->[$linux]) {
+ $to->[$linux] = $maps{xwinxt}->[0]->[$linux] + 8;
+ $from->[$to->[$linux]] = $linux;
+ }
+
+# print $linux, "\n";
+}
+
+close CSV;
+
+my $srcmap = $maps{$src}->[1];
+my $dstmap = $maps{$dst}->[0];
+
+printf "static const guint16 keymap_%s2%s[] = {\n", $src, $dst;
+
+for (my $i = 0 ; $i <= $#{$srcmap} ; $i++) {
+ my $linux = $srcmap->[$i] || 0;
+ my $j = $dstmap->[$linux];
+ next unless $linux && $j;
+
+ my $srcname = $names{$src}->[$linux] if exists $names{$src};
+ my $dstname = $names{$dst}->[$linux] if exists $names{$dst};
+ my $vianame = $names{linux}->[$linux] unless $src eq "linux" || $dst eq "linux";
+
+ $srcname = "" unless $srcname;
+ $dstname = "" unless $dstname;
+ $vianame = "" unless $vianame;
+ $srcname = " ($srcname)" if $srcname;
+ $dstname = " ($dstname)" if $dstname;
+ $vianame = " ($vianame)" if $vianame;
+
+ my $comment;
+ if ($src ne "linux" && $dst ne "linux") {
+ $comment = sprintf "%d%s => %d%s via %d%s", $i, $srcname, $j, $dstname, $linux, $vianame;
+ } else {
+ $comment = sprintf "%d%s => %d%s", $i, $srcname, $j, $dstname;
+ }
+
+ my $data = sprintf "[0x%x] = 0x%x,", $i, $j;
+
+ printf " %-20s /* %s */\n", $data, $comment;
+}
+
+print "};\n";
--- /dev/null
+"Linux Name","Linux Keycode","OS-X Name","OS-X Keycode","AT set1 keycode","AT set2 keycode","AT set3 keycode",XT,"XT KBD","USB Keycodes","Win32 Name","Win32 Keycode","Xwin XT","Xfree86 KBD XT","X11 keysym","X11 keycode"
+KEY_RESERVED,0,,,,,,,,,,,,,,
+KEY_ESC,1,Escape,0x35,1,118,8,1,1,41,VK_ESCAPE,0x1b,1,1,XK_Escape,0xff1b
+KEY_1,2,ANSI_1,0x12,2,22,22,2,2,30,VK_1,0x31,2,2,XK_1,0x0031
+KEY_2,3,ANSI_2,0x13,3,30,30,3,3,31,VK_2,0x32,3,3,XK_2,0x0032
+KEY_3,4,ANSI_3,0x14,4,38,38,4,4,32,VK_3,0x33,4,4,XK_3,0x0033
+KEY_4,5,ANSI_4,0x15,5,37,37,5,5,33,VK_4,0x34,5,5,XK_4,0x0034
+KEY_5,6,ANSI_5,0x17,6,46,46,6,6,34,VK_5,0x35,6,6,XK_5,0x0035
+KEY_6,7,ANSI_6,0x16,7,54,54,7,7,35,VK_6,0x36,7,7,XK_6,0x0036
+KEY_7,8,ANSI_7,0x1a,8,61,61,8,8,36,VK_7,0x37,8,8,XK_7,0x0037
+KEY_8,9,ANSI_8,0x1c,9,62,62,9,9,37,VK_8,0x38,9,9,XK_8,0x0038
+KEY_9,10,ANSI_9,0x19,10,70,70,10,10,38,VK_9,0x39,10,10,XK_9,0x0039
+KEY_0,11,ANSI_0,0x1d,11,69,69,11,11,39,VK_0,0x30,11,11,XK_0,0x0030
+KEY_MINUS,12,ANSI_Minus,0x1b,12,78,78,12,12,45,VK_OEM_MINUS,0xbd,12,12,XK_minus,0x002d
+KEY_EQUAL,13,ANSI_Equal,0x18,13,85,85,13,13,46,VK_OEM_PLUS,0xbb,13,13,XK_equal,0x003d
+KEY_BACKSPACE,14,Delete,0x33,14,102,102,14,14,42,VK_BACK,0x08,14,14,XK_BackSpace,0xff08
+KEY_TAB,15,Tab,0x30,15,13,13,15,15,43,VK_TAB,0x09,15,15,XK_Tab,0xff09
+KEY_Q,16,ANSI_Q,0xc,16,21,21,16,16,20,VK_Q,0x51,16,16,XK_Q,0x0051
+KEY_Q,16,ANSI_Q,0xc,16,21,21,16,16,20,VK_Q,0x51,16,16,XK_q,0x0071
+KEY_W,17,ANSI_W,0xd,17,29,29,17,17,26,VK_W,0x57,17,17,XK_W,0x0057
+KEY_W,17,ANSI_W,0xd,17,29,29,17,17,26,VK_W,0x57,17,17,XK_w,0x0077
+KEY_E,18,ANSI_E,0xe,18,36,36,18,18,8,VK_E,0x45,18,18,XK_E,0x0045
+KEY_E,18,ANSI_E,0xe,18,36,36,18,18,8,VK_E,0x45,18,18,XK_e,0x0065
+KEY_R,19,ANSI_R,0xf,19,45,45,19,19,21,VK_R,0x52,19,19,XK_R,0x0052
+KEY_R,19,ANSI_R,0xf,19,45,45,19,19,21,VK_R,0x52,19,19,XK_r,0x0072
+KEY_T,20,ANSI_T,0x11,20,44,44,20,20,23,VK_T,0x54,20,20,XK_T,0x0054
+KEY_T,20,ANSI_T,0x11,20,44,44,20,20,23,VK_T,0x54,20,20,XK_t,0x0074
+KEY_Y,21,ANSI_Y,0x10,21,53,53,21,21,28,VK_Y,0x59,21,21,XK_Y,0x0059
+KEY_Y,21,ANSI_Y,0x10,21,53,53,21,21,28,VK_Y,0x59,21,21,XK_y,0x0079
+KEY_U,22,ANSI_U,0x20,22,60,60,22,22,24,VK_U,0x55,22,22,XK_U,0x0055
+KEY_U,22,ANSI_U,0x20,22,60,60,22,22,24,VK_U,0x55,22,22,XK_u,0x0075
+KEY_I,23,ANSI_I,0x22,23,67,67,23,23,12,VK_I,0x49,23,23,XK_I,0x0049
+KEY_I,23,ANSI_I,0x22,23,67,67,23,23,12,VK_I,0x49,23,23,XK_i,0x0069
+KEY_O,24,ANSI_O,0x1f,24,68,68,24,24,18,VK_O,0x4f,24,24,XK_O,0x004f
+KEY_O,24,ANSI_O,0x1f,24,68,68,24,24,18,VK_O,0x4f,24,24,XK_o,0x006f
+KEY_P,25,ANSI_P,0x23,25,77,77,25,25,19,VK_P,0x50,25,25,XK_P,0x0050
+KEY_P,25,ANSI_P,0x23,25,77,77,25,25,19,VK_P,0x50,25,25,XK_p,0x0070
+KEY_LEFTBRACE,26,ANSI_LeftBracket,0x21,26,84,84,26,26,47,VK_OEM_4,0xdb,26,26,XK_bracketleft,0x005b
+KEY_RIGHTBRACE,27,ANSI_RightBracket,0x1e,27,91,91,27,27,48,VK_OEM_6,0xdd,27,27,XK_bracketright,0x005d
+KEY_ENTER,28,Return,0x24,28,90,90,28,28,40,VK_RETURN,0x0d,28,28,XK_Return,0xff0d
+KEY_LEFTCTRL,29,Control,0x3b,29,20,17,29,29,224,VK_LCONTROL,0xa2,29,29,XK_Control_L,0xffe3
+KEY_LEFTCTRL,29,Control,0x3b,29,20,17,29,29,224,VK_CONTROL,0x11,29,29,XK_Control_L,0xffe3
+KEY_A,30,ANSI_A,0x0,30,28,28,30,30,4,VK_A,0x41,30,30,XK_A,0x0041
+KEY_A,30,ANSI_A,0x0,30,28,28,30,30,4,VK_A,0x41,30,30,XK_a,0x0061
+KEY_S,31,ANSI_S,0x1,31,27,27,31,31,22,VK_S,0x53,31,31,XK_S,0x0053
+KEY_S,31,ANSI_S,0x1,31,27,27,31,31,22,VK_S,0x53,31,31,XK_s,0x0073
+KEY_D,32,ANSI_D,0x2,32,35,35,32,32,7,VK_D,0x44,32,32,XK_D,0x0044
+KEY_D,32,ANSI_D,0x2,32,35,35,32,32,7,VK_D,0x44,32,32,XK_d,0x0064
+KEY_F,33,ANSI_F,0x3,33,43,43,33,33,9,VK_F,0x46,33,33,XK_F,0x0046
+KEY_F,33,ANSI_F,0x3,33,43,43,33,33,9,VK_F,0x46,33,33,XK_f,0x0066
+KEY_G,34,ANSI_G,0x5,34,52,52,34,34,10,VK_G,0x47,34,34,XK_G,0x0047
+KEY_G,34,ANSI_G,0x5,34,52,52,34,34,10,VK_G,0x47,34,34,XK_g,0x0067
+KEY_H,35,ANSI_H,0x4,35,51,51,35,35,11,VK_H,0x48,35,35,XK_H,0x0048
+KEY_H,35,ANSI_H,0x4,35,51,51,35,35,11,VK_H,0x48,35,35,XK_h,0x0068
+KEY_J,36,ANSI_J,0x26,36,59,59,36,36,13,VK_J,0x4a,36,36,XK_J,0x004a
+KEY_J,36,ANSI_J,0x26,36,59,59,36,36,13,VK_J,0x4a,36,36,XK_j,0x006a
+KEY_K,37,ANSI_K,0x28,37,66,66,37,37,14,VK_K,0x4b,37,37,XK_K,0x004b
+KEY_K,37,ANSI_K,0x28,37,66,66,37,37,14,VK_K,0x4b,37,37,XK_K,0x006b
+KEY_L,38,ANSI_L,0x25,38,75,75,38,38,15,VK_L,0x4c,38,38,XK_L,0x004c
+KEY_L,38,ANSI_L,0x25,38,75,75,38,38,15,VK_L,0x4c,38,38,XK_l,0x006c
+KEY_SEMICOLON,39,ANSI_Semicolon,0x29,39,76,76,39,39,51,VK_OEM_1,0xba,39,39,XK_semicolon,0x003b
+KEY_APOSTROPHE,40,ANSI_Quote,0x27,40,82,82,40,40,52,VK_OEM_7,0xde,40,40,XK_apostrophe,0x0027
+KEY_GRAVE,41,ANSI_Grave,0x32,41,14,14,41,41,53,VK_OEM_3,0xc0,41,41,XK_grave,0x0060
+KEY_SHIFT,42,Shift,0x38,42,18,18,42,42,225,VK_SHIFT,0x10,42,42,XK_Shift_L,0xffe1
+KEY_LEFTSHIFT,42,Shift,0x38,42,18,18,42,42,225,VK_LSHIFT,0xa0,42,42,XK_Shift_L,0xffe1
+KEY_BACKSLASH,43,ANSI_Backslash,0x2a,43,93,93,43,43,50,VK_OEM_5,0xdc,43,43,XK_backslash,0x005c
+KEY_Z,44,ANSI_Z,0x6,44,26,26,44,44,29,VK_Z,0x5a,44,44,XK_Z,0x005a
+KEY_Z,44,ANSI_Z,0x6,44,26,26,44,44,29,VK_Z,0x5a,44,44,XK_z,0x007a
+KEY_X,45,ANSI_X,0x7,45,34,34,45,45,27,VK_X,0x58,45,45,XK_X,0x0058
+KEY_X,45,ANSI_X,0x7,45,34,34,45,45,27,VK_X,0x58,45,45,XK_x,0x0078
+KEY_C,46,ANSI_C,0x8,46,33,33,46,46,6,VK_C,0x43,46,46,XK_C,0x0043
+KEY_C,46,ANSI_C,0x8,46,33,33,46,46,6,VK_C,0x43,46,46,XK_c,0x0063
+KEY_V,47,ANSI_V,0x9,47,42,42,47,47,25,VK_V,0x56,47,47,XK_V,0x0056
+KEY_V,47,ANSI_V,0x9,47,42,42,47,47,25,VK_V,0x56,47,47,XK_v,0x0076
+KEY_B,48,ANSI_B,0xb,48,50,50,48,48,5,VK_B,0x42,48,48,XK_B,0x0042
+KEY_B,48,ANSI_B,0xb,48,50,50,48,48,5,VK_B,0x42,48,48,XK_b,0x0062
+KEY_N,49,ANSI_N,0x2d,49,49,49,49,49,17,VK_N,0x4e,49,49,XK_N,0x004e
+KEY_N,49,ANSI_N,0x2d,49,49,49,49,49,17,VK_N,0x4e,49,49,XK_n,0x006e
+KEY_M,50,ANSI_M,0x2e,50,58,58,50,50,16,VK_M,0x4d,50,50,XK_M,0x004d
+KEY_M,50,ANSI_M,0x2e,50,58,58,50,50,16,VK_M,0x4d,50,50,XK_m,0x006d
+KEY_COMMA,51,ANSI_Comma,0x2b,51,65,65,51,51,54,VK_OEM_COMMA,0xbc,51,51,XK_comma,0x002c
+KEY_DOT,52,ANSI_Period,0x2f,52,73,73,52,52,55,VK_OEM_PERIOD,0xbe,52,52,XK_period,0x002e
+KEY_SLASH,53,ANSI_Slash,0x2c,53,74,74,53,53,56,VK_OEM_2,0xbf,53,53,XK_slash,0x002f
+KEY_RIGHTSHIFT,54,RightShift,0x3c,54,89,89,54,54,229,VK_RSHIFT,0xa1,54,54,XK_Shift_R,0xffe2
+KEY_KPASTERISK,55,ANSI_KeypadMultiply,0x43,55,124,126,55,55,85,VK_MULTIPLY,0x6a,55,55,XK_multiply,0x00d7
+KEY_LEFTALT,56,Option,0x3a,56,17,25,56,56,226,VK_LMENU,0xa4,56,56,XK_Alt_L,0xffe9
+KEY_LEFTALT,56,Option,0x3a,56,17,25,56,56,226,VK_MENU,0x12,56,56,XK_Alt_L,0xffe9
+KEY_SPACE,57,Space,0x31,57,41,41,57,57,44,VK_SPACE,0x20,57,57,XK_space,0x0020
+KEY_CAPSLOCK,58,CapsLock,0x39,58,88,20,58,58,57,VK_CAPITAL,0x14,58,58,XK_Caps_Lock,0xffe5
+KEY_F1,59,F1,0x7a,59,5,7,59,59,58,VK_F1,0x70,59,59,XK_F1,0xffbe
+KEY_F2,60,F2,0x78,60,6,15,60,60,59,VK_F2,0x71,60,60,XK_F2,0xffbf
+KEY_F3,61,F3,0x63,61,4,23,61,61,60,VK_F3,0x72,61,61,XK_F3,0xffc0
+KEY_F4,62,F4,0x76,62,12,31,62,62,61,VK_F4,0x73,62,62,XK_F4,0xffc1
+KEY_F5,63,F5,0x60,63,3,39,63,63,62,VK_F5,0x74,63,63,XK_F5,0xffc2
+KEY_F6,64,F6,0x61,64,11,47,64,64,63,VK_F6,0x75,64,64,XK_F6,0xffc3
+KEY_F7,65,F7,0x62,65,259,55,65,65,64,VK_F7,0x76,65,65,XK_F7,0xffc4
+KEY_F8,66,F8,0x64,66,10,63,66,66,65,VK_F8,0x77,66,66,XK_F8,0xffc5
+KEY_F9,67,F9,0x65,67,1,71,67,67,66,VK_F9,0x78,67,67,XK_F9,0xffc6
+KEY_F10,68,F10,0x6d,68,9,79,68,68,67,VK_F10,0x79,68,68,XK_F10,0xffc7
+KEY_NUMLOCK,69,,,69,119,118,69,69,83,VK_NUMLOCK,0x90,69,69,XK_Num_Lock,0xff7f
+KEY_SCROLLLOCK,70,,,70,126,95,70,70,71,VK_SCROLL,0x91,70,70,XK_Scroll_Lock,0xff14
+KEY_KP7,71,ANSI_Keypad7,0x59,71,108,108,71,71,95,VK_NUMPAD7,0x67,71,71,XK_KP_7,0xffb7
+KEY_KP8,72,ANSI_Keypad8,0x5b,72,117,117,72,72,96,VK_NUMPAD8,0x68,72,72,XK_KP_8,0xffb8
+KEY_KP9,73,ANSI_Keypad9,0x5c,73,125,125,73,73,97,VK_NUMPAD9,0x69,73,73,XK_KP_9,0xffb9
+KEY_KPMINUS,74,ANSI_KeypadMinus,0x4e,74,123,132,74,74,86,VK_SUBTRACT,0x6d,74,74,XK_KP_Subtract,0xffad
+KEY_KP4,75,ANSI_Keypad4,0x56,75,107,107,75,75,92,VK_NUMPAD4,0x64,75,75,XK_KP_4,0xffb4
+KEY_KP5,76,ANSI_Keypad5,0x57,76,115,115,76,76,93,VK_NUMPAD5,0x65,76,76,XK_KP_5,0xffb5
+KEY_KP6,77,ANSI_Keypad6,0x58,77,116,116,77,77,94,VK_NUMPAD6,0x66,77,77,XK_KP_6,0xffb6
+KEY_KPPLUS,78,ANSI_KeypadPlus,0x45,78,121,124,78,78,87,VK_ADD,0x6b,78,78,XK_KP_Add,0xffab
+KEY_KP1,79,ANSI_Keypad1,0x53,79,105,105,79,79,89,VK_NUMPAD1,0x61,79,79,XK_KP_1,0xffb1
+KEY_KP2,80,ANSI_Keypad2,0x54,80,114,114,80,80,90,VK_NUMPAD2,0x62,80,80,XK_KP_2,0xffb2
+KEY_KP3,81,ANSI_Keypad3,0x55,81,122,122,81,81,91,VK_NUMPAD3,0x63,81,81,XK_KP_3,0xffb3
+KEY_KP0,82,ANSI_Keypad0,0x52,82,112,112,82,82,98,VK_NUMPAD0,0x60,82,82,XK_KP_0,0xffb0
+KEY_KPDOT,83,ANSI_KeypadDecimal,0x41,83,113,113,83,83,99,VK_DECIMAL,0x6e,83,83,XK_KP_Decimal,0xffae
+,84,,,,,,,84,,,,,
+KEY_ZENKAKUHANKAKU,85,,,118,95,,,118,148,,,,
+KEY_102ND,86,,,86,97,19,,86,100,VK_OEM_102,0xe1,,
+KEY_F11,87,F11,0x67,87,120,86,101,87,68,VK_F11,0x7a,,
+KEY_F12,88,F12,0x6f,88,7,94,102,88,69,VK_F12,0x7b,,
+KEY_RO,89,,,115,81,,,115,135,,,,
+KEY_KATAKANA,90,JIS_Kana????,0x68,120,99,,,120,146,VK_KANA,0x15,,
+KEY_HIRAGANA,91,,,119,98,,,119,147,,,,
+KEY_HENKAN,92,,,121,100,134,,121,138,,,,
+KEY_KATAKANAHIRAGANA,93,,,112,19,135,,112,136,,,0xc8,0xc8
+KEY_MUHENKAN,94,,,123,103,133,,123,139,,,,
+KEY_KPJPCOMMA,95,JIS_KeypadComma,0x5f,92,39,,,92,140,,,,,XK_KP_Separator,0xffac
+KEY_KPENTER,96,ANSI_KeypadEnter,0x4c,,158,121,,284,88,,,0x64,0x64,XK_KP_Enter,0xff8d
+KEY_RIGHTCTRL,97,RightControl,0x3e,,,88,,285,228,VK_RCONTROL,0xa3,0x65,0x65,XK_Control_R,0xffe4
+KEY_KPSLASH,98,ANSI_KeypadDivide,0x4b,,181,119,,309,84,VK_DIVIDE,0x6f,0x68,0x68,XK_KP_Divide,0xffaf
+KEY_SYSRQ,99,,,84,260,87,,84,70,"VK_SNAPSHOT ???",0x2c,0x67,0x67,XK_Sys_Req,0xff15
+KEY_RIGHTALT,100,RightOption,0x3d,,,57,,312,230,VK_RMENU,0xa5,0x69,0x69,XK_Alt_R,0xffea
+KEY_LINEFEED,101,,,,,,,91,,,,,
+KEY_HOME,102,Home,0x73,,224,110,,327,74,VK_HOME,0x24,0x59,0x59,XK_Home,0xff50
+KEY_UP,103,UpArrow,0x7e,,236,99,109,328,82,VK_UP,0x26,0x5a,0x5a,XK_Up,0xff52
+KEY_PAGEUP,104,PageUp,0x74,,201,111,,329,75,VK_PRIOR,0x21,0x5b,0x5b,XK_Page_Up,0xff55
+KEY_LEFT,105,LeftArrow,0x7b,,203,97,111,331,80,VK_LEFT,0x25,0x5c,0x5c,XK_Left,0xff51
+KEY_RIGHT,106,RightArrow,0x7c,,205,106,112,333,79,VK_RIGHT,0x27,0x5e,0x5e,XK_Right,0xff53
+KEY_END,107,End,0x77,,225,101,,335,77,VK_END,0x23,0x5f,0x5f,XK_End,0xff57
+KEY_DOWN,108,DownArrow,0x7d,,254,96,110,336,81,VK_DOWN,0x28,0x60,0x60,XK_Down,0xff54
+KEY_PAGEDOWN,109,PageDown,0x79,,243,109,,337,78,VK_NEXT,0x22,0x61,0x61,XK_Page_Down,0xff56
+KEY_INSERT,110,,,,210,103,107,338,73,VK_INSERT,0x2d,0x62,0x62,XK_Insert,0xff63
+KEY_DELETE,111,ForwardDelete,0x75,,244,100,108,339,76,VK_DELETE,0x2e,0x63,0x63,XK_Delete,0xffff
+KEY_MACRO,112,,,,239,142,,367,,,,,
+KEY_MUTE,113,Mute,0x4a,,251,156,,288,239,VK_VOLUME_MUTE,0xad,,,
+KEY_VOLUMEDOWN,114,VolumeDown,0x49,,,157,,302,238,VK_VOLUME_DOWN,0xae,,
+KEY_VOLUMEUP,115,VolumeUp,0x48,,233,149,,304,237,VK_VOLUME_UP,0xaf,,
+KEY_POWER,116,,,,,,,350,102,,,,
+KEY_KPEQUAL,117,ANSI_KeypadEquals,0x51,89,15,,,89,103,,,0x76,0x76,XK_KP_Equal,0xffbd
+KEY_KPPLUSMINUS,118,,,,206,,,334,,,,,
+KEY_PAUSE,119,,,,198,98,,326,72,VK_PAUSE,0x013,0x66,0x66,XK_Pause,0xff13
+KEY_SCALE,120,,,,,,,267,,,,,
+KEY_KPCOMMA,121,ANSI_KeypadClear????,0x47,126,109,,,126,133,VK_SEPARATOR??,0x6c,,
+KEY_HANGEUL,122,,,,,,,,144,VK_HANGEUL,0x15,,
+KEY_HANJA,123,,,,,,,269,145,VK_HANJA,0x19,,
+KEY_YEN,124,JIS_Yen,0x5d,125,106,,,125,137,,,0x7d,0x7d
+KEY_LEFTMETA,125,Command,0x37,,,139,,347,227,VK_LWIN,0x5b,0x6b,0x6b,XK_Meta_L,0xffe7
+KEY_RIGHTMETA,126,,,,,140,,348,231,VK_RWIN,0x5c,0x6c,0x6c,XK_Meta_R,0xffe8
+KEY_COMPOSE,127,Function,0x3f,,,141,,349,101,VK_APPS,0x5d,0x6d,0x6d
+KEY_STOP,128,,,,,10,,360,243,VK_BROWSER_STOP,0xa9,,
+KEY_AGAIN,129,,,,,11,,261,121,,,,
+KEY_PROPS,130,,,,,12,,262,118,,,,
+KEY_UNDO,131,,,,,16,,263,122,,,,
+KEY_FRONT,132,,,,,,,268,119,,,,
+KEY_COPY,133,,,,,24,,376,124,,,,
+KEY_OPEN,134,,,,,32,,100,116,,,,
+KEY_PASTE,135,,,,,40,,101,125,,,,
+KEY_FIND,136,,,,,48,,321,244,,,,
+KEY_CUT,137,,,,,56,,316,123,,,,
+KEY_HELP,138,,,,,9,,373,117,VK_HELP,0x2f,,,XK_Help,0xff6a
+KEY_MENU,139,,,,,145,,286,,,,,
+KEY_CALC,140,,,,174,163,,289,251,,,,
+KEY_SETUP,141,,,,,,,102,,,,,
+KEY_SLEEP,142,,,,,,,351,248,VK_SLEEP,0x5f,,
+KEY_WAKEUP,143,,,,,,,355,,,,,
+KEY_FILE,144,,,,,,,103,,,,,
+KEY_SENDFILE,145,,,,,,,104,,,,,
+KEY_DELETEFILE,146,,,,,,,105,,,,,
+KEY_XFER,147,,,,,162,,275,,,,,
+KEY_PROG1,148,,,,,160,,287,,,,,
+KEY_PROG2,149,,,,,161,,279,,,,,
+KEY_WWW,150,,,,,,,258,240,,,,
+KEY_MSDOS,151,,,,,,,106,,,,,
+KEY_SCREENLOCK,152,,,,,150,,274,249,,,,
+KEY_DIRECTION,153,,,,,,,107,,,,,
+KEY_CYCLEWINDOWS,154,,,,,155,,294,,,,,
+KEY_MAIL,155,,,,,,,364,,,,,
+KEY_BOOKMARKS,156,,,,,,,358,,,,,
+KEY_COMPUTER,157,,,,,,,363,,,,,
+KEY_BACK,158,,,,,,,362,241,VK_BROWSER_BACK,0xa6,,
+KEY_FORWARD,159,,,,,,,361,242,VK_BROWSER_FORWARD,0xa7,,
+KEY_CLOSECD,160,,,,,154,,291,,,,,
+KEY_EJECTCD,161,,,,,,,108,236,,,,
+KEY_EJECTCLOSECD,162,,,,,,,381,,,,,
+KEY_NEXTSONG,163,,,,241,147,,281,235,VK_MEDIA_NEXT_TRACK,0xb0,,
+KEY_PLAYPAUSE,164,,,,173,,,290,232,VK_MEDIA_PLAY_PAUSE,0xb3,,
+KEY_PREVIOUSSONG,165,,,,250,148,,272,234,VK_MEDIA_PREV_TRACK,0xb1,,
+KEY_STOPCD,166,,,,164,152,,292,233,VK_MEDIA_STOP,0xb2,,
+KEY_RECORD,167,,,,,158,,305,,,,,
+KEY_REWIND,168,,,,,159,,280,,,,,
+KEY_PHONE,169,,,,,,,99,,,,,
+KEY_ISO,170,ISO_Section,0xa,,,,,112,,,,,
+KEY_CONFIG,171,,,,,,,257,,,,,
+KEY_HOMEPAGE,172,,,,178,151,,306,,VK_BROWSER_HOME,0xac,,
+KEY_REFRESH,173,,,,,,,359,250,VK_BROWSER_REFRESH,0xa8,,
+KEY_EXIT,174,,,,,,,113,,,,,
+KEY_MOVE,175,,,,,,,114,,,,,
+KEY_EDIT,176,,,,,,,264,247,,,,
+KEY_SCROLLUP,177,,,,,,,117,245,,,,
+KEY_SCROLLDOWN,178,,,,,,,271,246,,,,
+KEY_KPLEFTPAREN,179,,,,,,,374,182,,,,
+KEY_KPRIGHTPAREN,180,,,,,,,379,183,,,,
+KEY_NEW,181,,,,,,,265,,,,,
+KEY_REDO,182,,,,,,,266,,,,,
+KEY_F13,183,F13,0x69,93,47,127,,93,104,VK_F13,0x7c,0x6e,0x6e
+KEY_F14,184,F14,0x6b,94,55,128,,94,105,VK_F14,0x7d,0x6f,0x6f
+KEY_F15,185,F15,0x71,95,63,129,,95,106,VK_F15,0x7e,0x70,0x70
+KEY_F16,186,F16,0x6a,,,130,,85,107,VK_F16,0x7f,0x71,0x71
+KEY_F17,187,F17,0x40,,,131,,259,108,VK_F17,0x80,0x72,0x72
+KEY_F18,188,F18,0x4f,,,,,375,109,VK_F18,0x81,,
+KEY_F19,189,F19,0x50,,,,,260,110,VK_F19,0x82,,
+KEY_F20,190,F20,0x5a,,,,,90,111,VK_F20,0x83,,
+KEY_F21,191,,,,,,,116,112,VK_F21,0x84,,
+KEY_F22,192,,,,,,,377,113,VK_F22,0x85,,
+KEY_F23,193,,,,,,,109,114,VK_F23,0x86,,
+KEY_F24,194,,,,,,,111,115,VK_F24,0x87,,
+,195,,,,,,,277,,,,,
+,196,,,,,,,278,,,,,
+,197,,,,,,,282,,,,,
+,198,,,,,,,283,,,,,
+,199,,,,,,,295,,,,,
+KEY_PLAYCD,200,,,,,,,296,,,,,
+KEY_PAUSECD,201,,,,,,,297,,,,,
+KEY_PROG3,202,,,,,,,299,,,,,
+KEY_PROG4,203,,,,,,,300,,,,,
+KEY_DASHBOARD,204,,,,,,,301,,,,,
+KEY_SUSPEND,205,,,,,,,293,,,,,
+KEY_CLOSE,206,,,,,,,303,,,,,
+KEY_PLAY,207,,,,,,,307,,VK_PLAY,0xfa,,
+KEY_FASTFORWARD,208,,,,,,,308,,,,,
+KEY_BASSBOOST,209,,,,,,,310,,,,,
+KEY_PRINT,210,,,,,,,313,,VK_PRINT,0x2a,,
+KEY_HP,211,,,,,,,314,,,,,
+KEY_CAMERA,212,,,,,,,315,,,,,
+KEY_SOUND,213,,,,,,,317,,,,,
+KEY_QUESTION,214,,,,,,,318,,,,,
+KEY_EMAIL,215,,,,,,,319,,VK_LAUNCH_MAIL,0xb4,,
+KEY_CHAT,216,,,,,,,320,,,,,
+KEY_SEARCH,217,,,,,,,357,,VK_BROWSER_SEARCH,0xaa,,
+KEY_CONNECT,218,,,,,,,322,,,,,
+KEY_FINANCE,219,,,,,,,323,,,,,
+KEY_SPORT,220,,,,,,,324,,,,,
+KEY_SHOP,221,,,,,,,325,,,,,
+KEY_ALTERASE,222,,,,,,,276,,,,,
+KEY_CANCEL,223,,,,,,,330,,,,,
+KEY_BRIGHTNESSDOWN,224,,,,,,,332,,,,,
+KEY_BRIGHTNESSUP,225,,,,,,,340,,,,,
+KEY_MEDIA,226,,,,,,,365,,,,,
+KEY_SWITCHVIDEOMODE,227,,,,,,,342,,,,,
+KEY_KBDILLUMTOGGLE,228,,,,,,,343,,,,,
+KEY_KBDILLUMDOWN,229,,,,,,,344,,,,,
+KEY_KBDILLUMUP,230,,,,,,,345,,,,,
+KEY_SEND,231,,,,,,,346,,,,,
+KEY_REPLY,232,,,,,,,356,,,,,
+KEY_FORWARDMAIL,233,,,,,,,270,,,,,
+KEY_SAVE,234,,,,,,,341,,,,,
+KEY_DOCUMENTS,235,,,,,,,368,,,,,
+KEY_BATTERY,236,,,,,,,369,,,,,
+KEY_BLUETOOTH,237,,,,,,,370,,,,,
+KEY_WLAN,238,,,,,,,371,,,,,
+KEY_UWB,239,,,,,,,372,,,,,
+KEY_UNKNOWN,240,,,,,,,,,,,,
+KEY_VIDEO_NEXT,241,,,,,,,,,,,,
+KEY_VIDEO_PREV,242,,,,,,,,,,,,
+KEY_BRIGHTNESS_CYCLE,243,,,,,,,,,,,,
+KEY_BRIGHTNESS_ZERO,244,,,,,,,,,,,,
+KEY_DISPLAY_OFF,245,,,,,,,,,,,,
+KEY_WIMAX,246,,,,,,,,,,,,
+,247,,,,,,,,,,,,
+,248,,,,,,,,,,,,
+,249,,,,,,,,,,,,
+,250,,,,,,,,,,,,
+,251,,,,,,,,,,,,
+,252,,,,,,,,,,,,
+,253,,,,,,,,,,,,
+,254,,,,,,,,,,,,
+,255,,,,182,,,,,,,,
+BTN_MISC,0x100,,,,,,,,,,,,
+BTN_0,0x100,,,,,,,,,VK_LBUTTON,0x01,,
+BTN_1,0x101,,,,,,,,,VK_RBUTTON,0x02,,
+BTN_2,0x102,,,,,,,,,VK_MBUTTON,0x04,,
+BTN_3,0x103,,,,,,,,,VK_XBUTTON1,0x05,,
+BTN_4,0x104,,,,,,,,,VK_XBUTTON2,0x06,,
+BTN_5,0x105,,,,,,,,,,,,
+BTN_6,0x106,,,,,,,,,,,,
+BTN_7,0x107,,,,,,,,,,,,
+BTN_8,0x108,,,,,,,,,,,,
+BTN_9,0x109,,,,,,,,,,,,
+BTN_MOUSE,0x110,,,,,,,,,,,,
+BTN_LEFT,0x110,,,,,,,,,,,,
+BTN_RIGHT,0x111,,,,,,,,,,,,
+BTN_MIDDLE,0x112,,,,,,,,,,,,
+BTN_SIDE,0x113,,,,,,,,,,,,
+BTN_EXTRA,0x114,,,,,,,,,,,,
+BTN_FORWARD,0x115,,,,,,,,,,,,
+BTN_BACK,0x116,,,,,,,,,,,,
+BTN_TASK,0x117,,,,,,,,,,,,
+BTN_JOYSTICK,0x120,,,,,,,,,,,,
+BTN_TRIGGER,0x120,,,,,,,,,,,,
+BTN_THUMB,0x121,,,,,,,,,,,,
+BTN_THUMB2,0x122,,,,,,,,,,,,
+BTN_TOP,0x123,,,,,,,,,,,,
+BTN_TOP2,0x124,,,,,,,,,,,,
+BTN_PINKIE,0x125,,,,,,,,,,,,
+BTN_BASE,0x126,,,,,,,,,,,,
+BTN_BASE2,0x127,,,,,,,,,,,,
+BTN_BASE3,0x128,,,,,,,,,,,,
+BTN_BASE4,0x129,,,,,,,,,,,,
+BTN_BASE5,0x12a,,,,,,,,,,,,
+BTN_BASE6,0x12b,,,,,,,,,,,,
+BTN_DEAD,0x12f,,,,,,,,,,,,
+BTN_GAMEPAD,0x130,,,,,,,,,,,,
+BTN_A,0x130,,,,,,,,,,,,
+BTN_B,0x131,,,,,,,,,,,,
+BTN_C,0x132,,,,,,,,,,,,
+BTN_X,0x133,,,,,,,,,,,,
+BTN_Y,0x134,,,,,,,,,,,,
+BTN_Z,0x135,,,,,,,,,,,,
+BTN_TL,0x136,,,,,,,,,,,,
+BTN_TR,0x137,,,,,,,,,,,,
+BTN_TL2,0x138,,,,,,,,,,,,
+BTN_TR2,0x139,,,,,,,,,,,,
+BTN_SELECT,0x13a,,,,,,,,,,,,
+BTN_START,0x13b,,,,,,,,,,,,
+BTN_MODE,0x13c,,,,,,,,,,,,
+BTN_THUMBL,0x13d,,,,,,,,,,,,
+BTN_THUMBR,0x13e,,,,,,,,,,,,
+BTN_DIGI,0x140,,,,,,,,,,,,
+BTN_TOOL_PEN,0x140,,,,,,,,,,,,
+BTN_TOOL_RUBBER,0x141,,,,,,,,,,,,
+BTN_TOOL_BRUSH,0x142,,,,,,,,,,,,
+BTN_TOOL_PENCIL,0x143,,,,,,,,,,,,
+BTN_TOOL_AIRBRUSH,0x144,,,,,,,,,,,,
+BTN_TOOL_FINGER,0x145,,,,,,,,,,,,
+BTN_TOOL_MOUSE,0x146,,,,,,,,,,,,
+BTN_TOOL_LENS,0x147,,,,,,,,,,,,
+BTN_TOUCH,0x14a,,,,,,,,,,,,
+BTN_STYLUS,0x14b,,,,,,,,,,,,
+BTN_STYLUS2,0x14c,,,,,,,,,,,,
+BTN_TOOL_DOUBLETAP,0x14d,,,,,,,,,,,,
+BTN_TOOL_TRIPLETAP,0x14e,,,,,,,,,,,,
+BTN_TOOL_QUADTAP,0x14f,,,,,,,,,,,,
+BTN_WHEEL,0x150,,,,,,,,,,,,
+BTN_GEAR_DOWN,0x150,,,,,,,,,,,,
+BTN_GEAR_UP,0x151,,,,,,,,,,,,
+KEY_OK,0x160,,,,,,,,,,,,
+KEY_SELECT,0x161,,,,,,,,,VK_SELECT,0x29,,,XK_Select,0xff60
+KEY_GOTO,0x162,,,,,,,,,,,,
+KEY_CLEAR,0x163,,,,,,,,,,,,
+KEY_POWER2,0x164,,,,,,,,,,,,
+KEY_OPTION,0x165,,,,,,,,,,,,
+KEY_INFO,0x166,,,,,,,,,,,,
+KEY_TIME,0x167,,,,,,,,,,,,
+KEY_VENDOR,0x168,,,,,,,,,,,,
+KEY_ARCHIVE,0x169,,,,,,,,,,,,
+KEY_PROGRAM,0x16a,,,,,,,,,,,,
+KEY_CHANNEL,0x16b,,,,,,,,,,,,
+KEY_FAVORITES,0x16c,,,,,,,,,VK_BROWSER_FAVOURITES,0xab,,
+KEY_EPG,0x16d,,,,,,,,,,,,
+KEY_PVR,0x16e,,,,,,,,,,,,
+KEY_MHP,0x16f,,,,,,,,,,,,
+KEY_LANGUAGE,0x170,,,,,,,,,,,,
+KEY_TITLE,0x171,,,,,,,,,,,,
+KEY_SUBTITLE,0x172,,,,,,,,,,,,
+KEY_ANGLE,0x173,,,,,,,,,,,,
+KEY_ZOOM,0x174,,,,,,,,,VK_ZOOM,0xfb,,
+KEY_MODE,0x175,,,,,,,,,,,,
+KEY_KEYBOARD,0x176,,,,,,,,,,,,
+KEY_SCREEN,0x177,,,,,,,,,,,,
+KEY_PC,0x178,,,,,,,,,,,,
+KEY_TV,0x179,,,,,,,,,,,,
+KEY_TV2,0x17a,,,,,,,,,,,,
+KEY_VCR,0x17b,,,,,,,,,,,,
+KEY_VCR2,0x17c,,,,,,,,,,,,
+KEY_SAT,0x17d,,,,,,,,,,,,
+KEY_SAT2,0x17e,,,,,,,,,,,,
+KEY_CD,0x17f,,,,,,,,,,,,
+KEY_TAPE,0x180,,,,,,,,,,,,
+KEY_RADIO,0x181,,,,,,,,,,,,
+KEY_TUNER,0x182,,,,,,,,,,,,
+KEY_PLAYER,0x183,,,,,,,,,,,,
+KEY_TEXT,0x184,,,,,,,,,,,,
+KEY_DVD,0x185,,,,,,,,,,,,
+KEY_AUX,0x186,,,,,,,,,,,,
+KEY_MP3,0x187,,,,,,,,,,,,
+KEY_AUDIO,0x188,,,,,,,,,,,,
+KEY_VIDEO,0x189,,,,,,,,,,,,
+KEY_DIRECTORY,0x18a,,,,,,,,,,,,
+KEY_LIST,0x18b,,,,,,,,,,,,
+KEY_MEMO,0x18c,,,,,,,,,,,,
+KEY_CALENDAR,0x18d,,,,,,,,,,,,
+KEY_RED,0x18e,,,,,,,,,,,,
+KEY_GREEN,0x18f,,,,,,,,,,,,
+KEY_YELLOW,0x190,,,,,,,,,,,,
+KEY_BLUE,0x191,,,,,,,,,,,,
+KEY_CHANNELUP,0x192,,,,,,,,,,,,
+KEY_CHANNELDOWN,0x193,,,,,,,,,,,,
+KEY_FIRST,0x194,,,,,,,,,,,,
+KEY_LAST,0x195,,,,,,,,,,,,
+KEY_AB,0x196,,,,,,,,,,,,
+KEY_NEXT,0x197,,,,,,,,,,,,
+KEY_RESTART,0x198,,,,,,,,,,,,
+KEY_SLOW,0x199,,,,,,,,,,,,
+KEY_SHUFFLE,0x19a,,,,,,,,,,,,
+KEY_BREAK,0x19b,,,,,,,,,,,,
+KEY_PREVIOUS,0x19c,,,,,,,,,,,,
+KEY_DIGITS,0x19d,,,,,,,,,,,,
+KEY_TEEN,0x19e,,,,,,,,,,,,
+KEY_TWEN,0x19f,,,,,,,,,,,,
+KEY_VIDEOPHONE,0x1a0,,,,,,,,,,,,
+KEY_GAMES,0x1a1,,,,,,,,,,,,
+KEY_ZOOMIN,0x1a2,,,,,,,,,,,,
+KEY_ZOOMOUT,0x1a3,,,,,,,,,,,,
+KEY_ZOOMRESET,0x1a4,,,,,,,,,,,,
+KEY_WORDPROCESSOR,0x1a5,,,,,,,,,,,,
+KEY_EDITOR,0x1a6,,,,,,,,,,,,
+KEY_SPREADSHEET,0x1a7,,,,,,,,,,,,
+KEY_GRAPHICSEDITOR,0x1a8,,,,,,,,,,,,
+KEY_PRESENTATION,0x1a9,,,,,,,,,,,,
+KEY_DATABASE,0x1aa,,,,,,,,,,,,
+KEY_NEWS,0x1ab,,,,,,,,,,,,
+KEY_VOICEMAIL,0x1ac,,,,,,,,,,,,
+KEY_ADDRESSBOOK,0x1ad,,,,,,,,,,,,
+KEY_MESSENGER,0x1ae,,,,,,,,,,,,
+KEY_DISPLAYTOGGLE,0x1af,,,,,,,,,,,,
+KEY_SPELLCHECK,0x1b0,,,,,,,,,,,,
+KEY_LOGOFF,0x1b1,,,,,,,,,,,,
+KEY_DOLLAR,0x1b2,,,,,,,,,,,,
+KEY_EURO,0x1b3,,,,,,,,,,,,
+KEY_FRAMEBACK,0x1b4,,,,,,,,,,,,
+KEY_FRAMEFORWARD,0x1b5,,,,,,,,,,,,
+KEY_CONTEXT_MENU,0x1b6,,,,,,,,,,,,
+KEY_MEDIA_REPEAT,0x1b7,,,,,,,,,,,,
+KEY_DEL_EOL,0x1c0,,,,,,,,,,,,
+KEY_DEL_EOS,0x1c1,,,,,,,,,,,,
+KEY_INS_LINE,0x1c2,,,,,,,,,,,,
+KEY_DEL_LINE,0x1c3,,,,,,,,,,,,
+KEY_FN,0x1d0,,,,,,,,,,,,
+KEY_FN_ESC,0x1d1,,,,,,,,,,,,
+KEY_FN_F1,0x1d2,,,,,,,,,,,,
+KEY_FN_F2,0x1d3,,,,,,,,,,,,
+KEY_FN_F3,0x1d4,,,,,,,,,,,,
+KEY_FN_F4,0x1d5,,,,,,,,,,,,
+KEY_FN_F5,0x1d6,,,,,,,,,,,,
+KEY_FN_F6,0x1d7,,,,,,,,,,,,
+KEY_FN_F7,0x1d8,,,,,,,,,,,,
+KEY_FN_F8,0x1d9,,,,,,,,,,,,
+KEY_FN_F9,0x1da,,,,,,,,,,,,
+KEY_FN_F10,0x1db,,,,,,,,,,,,
+KEY_FN_F11,0x1dc,,,,,,,,,,,,
+KEY_FN_F12,0x1dd,,,,,,,,,,,,
+KEY_FN_1,0x1de,,,,,,,,,,,,
+KEY_FN_2,0x1df,,,,,,,,,,,,
+KEY_FN_D,0x1e0,,,,,,,,,,,,
+KEY_FN_E,0x1e1,,,,,,,,,,,,
+KEY_FN_F,0x1e2,,,,,,,,,,,,
+KEY_FN_S,0x1e3,,,,,,,,,,,,
+KEY_FN_B,0x1e4,,,,,,,,,,,,
+KEY_BRL_DOT1,0x1f1,,,,,,,,,,,,
+KEY_BRL_DOT2,0x1f2,,,,,,,,,,,,
+KEY_BRL_DOT3,0x1f3,,,,,,,,,,,,
+KEY_BRL_DOT4,0x1f4,,,,,,,,,,,,
+KEY_BRL_DOT5,0x1f5,,,,,,,,,,,,
+KEY_BRL_DOT6,0x1f6,,,,,,,,,,,,
+KEY_BRL_DOT7,0x1f7,,,,,,,,,,,,
+KEY_BRL_DOT8,0x1f8,,,,,,,,,,,,
+KEY_BRL_DOT9,0x1f9,,,,,,,,,,,,
+KEY_BRL_DOT10,0x1fa,,,,,,,,,,,,
+KEY_NUMERIC_0,0x200,,,,,,,,,,,,
+KEY_NUMERIC_1,0x201,,,,,,,,,,,,
+KEY_NUMERIC_2,0x202,,,,,,,,,,,,
+KEY_NUMERIC_3,0x203,,,,,,,,,,,,
+KEY_NUMERIC_4,0x204,,,,,,,,,,,,
+KEY_NUMERIC_5,0x205,,,,,,,,,,,,
+KEY_NUMERIC_6,0x206,,,,,,,,,,,,
+KEY_NUMERIC_7,0x207,,,,,,,,,,,,
+KEY_NUMERIC_8,0x208,,,,,,,,,,,,
+KEY_NUMERIC_9,0x209,,,,,,,,,,,,
+KEY_NUMERIC_STAR,0x20a,,,,,,,,,,,,
+KEY_NUMERIC_POUND,0x20b,,,,,,,,,,,,
+KEY_RFKILL,0x20c,,,,,,,,,,,,
--- /dev/null
+SPICEGTK_1 {
+global:
+spice_audio_get;
+spice_audio_get_type;
+spice_audio_new;
+spice_channel_connect;
+spice_channel_destroy;
+spice_channel_disconnect;
+spice_channel_event_get_type;
+spice_channel_flush_async;
+spice_channel_flush_finish;
+spice_channel_get_error;
+spice_channel_get_type;
+spice_channel_new;
+spice_channel_open_fd;
+spice_channel_set_capability;
+spice_channel_string_to_type;
+spice_channel_test_capability;
+spice_channel_test_common_capability;
+spice_channel_type_to_string;
+spice_client_error_quark;
+spice_cursor_channel_get_type;
+spice_display_change_preferred_compression;
+spice_display_channel_get_type;
+spice_display_get_gl_scanout;
+spice_display_get_grab_keys;
+spice_display_get_pixbuf;
+spice_display_get_primary;
+spice_display_get_type;
+spice_display_gl_draw_done;
+spice_display_key_event_get_type;
+spice_display_mouse_ungrab;
+spice_display_new;
+spice_display_new_with_monitor;
+spice_display_send_keys;
+spice_display_set_grab_keys;
+spice_file_transfer_task_cancel;
+spice_file_transfer_task_get_filename;
+spice_file_transfer_task_get_progress;
+spice_file_transfer_task_get_total_bytes;
+spice_file_transfer_task_get_transferred_bytes;
+spice_file_transfer_task_get_type;
+spice_get_option_group;
+spice_gl_scanout_free;
+spice_gl_scanout_get_type;
+spice_grab_sequence_as_string;
+spice_grab_sequence_copy;
+spice_grab_sequence_free;
+spice_grab_sequence_get_type;
+spice_grab_sequence_new;
+spice_grab_sequence_new_from_string;
+spice_g_signal_connect_object;
+spice_gtk_session_copy_to_guest;
+spice_gtk_session_get;
+spice_gtk_session_get_type;
+spice_gtk_session_paste_from_guest;
+spice_inputs_button_press;
+spice_inputs_button_release;
+spice_inputs_channel_get_type;
+spice_inputs_key_press;
+spice_inputs_key_press_and_release;
+spice_inputs_key_release;
+spice_inputs_lock_get_type;
+spice_inputs_motion;
+spice_inputs_position;
+spice_inputs_set_key_locks;
+spice_main_agent_test_capability;
+spice_main_channel_get_type;
+spice_main_clipboard_grab;
+spice_main_clipboard_notify;
+spice_main_clipboard_release;
+spice_main_clipboard_request;
+spice_main_clipboard_selection_grab;
+spice_main_clipboard_selection_notify;
+spice_main_clipboard_selection_release;
+spice_main_clipboard_selection_request;
+spice_main_file_copy_async;
+spice_main_file_copy_finish;
+spice_main_request_mouse_mode;
+spice_main_send_monitor_config;
+spice_main_set_display;
+spice_main_set_display_enabled;
+spice_main_update_display;
+spice_main_update_display_enabled;
+spice_playback_channel_get_type;
+spice_playback_channel_set_delay;
+spice_port_channel_get_type;
+spice_port_event;
+spice_port_write_async;
+spice_port_write_finish;
+spice_record_channel_get_type;
+spice_record_send_data;
+spice_session_connect;
+spice_session_disconnect;
+spice_session_get_channels;
+spice_session_get_proxy_uri;
+spice_session_get_read_only;
+spice_session_get_type;
+spice_session_has_channel_type;
+spice_session_is_for_migration;
+spice_session_migration_get_type;
+spice_session_new;
+spice_session_open_fd;
+spice_session_verify_get_type;
+spice_set_session_option;
+spice_smartcard_channel_get_type;
+spice_smartcard_manager_get;
+spice_smartcard_manager_get_readers;
+spice_smartcard_manager_get_type;
+spice_smartcard_manager_insert_card;
+spice_smartcard_manager_remove_card;
+spice_smartcard_reader_get_type;
+spice_smartcard_reader_insert_card;
+spice_smartcard_reader_is_software;
+spice_smartcard_reader_remove_card;
+spice_uri_get_hostname;
+spice_uri_get_password;
+spice_uri_get_port;
+spice_uri_get_scheme;
+spice_uri_get_type;
+spice_uri_get_user;
+spice_uri_set_hostname;
+spice_uri_set_password;
+spice_uri_set_port;
+spice_uri_set_scheme;
+spice_uri_set_user;
+spice_uri_to_string;
+spice_usb_device_get_description;
+spice_usb_device_get_libusb_device;
+spice_usb_device_get_type;
+spice_usb_device_manager_can_redirect_device;
+spice_usb_device_manager_connect_device_async;
+spice_usb_device_manager_connect_device_finish;
+spice_usb_device_manager_disconnect_device;
+spice_usb_device_manager_disconnect_device_async;
+spice_usb_device_manager_disconnect_device_finish;
+spice_usb_device_manager_get;
+spice_usb_device_manager_get_devices;
+spice_usb_device_manager_get_devices_with_filter;
+spice_usb_device_manager_get_type;
+spice_usb_device_manager_is_device_connected;
+spice_usb_device_manager_is_redirecting;
+spice_usb_device_widget_get_type;
+spice_usb_device_widget_new;
+spice_usbredir_channel_get_type;
+spice_util_get_debug;
+spice_util_get_version_string;
+spice_util_set_debug;
+spice_uuid_to_string;
+spice_webdav_channel_get_type;
+local:
+*;
+};
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SMARTCARD_MANAGER_PRIV_H__
+#define __SMARTCARD_MANAGER_PRIV_H__
+
+#include "config.h"
+#include <gio/gio.h>
+#include "spice-session.h"
+
+G_BEGIN_DECLS
+
+void spice_smartcard_manager_init_async(SpiceSession *session,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer opaque);
+gboolean spice_smartcard_manager_init_finish(SpiceSession *session,
+ GAsyncResult *result,
+ GError **err);
+
+G_END_DECLS
+
+#endif /* __SMARTCARD_MANAGER_PRIV_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <glib-object.h>
+#include <string.h>
+
+#ifdef USE_SMARTCARD_012
+#include <vcard_emul.h>
+#include <vevent.h>
+#include <vreader.h>
+#else
+#ifdef USE_SMARTCARD
+#include <libcacard.h>
+#endif
+#endif
+
+#include "spice-client.h"
+#include "smartcard-manager.h"
+#include "smartcard-manager-priv.h"
+#include "spice-marshal.h"
+
+/**
+ * SECTION:smartcard-manager
+ * @short_description: smartcard management
+ * @title: Spice Smartcard Manager
+ * @section_id:
+ * @see_also:
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * #SpiceSmartcardManager monitors smartcard reader plugging/unplugging,
+ * and smartcard insertions/removals. It also provides methods to handle
+ * software smartcards (to emulate a smartcard reader/smartcard on the
+ * guest using 3 certificates available to the client).
+ */
+
+/* ------------------------------------------------------------------ */
+/* gobject glue */
+
+#define SPICE_SMARTCARD_MANAGER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SPICE_TYPE_SMARTCARD_MANAGER, SpiceSmartcardManagerPrivate))
+
+struct _SpiceSmartcardManagerPrivate {
+ guint monitor_id;
+
+ /* software smartcard reader, the certificates to use for this reader
+ * were given at the channel creation time. This reader has no physical
+ * existence, it's all controlled by explicit software
+ * insertion/removal of cards
+ */
+#ifdef USE_SMARTCARD
+ VReader *software_reader;
+#endif
+};
+
+G_DEFINE_TYPE(SpiceSmartcardManager, spice_smartcard_manager, G_TYPE_OBJECT)
+#ifdef USE_SMARTCARD
+G_DEFINE_BOXED_TYPE(VReader, spice_smartcard_reader, vreader_reference, vreader_free)
+#else
+typedef GObject VReader;
+G_DEFINE_BOXED_TYPE(VReader, spice_smartcard_reader, g_object_ref, g_object_unref)
+#endif
+
+/* Properties */
+enum {
+ PROP_0,
+};
+
+/* Signals */
+enum {
+ SPICE_SMARTCARD_MANAGER_READER_ADDED,
+ SPICE_SMARTCARD_MANAGER_READER_REMOVED,
+ SPICE_SMARTCARD_MANAGER_CARD_INSERTED,
+ SPICE_SMARTCARD_MANAGER_CARD_REMOVED,
+
+ SPICE_SMARTCARD_MANAGER_LAST_SIGNAL,
+};
+
+static guint signals[SPICE_SMARTCARD_MANAGER_LAST_SIGNAL];
+
+#ifdef USE_SMARTCARD
+typedef gboolean (*SmartcardSourceFunc)(VEvent *event, gpointer user_data);
+static gboolean smartcard_monitor_dispatch(VEvent *event, gpointer user_data);
+#endif
+
+/* ------------------------------------------------------------------ */
+
+static void spice_smartcard_manager_init(SpiceSmartcardManager *smartcard_manager)
+{
+ SpiceSmartcardManagerPrivate *priv;
+
+ priv = SPICE_SMARTCARD_MANAGER_GET_PRIVATE(smartcard_manager);
+ smartcard_manager->priv = priv;
+}
+
+static void spice_smartcard_manager_dispose(GObject *gobject)
+{
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_smartcard_manager_parent_class)->dispose)
+ G_OBJECT_CLASS(spice_smartcard_manager_parent_class)->dispose(gobject);
+}
+
+static void spice_smartcard_manager_finalize(GObject *gobject)
+{
+ SpiceSmartcardManager *manager = SPICE_SMARTCARD_MANAGER(gobject);
+ SpiceSmartcardManagerPrivate *priv = manager->priv;
+
+ if (priv->monitor_id != 0) {
+ g_source_remove(priv->monitor_id);
+ priv->monitor_id = 0;
+ }
+
+#ifdef USE_SMARTCARD
+ g_clear_pointer(&priv->software_reader, vreader_free);
+#endif
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_smartcard_manager_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_smartcard_manager_parent_class)->finalize(gobject);
+}
+
+static void spice_smartcard_manager_class_init(SpiceSmartcardManagerClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ /**
+ * SpiceSmartcardManager::reader-added:
+ * @manager: the #SpiceSmartcardManager that emitted the signal
+ * @vreader: #VReader boxed object corresponding to the added reader
+ *
+ * The #SpiceSmartcardManager::reader-added signal is emitted whenever
+ * a new smartcard reader (software or hardware) has been plugged in.
+ **/
+ signals[SPICE_SMARTCARD_MANAGER_READER_ADDED] =
+ g_signal_new("reader-added",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceSmartcardManagerClass, reader_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1,
+ SPICE_TYPE_SMARTCARD_READER);
+
+ /**
+ * SpiceSmartcardManager::reader-removed:
+ * @manager: the #SpiceSmartcardManager that emitted the signal
+ * @vreader: #VReader boxed object corresponding to the removed reader
+ *
+ * The #SpiceSmartcardManager::reader-removed signal is emitted whenever
+ * a smartcard reader (software or hardware) has been removed.
+ **/
+ signals[SPICE_SMARTCARD_MANAGER_READER_REMOVED] =
+ g_signal_new("reader-removed",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceSmartcardManagerClass, reader_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1,
+ SPICE_TYPE_SMARTCARD_READER);
+
+ /**
+ * SpiceSmartcardManager::card-inserted:
+ * @manager: the #SpiceSmartcardManager that emitted the signal
+ * @vreader: #VReader boxed object corresponding to the reader a new
+ * card was inserted in
+ *
+ * The #SpiceSmartcardManager::card-inserted signal is emitted whenever
+ * a smartcard is inserted in a reader
+ **/
+ signals[SPICE_SMARTCARD_MANAGER_CARD_INSERTED] =
+ g_signal_new("card-inserted",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceSmartcardManagerClass, card_inserted),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1,
+ SPICE_TYPE_SMARTCARD_READER);
+
+ /**
+ * SpiceSmartcardManager::card-removed:
+ * @manager: the #SpiceSmartcardManager that emitted the signal
+ * @vreader: #VReader boxed object corresponding to the reader a card
+ * was removed from
+ *
+ * The #SpiceSmartcardManager::card-removed signal is emitted whenever
+ * a smartcard was removed from a reader.
+ **/
+ signals[SPICE_SMARTCARD_MANAGER_CARD_REMOVED] =
+ g_signal_new("card-removed",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceSmartcardManagerClass, card_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1,
+ SPICE_TYPE_SMARTCARD_READER);
+ gobject_class->dispose = spice_smartcard_manager_dispose;
+ gobject_class->finalize = spice_smartcard_manager_finalize;
+
+ g_type_class_add_private(klass, sizeof(SpiceSmartcardManagerPrivate));
+}
+
+/* ------------------------------------------------------------------ */
+/* private api */
+
+static SpiceSmartcardManager *spice_smartcard_manager_new(void)
+{
+ return g_object_new(SPICE_TYPE_SMARTCARD_MANAGER, NULL);
+}
+
+/* ------------------------------------------------------------------ */
+/* public api */
+
+/**
+ * spice_smartcard_manager_get:
+ *
+ * #SpiceSmartcardManager is a singleton, use this function to get a pointer
+ * to it. A new SpiceSmartcardManager instance will be created the first
+ * time this function is called
+ *
+ * Returns: (transfer none): a weak reference to the #SpiceSmartcardManager
+ */
+SpiceSmartcardManager *spice_smartcard_manager_get(void)
+{
+ static GOnce manager_singleton_once = G_ONCE_INIT;
+
+ return g_once(&manager_singleton_once,
+ (GThreadFunc)spice_smartcard_manager_new,
+ NULL);
+}
+
+#ifdef USE_SMARTCARD
+static gboolean smartcard_monitor_dispatch(VEvent *event, gpointer user_data)
+{
+ g_return_val_if_fail(event != NULL, TRUE);
+ SpiceSmartcardManager *manager = SPICE_SMARTCARD_MANAGER(user_data);
+
+ switch (event->type) {
+ case VEVENT_READER_INSERT:
+ if (spice_smartcard_reader_is_software((SpiceSmartcardReader*)event->reader)) {
+ g_warn_if_fail(manager->priv->software_reader == NULL);
+ manager->priv->software_reader = vreader_reference(event->reader);
+ }
+ SPICE_DEBUG("smartcard: reader-added");
+ g_signal_emit(G_OBJECT(user_data),
+ signals[SPICE_SMARTCARD_MANAGER_READER_ADDED],
+ 0, event->reader);
+ break;
+
+ case VEVENT_READER_REMOVE:
+ if (spice_smartcard_reader_is_software((SpiceSmartcardReader*)event->reader)) {
+ g_warn_if_fail(manager->priv->software_reader != NULL);
+ g_clear_pointer(&manager->priv->software_reader, vreader_free);
+ }
+ SPICE_DEBUG("smartcard: reader-removed");
+ g_signal_emit(G_OBJECT(user_data),
+ signals[SPICE_SMARTCARD_MANAGER_READER_REMOVED],
+ 0, event->reader);
+ break;
+
+ case VEVENT_CARD_INSERT:
+ SPICE_DEBUG("smartcard: card-inserted");
+ g_signal_emit(G_OBJECT(user_data),
+ signals[SPICE_SMARTCARD_MANAGER_CARD_INSERTED],
+ 0, event->reader);
+ break;
+ case VEVENT_CARD_REMOVE:
+ SPICE_DEBUG("smartcard: card-removed");
+ g_signal_emit(G_OBJECT(user_data),
+ signals[SPICE_SMARTCARD_MANAGER_CARD_REMOVED],
+ 0, event->reader);
+ break;
+ case VEVENT_LAST:
+ break;
+ }
+
+ return TRUE;
+}
+
+/* ------------------------------------------------------------------ */
+/* smartcard monitoring GSource */
+struct _SmartcardSource {
+ GSource parent_source;
+ VEvent *pending_event;
+};
+typedef struct _SmartcardSource SmartcardSource;
+
+static gboolean smartcard_source_prepare(GSource *source, gint *timeout)
+{
+ SmartcardSource *smartcard_source = (SmartcardSource *)source;
+
+ if (smartcard_source->pending_event == NULL)
+ smartcard_source->pending_event = vevent_get_next_vevent();
+
+ if (timeout != NULL)
+ *timeout = -1;
+
+ return (smartcard_source->pending_event != NULL);
+}
+
+static gboolean smartcard_source_check(GSource *source)
+{
+ return smartcard_source_prepare(source, NULL);
+}
+
+static gboolean smartcard_source_dispatch(GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ SmartcardSource *smartcard_source = (SmartcardSource *)source;
+ SmartcardSourceFunc smartcard_callback = (SmartcardSourceFunc)callback;
+
+ g_return_val_if_fail(smartcard_source->pending_event != NULL, FALSE);
+
+ if (callback) {
+ gboolean event_consumed;
+ event_consumed = smartcard_callback(smartcard_source->pending_event,
+ user_data);
+ if (event_consumed) {
+ vevent_delete(smartcard_source->pending_event);
+ smartcard_source->pending_event = NULL;
+ }
+ }
+
+ return TRUE;
+}
+
+static void smartcard_source_finalize(GSource *source)
+{
+ SmartcardSource *smartcard_source = (SmartcardSource *)source;
+
+ g_clear_pointer(&smartcard_source->pending_event, vevent_delete);
+}
+
+static GSource *smartcard_monitor_source_new(void)
+{
+ static GSourceFuncs source_funcs = {
+ .prepare = smartcard_source_prepare,
+ .check = smartcard_source_check,
+ .dispatch = smartcard_source_dispatch,
+ .finalize = smartcard_source_finalize
+ };
+ GSource *source;
+
+ source = g_source_new(&source_funcs, sizeof(SmartcardSource));
+ g_source_set_name(source, "Smartcard event source");
+ return source;
+}
+
+static guint smartcard_monitor_add(SmartcardSourceFunc callback,
+ gpointer user_data)
+{
+ GSource *source;
+ guint id;
+
+ source = smartcard_monitor_source_new();
+ g_source_set_callback(source, (GSourceFunc)callback, user_data, NULL);
+ id = g_source_attach(source, NULL);
+ g_source_unref(source);
+
+ return id;
+}
+
+static void
+spice_smartcard_manager_update_monitor(void)
+{
+ SpiceSmartcardManager *self = spice_smartcard_manager_get();
+ SpiceSmartcardManagerPrivate *priv = self->priv;
+
+ if (priv->monitor_id != 0)
+ return;
+
+ priv->monitor_id = smartcard_monitor_add(smartcard_monitor_dispatch, self);
+}
+
+#define SPICE_SOFTWARE_READER_NAME "Spice Software Smartcard"
+
+typedef struct {
+ SpiceSession *session;
+ GCancellable *cancellable;
+ GError *err;
+} SmartcardManagerInitArgs;
+
+static gboolean smartcard_manager_init(SmartcardManagerInitArgs *args)
+{
+ gchar *emul_args = NULL;
+ VCardEmulOptions *options = NULL;
+ VCardEmulError emul_init_status;
+ gchar *dbname = NULL;
+ GStrv certificates = NULL;
+ gboolean retval = FALSE;
+
+ SPICE_DEBUG("smartcard_manager_init");
+ g_return_val_if_fail(SPICE_IS_SESSION(args->session), FALSE);
+ g_object_get(G_OBJECT(args->session),
+ "smartcard-db", &dbname,
+ "smartcard-certificates", &certificates,
+ NULL);
+
+ if ((certificates == NULL) || (g_strv_length(certificates) != 3))
+ goto init;
+
+ if (dbname) {
+ emul_args = g_strdup_printf("db=\"%s\" use_hw=no "
+ "soft=(,%s,CAC,,%s,%s,%s)",
+ dbname, SPICE_SOFTWARE_READER_NAME,
+ certificates[0], certificates[1],
+ certificates[2]);
+ } else {
+ emul_args = g_strdup_printf("use_hw=no soft=(,%s,CAC,,%s,%s,%s)",
+ SPICE_SOFTWARE_READER_NAME,
+ certificates[0], certificates[1],
+ certificates[2]);
+ }
+
+ options = vcard_emul_options(emul_args);
+ if (options == NULL) {
+ args->err = g_error_new(SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED,
+ "vcard_emul_options() failed!");
+ goto end;
+ }
+
+ if (g_cancellable_set_error_if_cancelled(args->cancellable, &args->err))
+ goto end;
+
+init:
+ SPICE_DEBUG("vcard_emul_init");
+ emul_init_status = vcard_emul_init(options);
+ if ((emul_init_status != VCARD_EMUL_OK)
+ && (emul_init_status != VCARD_EMUL_INIT_ALREADY_INITED)) {
+ args->err = g_error_new(SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED,
+ "Failed to initialize smartcard");
+ goto end;
+ }
+
+ retval = TRUE;
+
+end:
+ SPICE_DEBUG("smartcard_manager_init end: %d", retval);
+ g_free(emul_args);
+ g_free(dbname);
+ g_strfreev(certificates);
+ return retval;
+}
+
+static void smartcard_manager_init_helper(GTask *task,
+ gpointer object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ static GOnce smartcard_manager_once = G_ONCE_INIT;
+ SmartcardManagerInitArgs args;
+
+ args.session = SPICE_SESSION(object);
+ args.cancellable = cancellable;
+ args.err = NULL;
+
+
+ g_once(&smartcard_manager_once,
+ (GThreadFunc)smartcard_manager_init,
+ &args);
+
+ if (args.err != NULL)
+ g_task_return_error(task, args.err);
+ else
+ g_task_return_boolean(task, TRUE);
+}
+
+
+G_GNUC_INTERNAL
+void spice_smartcard_manager_init_async(SpiceSession *session,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer opaque)
+{
+ GTask *task = g_task_new(session, cancellable, callback, opaque);
+
+ g_task_run_in_thread(task, smartcard_manager_init_helper);
+ g_object_unref(task);
+}
+
+G_GNUC_INTERNAL
+gboolean spice_smartcard_manager_init_finish(SpiceSession *session,
+ GAsyncResult *result,
+ GError **err)
+{
+ GTask *task = G_TASK(result);
+
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+ g_return_val_if_fail(G_IS_TASK(task), FALSE);
+
+ SPICE_DEBUG("smartcard_manager_finish");
+
+ spice_smartcard_manager_update_monitor();
+
+ return g_task_propagate_boolean(task, err);
+}
+
+/**
+ * spice_smartcard_reader_is_software:
+ * @reader: a #SpiceSmartcardReader
+ *
+ * Tests if @reader is a software (emulated) smartcard reader.
+ *
+ * Returns: TRUE if @reader is a software (emulated) smartcard reader,
+ * FALSE otherwise
+ */
+gboolean spice_smartcard_reader_is_software(SpiceSmartcardReader *reader)
+{
+ g_return_val_if_fail(reader != NULL, FALSE);
+ return (strcmp(vreader_get_name((VReader*)reader), SPICE_SOFTWARE_READER_NAME) == 0);
+}
+
+/**
+ * spice_smartcard_reader_insert_card:
+ * @reader: a #SpiceSmartcardReader
+ *
+ * Simulates insertion of a smartcard in the software smartcard reader
+ * @reader. If @reader is not a software smartcard reader, FALSE will be
+ * returned.
+ *
+ * Returns: TRUE if insertion of a card was successfully simulated, FALSE
+ * otherwise
+ */
+gboolean spice_smartcard_reader_insert_card(SpiceSmartcardReader *reader)
+{
+ VCardEmulError status;
+
+ g_return_val_if_fail(spice_smartcard_reader_is_software(reader), FALSE);
+
+ status = vcard_emul_force_card_insert((VReader *)reader);
+
+ return (status == VCARD_EMUL_OK);
+}
+
+/**
+ * spice_smartcard_reader_remove_card:
+ * @reader: a #SpiceSmartcardReader
+ *
+ * Simulates removal of a smartcard from the software smartcard reader
+ * @reader. If @reader is not a software smartcard reader, FALSE will be
+ * returned.
+ *
+ * Returns: TRUE if removal of a card was successfully simulated, FALSE
+ * otherwise
+ */
+gboolean spice_smartcard_reader_remove_card(SpiceSmartcardReader *reader)
+{
+ VCardEmulError status;
+
+ g_return_val_if_fail(spice_smartcard_reader_is_software(reader), FALSE);
+
+ status = vcard_emul_force_card_remove((VReader *)reader);
+
+ return (status == VCARD_EMUL_OK);
+}
+
+/**
+ * spice_smartcard_manager_get_readers:
+ * @manager: a #SpiceSmartcardManager
+ *
+ * Gets the list of smartcard readers that are currently available, they
+ * can be either software (emulated) readers, or hardware ones.
+ *
+ * Returns: (element-type SpiceSmartcardReader) (transfer full): a newly
+ * allocated list of SpiceSmartcardReader instances, or NULL if none were
+ * found. When no longer needed, the list must be freed after unreferencing
+ * its elements with g_boxed_free()
+ *
+ * Since: 0.20
+ */
+GList *spice_smartcard_manager_get_readers(SpiceSmartcardManager *manager)
+{
+
+ GList *readers = NULL;
+ VReaderList *vreader_list;
+ VReaderListEntry *entry;
+
+ vreader_list = vreader_get_reader_list();
+
+ if (vreader_list == NULL)
+ return NULL;
+
+ for (entry = vreader_list_get_first(vreader_list);
+ entry != NULL;
+ entry = vreader_list_get_next(entry)) {
+ VReader *reader;
+
+ reader = vreader_list_get_reader(entry);
+ g_warn_if_fail(reader != NULL);
+ readers = g_list_prepend(readers, vreader_reference(reader));
+ }
+ vreader_list_delete(vreader_list);
+
+ return g_list_reverse(readers);
+}
+
+/**
+ * spice_smartcard_manager_insert_card:
+ * @manager: a #SpiceSmartcardManager
+ *
+ * Simulates the insertion of a smartcard in the guest. Valid certificates
+ * must have been set in #SpiceSession:smartcard-certificates for software
+ * smartcard support to work. At the moment, only one software smartcard
+ * reader is supported, that's why there is no parameter to indicate which
+ * reader to insert the card in.
+ *
+ * Returns: TRUE if smartcard insertion was successfully simulated, FALSE
+ * if this failed, or if software smartcard support isn't enabled.
+ *
+ * Since: 0.20
+ */
+gboolean spice_smartcard_manager_insert_card(SpiceSmartcardManager *manager)
+{
+ SpiceSmartcardReader *reader;
+
+ g_return_val_if_fail (manager->priv->software_reader != NULL, FALSE);
+
+ reader = (SpiceSmartcardReader *)manager->priv->software_reader;
+
+ return spice_smartcard_reader_insert_card(reader);
+}
+
+/**
+ * spice_smartcard_manager_remove_card:
+ * @manager: a #SpiceSmartcardManager
+ *
+ * Simulates the removal of a smartcard in the guest. At the moment, only
+ * one software smartcard reader is supported, that's why there is no
+ * parameter to indicate which reader to insert the card in.
+ *
+ * Returns: TRUE if smartcard removal was successfully simulated, FALSE
+ * if this failed, or if software smartcard support isn't enabled.
+ *
+ * Since: 0.20
+ */
+gboolean spice_smartcard_manager_remove_card(SpiceSmartcardManager *manager)
+{
+ SpiceSmartcardReader *reader;
+
+ g_return_val_if_fail (manager->priv->software_reader != NULL, FALSE);
+
+ reader = (SpiceSmartcardReader *)manager->priv->software_reader;
+
+ return spice_smartcard_reader_remove_card(reader);
+}
+#else
+gboolean spice_smartcard_reader_is_software(SpiceSmartcardReader *reader)
+{
+ return TRUE;
+}
+
+G_GNUC_INTERNAL
+void spice_smartcard_manager_init_async(SpiceSession *session,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer opaque)
+{
+ SPICE_DEBUG("using fake smartcard backend");
+}
+
+G_GNUC_INTERNAL
+gboolean spice_smartcard_manager_init_finish(SpiceSession *session,
+ GAsyncResult *result,
+ GError **err)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
+ return TRUE;
+}
+
+gboolean spice_smartcard_manager_insert_card(SpiceSmartcardManager *manager)
+{
+ return FALSE;
+}
+
+gboolean spice_smartcard_manager_remove_card(SpiceSmartcardManager *manager)
+{
+ return FALSE;
+}
+
+gboolean spice_smartcard_reader_insert_card(SpiceSmartcardReader *reader)
+{
+ return FALSE;
+}
+
+gboolean spice_smartcard_reader_remove_card(SpiceSmartcardReader *reader)
+{
+ return FALSE;
+}
+
+GList *spice_smartcard_manager_get_readers(SpiceSmartcardManager *manager)
+{
+ return NULL;
+}
+
+#endif /* USE_SMARTCARD */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_SMARTCARD_MANAGER_H__
+#define __SPICE_SMARTCARD_MANAGER_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include "spice-types.h"
+#include "spice-util.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_SMARTCARD_MANAGER (spice_smartcard_manager_get_type ())
+#define SPICE_SMARTCARD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_SMARTCARD_MANAGER, SpiceSmartcardManager))
+#define SPICE_SMARTCARD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_SMARTCARD_MANAGER, SpiceSmartcardManagerClass))
+#define SPICE_IS_SMARTCARD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_SMARTCARD_MANAGER))
+#define SPICE_IS_SMARTCARD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_SMARTCARD_MANAGER))
+#define SPICE_SMARTCARD_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_SMARTCARD_MANAGER, SpiceSmartcardManagerClass))
+
+#define SPICE_TYPE_SMARTCARD_READER (spice_smartcard_reader_get_type())
+
+typedef struct _SpiceSmartcardManager SpiceSmartcardManager;
+typedef struct _SpiceSmartcardManagerClass SpiceSmartcardManagerClass;
+typedef struct _SpiceSmartcardManagerPrivate SpiceSmartcardManagerPrivate;
+
+/**
+ * SpiceSmartcardReader:
+ *
+ * The #SpiceSmartcardReader struct is opaque and cannot be accessed directly.
+ */
+typedef struct _SpiceSmartcardReader SpiceSmartcardReader;
+
+/**
+ * SpiceSmartcardManager:
+ *
+ * The #SpiceSmartcardManager struct is opaque and should not be accessed directly.
+ */
+struct _SpiceSmartcardManager
+{
+ GObject parent;
+
+ /*< private >*/
+ SpiceSmartcardManagerPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpiceSmartcardManagerClass:
+ * @parent_class: Parent class.
+ * @reader_added: Signal class handler for the #SpiceSmartcardManager::reader_added signal.
+ * @reader_removed: Signal class handler for the #SpiceSmartcardManager::reader_removed signal.
+ * @card_inserted: Signal class handler for the #SpiceSmartcardManager::card_inserted signal.
+ * @card_removed: Signal class handler for the #SpiceSmartcardManager::card_removed signal.
+ *
+ * Class structure for #SpiceSmartcardManager.
+ */
+struct _SpiceSmartcardManagerClass
+{
+ GObjectClass parent_class;
+ /*< public >*/
+ /* signals */
+ void (*reader_added)(SpiceSmartcardManager *manager, SpiceSmartcardReader *reader);
+ void (*reader_removed)(SpiceSmartcardManager *manager, SpiceSmartcardReader *reader);
+ void (*card_inserted)(SpiceSmartcardManager *manager, SpiceSmartcardReader *reader);
+ void (*card_removed)(SpiceSmartcardManager *manager, SpiceSmartcardReader *reader );
+
+ /*< private >*/
+ /*
+ * If adding fields to this struct, remove corresponding
+ * amount of padding to avoid changing overall struct size
+ */
+ gchar _spice_reserved[SPICE_RESERVED_PADDING];
+};
+
+GType spice_smartcard_manager_get_type(void);
+GType spice_smartcard_reader_get_type(void);
+
+SpiceSmartcardManager *spice_smartcard_manager_get(void);
+gboolean spice_smartcard_manager_insert_card(SpiceSmartcardManager *manager);
+gboolean spice_smartcard_manager_remove_card(SpiceSmartcardManager *manager);
+gboolean spice_smartcard_reader_is_software(SpiceSmartcardReader *reader);
+gboolean spice_smartcard_reader_insert_card(SpiceSmartcardReader *reader);
+gboolean spice_smartcard_reader_remove_card(SpiceSmartcardReader *reader);
+GList *spice_smartcard_manager_get_readers(SpiceSmartcardManager *manager);
+
+G_END_DECLS
+
+#endif /* __SPICE_SMARTCARD_MANAGER_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_AUDIO_PRIVATE_H__
+#define __SPICE_AUDIO_PRIVATE_H__
+
+#include <glib.h>
+#include <gio/gio.h>
+#include "spice-session.h"
+
+G_BEGIN_DECLS
+
+struct _SpiceAudioPrivate {
+ SpiceSession *session;
+ GMainContext *main_context;
+};
+
+void spice_audio_get_playback_volume_info_async(SpiceAudio *audio, GCancellable *cancellable,
+ SpiceMainChannel *main_channel, GAsyncReadyCallback callback, gpointer user_data);
+gboolean spice_audio_get_playback_volume_info_finish(SpiceAudio *audio, GAsyncResult *res,
+ gboolean *mute, guint8 *nchannels, guint16 **volume, GError **error);
+void spice_audio_get_record_volume_info_async(SpiceAudio *audio, GCancellable *cancellable,
+ SpiceMainChannel *main_channel, GAsyncReadyCallback callback, gpointer user_data);
+gboolean spice_audio_get_record_volume_info_finish(SpiceAudio *audio, GAsyncResult *res,
+ gboolean *mute, guint8 *nchannels, guint16 **volume, GError **error);
+G_END_DECLS
+
+#endif /* __SPICE_AUDIO_PRIVATE_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * simple audio init dispatcher
+ */
+
+/**
+ * SECTION:spice-audio
+ * @short_description: a helper to play and to record audio channels
+ * @title: Spice Audio
+ * @section_id:
+ * @see_also: #SpiceRecordChannel, and #SpicePlaybackChannel
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * A class that handles the playback and record channels for your
+ * application, and connect them to the default sound system.
+ */
+
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+
+#include "spice-audio.h"
+#include "spice-session-priv.h"
+#include "spice-channel-priv.h"
+#include "spice-audio-priv.h"
+
+#ifdef HAVE_PULSE
+#include "spice-pulse.h"
+#endif
+#ifdef HAVE_GSTAUDIO
+#include "spice-gstaudio.h"
+#endif
+
+#define SPICE_AUDIO_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SPICE_TYPE_AUDIO, SpiceAudioPrivate))
+
+G_DEFINE_ABSTRACT_TYPE(SpiceAudio, spice_audio, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_SESSION,
+ PROP_MAIN_CONTEXT,
+};
+
+static void spice_audio_finalize(GObject *gobject)
+{
+ SpiceAudio *self = SPICE_AUDIO(gobject);
+ SpiceAudioPrivate *priv = self->priv;
+
+ g_clear_pointer(&priv->main_context, g_main_context_unref);
+
+ if (G_OBJECT_CLASS(spice_audio_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_audio_parent_class)->finalize(gobject);
+}
+
+static void spice_audio_get_property(GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceAudio *self = SPICE_AUDIO(gobject);
+ SpiceAudioPrivate *priv = self->priv;
+
+ switch (prop_id) {
+ case PROP_SESSION:
+ g_value_set_object(value, priv->session);
+ break;
+ case PROP_MAIN_CONTEXT:
+ g_value_set_boxed(value, priv->main_context);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_audio_set_property(GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceAudio *self = SPICE_AUDIO(gobject);
+ SpiceAudioPrivate *priv = self->priv;
+
+ switch (prop_id) {
+ case PROP_SESSION:
+ priv->session = g_value_get_object(value);
+ break;
+ case PROP_MAIN_CONTEXT:
+ priv->main_context = g_value_dup_boxed(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_audio_class_init(SpiceAudioClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GParamSpec *pspec;
+
+ gobject_class->finalize = spice_audio_finalize;
+ gobject_class->get_property = spice_audio_get_property;
+ gobject_class->set_property = spice_audio_set_property;
+
+ /**
+ * SpiceAudio:session:
+ *
+ * #SpiceSession this #SpiceAudio is associated with
+ *
+ **/
+ pspec = g_param_spec_object("session", "Session", "SpiceSession",
+ SPICE_TYPE_SESSION,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property(gobject_class, PROP_SESSION, pspec);
+
+ /**
+ * SpiceAudio:main-context:
+ */
+ pspec = g_param_spec_boxed("main-context", "Main Context",
+ "GMainContext to use for the event source",
+ G_TYPE_MAIN_CONTEXT,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property(gobject_class, PROP_MAIN_CONTEXT, pspec);
+
+ g_type_class_add_private(klass, sizeof(SpiceAudioPrivate));
+}
+
+static void spice_audio_init(SpiceAudio *self)
+{
+ self->priv = SPICE_AUDIO_GET_PRIVATE(self);
+}
+
+static void connect_channel(SpiceAudio *self, SpiceChannel *channel)
+{
+ if (channel->priv->state != SPICE_CHANNEL_STATE_UNCONNECTED)
+ return;
+
+ if (SPICE_AUDIO_GET_CLASS(self)->connect_channel(self, channel))
+ spice_channel_connect(channel);
+}
+
+static void update_audio_channels(SpiceAudio *self, SpiceSession *session)
+{
+ GList *list, *tmp;
+
+ if (!spice_session_get_audio_enabled(session)) {
+ SPICE_DEBUG("FIXME: disconnect audio channels");
+ return;
+ }
+
+ list = spice_session_get_channels(session);
+ for (tmp = g_list_first(list); tmp != NULL; tmp = g_list_next(tmp)) {
+ connect_channel(self, tmp->data);
+ }
+ g_list_free(list);
+}
+
+static void channel_new(SpiceSession *session, SpiceChannel *channel, SpiceAudio *self)
+{
+ connect_channel(self, channel);
+}
+
+static void session_enable_audio(GObject *gobject, GParamSpec *pspec,
+ gpointer user_data)
+{
+ update_audio_channels(SPICE_AUDIO(user_data), SPICE_SESSION(gobject));
+}
+
+void spice_audio_get_playback_volume_info_async(SpiceAudio *audio,
+ GCancellable *cancellable,
+ SpiceMainChannel *main_channel,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail(audio != NULL);
+ SPICE_AUDIO_GET_CLASS(audio)->get_playback_volume_info_async(audio,
+ cancellable, main_channel, callback, user_data);
+}
+
+gboolean spice_audio_get_playback_volume_info_finish(SpiceAudio *audio,
+ GAsyncResult *res,
+ gboolean *mute,
+ guint8 *nchannels,
+ guint16 **volume,
+ GError **error)
+{
+ g_return_val_if_fail(audio != NULL, FALSE);
+ return SPICE_AUDIO_GET_CLASS(audio)->get_playback_volume_info_finish(audio,
+ res, mute, nchannels, volume, error);
+}
+
+void spice_audio_get_record_volume_info_async(SpiceAudio *audio,
+ GCancellable *cancellable,
+ SpiceMainChannel *main_channel,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail(audio != NULL);
+ SPICE_AUDIO_GET_CLASS(audio)->get_record_volume_info_async(audio,
+ cancellable, main_channel, callback, user_data);
+}
+
+gboolean spice_audio_get_record_volume_info_finish(SpiceAudio *audio,
+ GAsyncResult *res,
+ gboolean *mute,
+ guint8 *nchannels,
+ guint16 **volume,
+ GError **error)
+{
+ g_return_val_if_fail(audio != NULL, FALSE);
+ return SPICE_AUDIO_GET_CLASS(audio)->get_record_volume_info_finish(audio,
+ res, mute, nchannels, volume, error);
+}
+
+/**
+ * spice_audio_new:
+ * @session: the #SpiceSession to connect to
+ * @context: (allow-none): a #GMainContext to attach to (or %NULL for
+ * default).
+ * @name: (allow-none): a name for the audio channels (or %NULL for
+ * application name).
+ *
+ * Once instantiated, #SpiceAudio will handle the playback and record
+ * channels to stream to your local audio system.
+ *
+ * Returns: a new #SpiceAudio instance or %NULL if no backend or failed.
+ * Deprecated: 0.8: Use spice_audio_get() instead
+ **/
+SpiceAudio *spice_audio_new(SpiceSession *session, GMainContext *context,
+ const char *name)
+{
+ SpiceAudio *self = NULL;
+
+ if (context == NULL)
+ context = g_main_context_default();
+ if (name == NULL)
+ name = g_get_application_name();
+
+#ifdef HAVE_PULSE
+ self = SPICE_AUDIO(spice_pulse_new(session, context, name));
+#endif
+#ifdef HAVE_GSTAUDIO
+ if (!self)
+ self = SPICE_AUDIO(spice_gstaudio_new(session, context, name));
+#endif
+ if (!self)
+ return NULL;
+
+ spice_g_signal_connect_object(session, "notify::enable-audio", G_CALLBACK(session_enable_audio), self, 0);
+ spice_g_signal_connect_object(session, "channel-new", G_CALLBACK(channel_new), self, G_CONNECT_AFTER);
+ update_audio_channels(self, session);
+
+ return self;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_AUDIO_H__
+#define __SPICE_CLIENT_AUDIO_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include <glib-object.h>
+#include <gio/gio.h>
+#include "spice-util.h"
+#include "spice-session.h"
+#include "channel-main.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_AUDIO spice_audio_get_type()
+
+#define SPICE_AUDIO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_AUDIO, SpiceAudio))
+
+#define SPICE_AUDIO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_AUDIO, SpiceAudioClass))
+
+#define SPICE_IS_AUDIO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_AUDIO))
+
+#define SPICE_IS_AUDIO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_AUDIO))
+
+#define SPICE_AUDIO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_AUDIO, SpiceAudioClass))
+
+typedef struct _SpiceAudio SpiceAudio;
+typedef struct _SpiceAudioClass SpiceAudioClass;
+typedef struct _SpiceAudioPrivate SpiceAudioPrivate;
+
+/**
+ * SpiceAudio:
+ *
+ * The #SpiceAudio struct is opaque and should not be accessed directly.
+ */
+struct _SpiceAudio {
+ GObject parent;
+
+ SpiceAudioPrivate *priv;
+};
+
+/**
+ * SpiceAudioClass:
+ * @parent_class: Parent class.
+ *
+ * Class structure for #SpiceAudio.
+ */
+struct _SpiceAudioClass {
+ GObjectClass parent_class;
+
+ /*< private >*/
+ gboolean (*connect_channel)(SpiceAudio *audio, SpiceChannel *channel);
+ void (*get_playback_volume_info_async)(SpiceAudio *audio,
+ GCancellable *cancellable,
+ SpiceMainChannel *main_channel,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*get_playback_volume_info_finish)(SpiceAudio *audio,
+ GAsyncResult *res,
+ gboolean *mute,
+ guint8 *nchannels,
+ guint16 **volume,
+ GError **error);
+ void (*get_record_volume_info_async)(SpiceAudio *audio,
+ GCancellable *cancellable,
+ SpiceMainChannel *main_channel,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*get_record_volume_info_finish)(SpiceAudio *audio,
+ GAsyncResult *res,
+ gboolean *mute,
+ guint8 *nchannels,
+ guint16 **volume,
+ GError **error);
+
+ gchar _spice_reserved[SPICE_RESERVED_PADDING - 4 * sizeof(void *)];
+};
+
+GType spice_audio_get_type(void);
+
+SpiceAudio* spice_audio_get(SpiceSession *session, GMainContext *context);
+
+#ifndef SPICE_DISABLE_DEPRECATED
+SPICE_DEPRECATED_FOR(spice_audio_get)
+SpiceAudio* spice_audio_new(SpiceSession *session, GMainContext *context, const char *name);
+#endif
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_AUDIO_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef SPICE_CHANNEL_CACHE_H_
+# define SPICE_CHANNEL_CACHE_H_
+
+#include <inttypes.h> /* For PRIx64 */
+#include "common/mem.h"
+#include "common/ring.h"
+
+G_BEGIN_DECLS
+
+typedef struct display_cache_item {
+ guint64 id;
+ gboolean lossy;
+ guint32 ref_count;
+} display_cache_item;
+
+typedef struct display_cache {
+ GHashTable *table;
+ gboolean ref_counted;
+}display_cache;
+
+static inline display_cache_item* cache_item_new(guint64 id, gboolean lossy)
+{
+ display_cache_item *self = g_new(display_cache_item, 1);
+ self->id = id;
+ self->lossy = lossy;
+ self->ref_count = 1;
+ return self;
+}
+
+static inline void cache_item_free(display_cache_item *self)
+{
+ g_free(self);
+}
+
+static inline display_cache* cache_new(GDestroyNotify value_destroy)
+{
+ display_cache * self = g_new(display_cache, 1);
+ self->table = g_hash_table_new_full(g_int64_hash, g_int64_equal,
+ (GDestroyNotify) cache_item_free,
+ value_destroy);
+ self->ref_counted = FALSE;
+ return self;
+}
+
+static inline display_cache * cache_image_new(GDestroyNotify value_destroy)
+{
+ display_cache * self = cache_new(value_destroy);
+ self->ref_counted = TRUE;
+ return self;
+};
+
+static inline gpointer cache_find(display_cache *cache, uint64_t id)
+{
+ return g_hash_table_lookup(cache->table, &id);
+}
+
+static inline gpointer cache_find_lossy(display_cache *cache, uint64_t id, gboolean *lossy)
+{
+ gpointer value;
+ display_cache_item *item;
+
+ if (!g_hash_table_lookup_extended(cache->table, &id, (gpointer*)&item, &value))
+ return NULL;
+
+ *lossy = item->lossy;
+
+ return value;
+}
+
+static inline void cache_add_lossy(display_cache *cache, uint64_t id,
+ gpointer value, gboolean lossy)
+{
+ display_cache_item *item = cache_item_new(id, lossy);
+ display_cache_item *current_item;
+ gpointer current_image;
+
+ //If image is currently in the table add its reference count before replacing it
+ if(cache->ref_counted) {
+ if(g_hash_table_lookup_extended(cache->table, &id, (gpointer*) ¤t_item,
+ (gpointer*) ¤t_image)) {
+ item->ref_count = current_item->ref_count + 1;
+ }
+ }
+ g_hash_table_replace(cache->table, item, value);
+}
+
+static inline void cache_add(display_cache *cache, uint64_t id, gpointer value)
+{
+ cache_add_lossy(cache, id, value, FALSE);
+}
+
+static inline gboolean cache_remove(display_cache *cache, uint64_t id)
+{
+ display_cache_item * item;
+ gpointer value;
+
+ if( g_hash_table_lookup_extended(cache->table, &id, (gpointer*) &item, &value)) {
+ --item->ref_count;
+ if(!cache->ref_counted || item->ref_count == 0 ) {
+ return g_hash_table_remove(cache->table, &id);
+ }
+ }
+ else {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static inline void cache_clear(display_cache *cache)
+{
+ g_hash_table_remove_all(cache->table);
+}
+
+static inline void cache_free(display_cache *cache)
+{
+ g_hash_table_unref(cache->table);
+ g_free(cache);
+}
+
+G_END_DECLS
+
+#endif // SPICE_CHANNEL_CACHE_H_
--- /dev/null
+#ifndef SPICE_CHANNEL_ENUMS_H
+#define SPICE_CHANNEL_ENUMS_H
+
+#warning "deprecated: please include spice-glib-enums.h"
+#include "spice-glib-enums.h"
+
+#endif /* SPICE_CHANNEL_ENUMS_H */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_CHANNEL_PRIV_H__
+#define __SPICE_CLIENT_CHANNEL_PRIV_H__
+
+#include "config.h"
+
+#include <openssl/ssl.h>
+#include <gio/gio.h>
+
+#if HAVE_SASL
+#include <sasl/sasl.h>
+#endif
+
+#include "spice-channel.h"
+#include "spice-util-priv.h"
+#include "coroutine.h"
+#include "gio-coroutine.h"
+
+#include "common/client_marshallers.h"
+#include "common/client_demarshallers.h"
+#include "common/ssl_verify.h"
+
+G_BEGIN_DECLS
+
+#define MAX_SPICE_DATA_HEADER_SIZE sizeof(SpiceDataHeader)
+
+#define CHANNEL_DEBUG(channel, fmt, ...) \
+ SPICE_DEBUG("%s: " fmt, SPICE_CHANNEL(channel)->priv->name, ## __VA_ARGS__)
+
+struct _SpiceMsgOut {
+ int refcount;
+ SpiceChannel *channel;
+ SpiceMessageMarshallers *marshallers;
+ SpiceMarshaller *marshaller;
+ uint8_t *header;
+ gboolean ro_check;
+};
+
+struct _SpiceMsgIn {
+ int refcount;
+ SpiceChannel *channel;
+ uint8_t header[MAX_SPICE_DATA_HEADER_SIZE];
+ uint8_t *data;
+ int dpos;
+ uint8_t *parsed;
+ size_t psize;
+ message_destructor_t pfree;
+ SpiceMsgIn *parent;
+};
+
+enum spice_channel_state {
+ SPICE_CHANNEL_STATE_UNCONNECTED = 0,
+ SPICE_CHANNEL_STATE_RECONNECTING,
+ SPICE_CHANNEL_STATE_CONNECTING,
+ SPICE_CHANNEL_STATE_READY,
+ SPICE_CHANNEL_STATE_SWITCHING,
+ SPICE_CHANNEL_STATE_MIGRATING,
+ SPICE_CHANNEL_STATE_MIGRATION_HANDSHAKE,
+};
+
+struct _SpiceChannelClassPrivate
+{
+ GArray *handlers;
+};
+
+struct _SpiceChannelPrivate {
+ /* swapped on migration */
+ SSL_CTX *ctx;
+ SSL *ssl;
+ SpiceOpenSSLVerify *sslverify;
+ GSocket *sock;
+ GSocketConnection *conn;
+ GInputStream *in;
+ GOutputStream *out;
+
+#if HAVE_SASL
+ sasl_conn_t *sasl_conn;
+ const char *sasl_decoded;
+ unsigned int sasl_decoded_length;
+ unsigned int sasl_decoded_offset;
+#endif
+
+ gboolean use_mini_header;
+ uint64_t out_serial;
+ uint64_t in_serial;
+
+ /* not swapped */
+ SpiceSession *session;
+ GCoroutine coroutine;
+ int fd;
+ gboolean has_error;
+ guint connect_delayed_id;
+
+ GQueue xmit_queue;
+ gboolean xmit_queue_blocked;
+ GMutex xmit_queue_lock;
+ guint xmit_queue_wakeup_id;
+ guint64 xmit_queue_size;
+
+ char name[16];
+ enum spice_channel_state state;
+ SpiceChannelEvent event;
+
+ spice_parse_channel_func_t parser;
+ SpiceMessageMarshallers *marshallers;
+ guint channel_watch;
+ int tls;
+
+ int channel_id;
+ int channel_type;
+ SpiceLinkHeader link_hdr;
+ SpiceLinkMess link_msg;
+ SpiceLinkHeader peer_hdr;
+ SpiceLinkReply* peer_msg;
+ int peer_pos;
+
+ int message_ack_window;
+ int message_ack_count;
+
+ GArray *caps;
+ GArray *common_caps;
+ GArray *remote_caps;
+ GArray *remote_common_caps;
+
+ gsize total_read_bytes;
+ uint64_t last_message_serial;
+ GSList *flushing;
+
+ gboolean disable_channel_msg;
+ gboolean auth_needs_username;
+ gboolean auth_needs_password;
+ GError *error;
+};
+
+SpiceMsgIn *spice_msg_in_new(SpiceChannel *channel);
+SpiceMsgIn *spice_msg_in_sub_new(SpiceChannel *channel, SpiceMsgIn *parent,
+ SpiceSubMessage *sub);
+void spice_msg_in_ref(SpiceMsgIn *in);
+void spice_msg_in_unref(SpiceMsgIn *in);
+int spice_msg_in_type(SpiceMsgIn *in);
+void *spice_msg_in_parsed(SpiceMsgIn *in);
+void *spice_msg_in_raw(SpiceMsgIn *in, int *len);
+void spice_msg_in_hexdump(SpiceMsgIn *in);
+
+SpiceMsgOut *spice_msg_out_new(SpiceChannel *channel, int type);
+void spice_msg_out_ref(SpiceMsgOut *out);
+void spice_msg_out_unref(SpiceMsgOut *out);
+void spice_msg_out_send(SpiceMsgOut *out);
+void spice_msg_out_send_internal(SpiceMsgOut *out);
+void spice_msg_out_hexdump(SpiceMsgOut *out, unsigned char *data, int len);
+
+uint16_t spice_header_get_msg_type(uint8_t *header, gboolean is_mini_header);
+uint32_t spice_header_get_msg_size(uint8_t *header, gboolean is_mini_header);
+
+void spice_channel_up(SpiceChannel *channel);
+void spice_channel_wakeup(SpiceChannel *channel, gboolean cancel);
+
+SpiceSession* spice_channel_get_session(SpiceChannel *channel);
+enum spice_channel_state spice_channel_get_state(SpiceChannel *channel);
+guint64 spice_channel_get_queue_size (SpiceChannel *channel);
+
+/* coroutine context */
+typedef void (*handler_msg_in)(SpiceChannel *channel, SpiceMsgIn *msg, gpointer data);
+void spice_channel_recv_msg(SpiceChannel *channel, handler_msg_in handler, gpointer data);
+
+/* channel-base.c */
+void spice_channel_set_handlers(SpiceChannelClass *klass,
+ const spice_msg_handler* handlers, const int n);
+void spice_channel_handle_wait_for_channels(SpiceChannel *channel, SpiceMsgIn *in);
+
+gint spice_channel_get_channel_id(SpiceChannel *channel);
+gint spice_channel_get_channel_type(SpiceChannel *channel);
+void spice_channel_swap(SpiceChannel *channel, SpiceChannel *swap, gboolean swap_msgs);
+gboolean spice_channel_get_read_only(SpiceChannel *channel);
+void spice_channel_reset(SpiceChannel *channel, gboolean migrating);
+
+void spice_caps_set(GArray *caps, guint32 cap, const gchar *desc);
+#define spice_channel_set_common_capability(channel, cap) \
+ spice_caps_set(SPICE_CHANNEL(channel)->priv->common_caps, cap, #cap)
+#define spice_channel_set_capability(channel, cap) \
+ spice_caps_set(SPICE_CHANNEL(channel)->priv->caps, cap, #cap)
+
+gchar *spice_channel_supported_string(void);
+
+void spice_vmc_write_async(SpiceChannel *self,
+ const void *buffer, gsize count,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gssize spice_vmc_write_finish(SpiceChannel *self,
+ GAsyncResult *result, GError **error);
+#ifdef G_OS_UNIX
+gint spice_channel_unix_read_fd(SpiceChannel *channel);
+#endif
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_CHANNEL_PRIV_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+
+#include "spice-channel-priv.h"
+#include "spice-session-priv.h"
+#include "spice-marshal.h"
+#include "bio-gio.h"
+
+#include <glib/gi18n-lib.h>
+
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#include <netinet/tcp.h> // TCP_NODELAY
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <ctype.h>
+
+#include "gio-coroutine.h"
+
+static void spice_channel_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg);
+static void spice_channel_write_msg(SpiceChannel *channel, SpiceMsgOut *out);
+static void spice_channel_send_link(SpiceChannel *channel);
+static void channel_reset(SpiceChannel *channel, gboolean migrating);
+static void spice_channel_reset_capabilities(SpiceChannel *channel);
+static void spice_channel_send_migration_handshake(SpiceChannel *channel);
+static gboolean channel_connect(SpiceChannel *channel, gboolean tls);
+
+/**
+ * SECTION:spice-channel
+ * @short_description: the base channel class
+ * @title: Spice Channel
+ * @section_id:
+ * @see_also: #SpiceSession, #SpiceMainChannel and other channels
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * #SpiceChannel is the base class for the different kind of Spice
+ * channel connections, such as #SpiceMainChannel, or
+ * #SpiceInputsChannel.
+ */
+
+/* ------------------------------------------------------------------ */
+/* gobject glue */
+
+#define SPICE_CHANNEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SPICE_TYPE_CHANNEL, SpiceChannelPrivate))
+
+G_DEFINE_TYPE_WITH_CODE (SpiceChannel, spice_channel, G_TYPE_OBJECT,
+ g_type_add_class_private (g_define_type_id, sizeof (SpiceChannelClassPrivate)));
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_SESSION,
+ PROP_CHANNEL_TYPE,
+ PROP_CHANNEL_ID,
+ PROP_TOTAL_READ_BYTES,
+ PROP_SOCKET,
+};
+
+/* Signals */
+enum {
+ SPICE_CHANNEL_EVENT,
+ SPICE_CHANNEL_OPEN_FD,
+
+ SPICE_CHANNEL_LAST_SIGNAL,
+};
+
+static guint signals[SPICE_CHANNEL_LAST_SIGNAL];
+
+static void spice_channel_iterate_write(SpiceChannel *channel);
+static void spice_channel_iterate_read(SpiceChannel *channel);
+
+static void spice_channel_init(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c;
+
+ c = channel->priv = SPICE_CHANNEL_GET_PRIVATE(channel);
+
+ c->out_serial = 1;
+ c->in_serial = 1;
+ c->fd = -1;
+ c->auth_needs_username = FALSE;
+ c->auth_needs_password = FALSE;
+ strcpy(c->name, "?");
+ c->caps = g_array_new(FALSE, TRUE, sizeof(guint32));
+ c->common_caps = g_array_new(FALSE, TRUE, sizeof(guint32));
+ c->remote_caps = g_array_new(FALSE, TRUE, sizeof(guint32));
+ c->remote_common_caps = g_array_new(FALSE, TRUE, sizeof(guint32));
+ spice_channel_set_common_capability(channel, SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION);
+ spice_channel_set_common_capability(channel, SPICE_COMMON_CAP_MINI_HEADER);
+#ifdef HAVE_SASL
+ spice_channel_set_common_capability(channel, SPICE_COMMON_CAP_AUTH_SASL);
+#endif
+ g_queue_init(&c->xmit_queue);
+ g_mutex_init(&c->xmit_queue_lock);
+}
+
+static void spice_channel_constructed(GObject *gobject)
+{
+ SpiceChannel *channel = SPICE_CHANNEL(gobject);
+ SpiceChannelPrivate *c = channel->priv;
+ const char *desc = spice_channel_type_to_string(c->channel_type);
+
+ snprintf(c->name, sizeof(c->name), "%s-%d:%d",
+ desc, c->channel_type, c->channel_id);
+ CHANNEL_DEBUG(channel, "%s", __FUNCTION__);
+
+ const char *disabled = g_getenv("SPICE_DISABLE_CHANNELS");
+ if (disabled && strstr(disabled, desc))
+ c->disable_channel_msg = TRUE;
+
+ spice_session_channel_new(c->session, channel);
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_channel_parent_class)->constructed)
+ G_OBJECT_CLASS(spice_channel_parent_class)->constructed(gobject);
+}
+
+static void spice_channel_dispose(GObject *gobject)
+{
+ SpiceChannel *channel = SPICE_CHANNEL(gobject);
+ SpiceChannelPrivate *c = channel->priv;
+
+ CHANNEL_DEBUG(channel, "%s %p", __FUNCTION__, gobject);
+
+ spice_channel_disconnect(channel, SPICE_CHANNEL_CLOSED);
+
+ g_clear_object(&c->session);
+
+ g_clear_error(&c->error);
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_channel_parent_class)->dispose)
+ G_OBJECT_CLASS(spice_channel_parent_class)->dispose(gobject);
+}
+
+static void spice_channel_finalize(GObject *gobject)
+{
+ SpiceChannel *channel = SPICE_CHANNEL(gobject);
+ SpiceChannelPrivate *c = channel->priv;
+
+ CHANNEL_DEBUG(channel, "%s %p", __FUNCTION__, gobject);
+
+ g_idle_remove_by_data(gobject);
+
+ g_mutex_clear(&c->xmit_queue_lock);
+
+ if (c->caps)
+ g_array_free(c->caps, TRUE);
+
+ if (c->common_caps)
+ g_array_free(c->common_caps, TRUE);
+
+ if (c->remote_caps)
+ g_array_free(c->remote_caps, TRUE);
+
+ if (c->remote_common_caps)
+ g_array_free(c->remote_common_caps, TRUE);
+
+ g_clear_pointer(&c->peer_msg, g_free);
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_channel_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_channel_parent_class)->finalize(gobject);
+}
+
+static void spice_channel_get_property(GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceChannel *channel = SPICE_CHANNEL(gobject);
+ SpiceChannelPrivate *c = channel->priv;
+
+ switch (prop_id) {
+ case PROP_SESSION:
+ g_value_set_object(value, c->session);
+ break;
+ case PROP_CHANNEL_TYPE:
+ g_value_set_int(value, c->channel_type);
+ break;
+ case PROP_CHANNEL_ID:
+ g_value_set_int(value, c->channel_id);
+ break;
+ case PROP_TOTAL_READ_BYTES:
+ g_value_set_ulong(value, c->total_read_bytes);
+ break;
+ case PROP_SOCKET:
+ g_value_set_object(value, c->sock);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+G_GNUC_INTERNAL
+gint spice_channel_get_channel_id(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+
+ g_return_val_if_fail(c != NULL, 0);
+ return c->channel_id;
+}
+
+G_GNUC_INTERNAL
+gint spice_channel_get_channel_type(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+
+ g_return_val_if_fail(c != NULL, 0);
+ return c->channel_type;
+}
+
+static void spice_channel_set_property(GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceChannel *channel = SPICE_CHANNEL(gobject);
+ SpiceChannelPrivate *c = channel->priv;
+
+ switch (prop_id) {
+ case PROP_SESSION:
+ c->session = g_value_dup_object(value);
+ break;
+ case PROP_CHANNEL_TYPE:
+ c->channel_type = g_value_get_int(value);
+ break;
+ case PROP_CHANNEL_ID:
+ c->channel_id = g_value_get_int(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_channel_class_init(SpiceChannelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ klass->iterate_write = spice_channel_iterate_write;
+ klass->iterate_read = spice_channel_iterate_read;
+ klass->channel_reset = channel_reset;
+
+ gobject_class->constructed = spice_channel_constructed;
+ gobject_class->dispose = spice_channel_dispose;
+ gobject_class->finalize = spice_channel_finalize;
+ gobject_class->get_property = spice_channel_get_property;
+ gobject_class->set_property = spice_channel_set_property;
+ klass->handle_msg = spice_channel_handle_msg;
+
+ g_object_class_install_property
+ (gobject_class, PROP_SESSION,
+ g_param_spec_object("spice-session",
+ "Spice session",
+ "Spice session",
+ SPICE_TYPE_SESSION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_CHANNEL_TYPE,
+ g_param_spec_int("channel-type",
+ "Channel type",
+ "Channel type",
+ -1, INT_MAX, -1,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_CHANNEL_ID,
+ g_param_spec_int("channel-id",
+ "Channel ID",
+ "Channel ID",
+ -1, INT_MAX, -1,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_TOTAL_READ_BYTES,
+ g_param_spec_ulong("total-read-bytes",
+ "Total read bytes",
+ "Total read bytes",
+ 0, G_MAXULONG, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceChannel:socket:
+ *
+ * Get the underlying #GSocket. Note that you should not read or
+ * write any data to it directly since this will likely corrupt
+ * the channel stream. This property is mainly useful to get some
+ * connections details.
+ *
+ * Since: 0.33
+ */
+ g_object_class_install_property
+ (gobject_class, PROP_SOCKET,
+ g_param_spec_object("socket",
+ "Socket",
+ "Underlying GSocket",
+ G_TYPE_SOCKET,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceChannel::channel-event:
+ * @channel: the channel that emitted the signal
+ * @event: a #SpiceChannelEvent
+ *
+ * The #SpiceChannel::channel-event signal is emitted when the
+ * state of the connection is changed. In case of errors,
+ * spice_channel_get_error() may provide additional informations
+ * on the source of the error.
+ **/
+ signals[SPICE_CHANNEL_EVENT] =
+ g_signal_new("channel-event",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceChannelClass, channel_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE,
+ 1,
+ SPICE_TYPE_CHANNEL_EVENT);
+
+ /**
+ * SpiceChannel::open-fd:
+ * @channel: the channel that emitted the signal
+ * @with_tls: wether TLS connection is requested
+ *
+ * The #SpiceChannel::open-fd signal is emitted when a new
+ * connection is requested. This signal is emitted when the
+ * connection is made with spice_session_open_fd().
+ **/
+ signals[SPICE_CHANNEL_OPEN_FD] =
+ g_signal_new("open-fd",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceChannelClass, open_fd),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+
+ g_type_class_add_private(klass, sizeof(SpiceChannelPrivate));
+
+ SSL_library_init();
+ SSL_load_error_strings();
+}
+
+/* ---------------------------------------------------------------- */
+/* private header api */
+
+static inline void spice_header_set_msg_type(uint8_t *header, gboolean is_mini_header,
+ uint16_t type)
+{
+ if (is_mini_header) {
+ ((SpiceMiniDataHeader *)header)->type = GUINT16_TO_LE(type);
+ } else {
+ ((SpiceDataHeader *)header)->type = GUINT16_TO_LE(type);
+ }
+}
+
+static inline void spice_header_set_msg_size(uint8_t *header, gboolean is_mini_header,
+ uint32_t size)
+{
+ if (is_mini_header) {
+ ((SpiceMiniDataHeader *)header)->size = GUINT32_TO_LE(size);
+ } else {
+ ((SpiceDataHeader *)header)->size = GUINT32_TO_LE(size);
+ }
+}
+
+G_GNUC_INTERNAL
+uint16_t spice_header_get_msg_type(uint8_t *header, gboolean is_mini_header)
+{
+ if (is_mini_header) {
+ return GUINT16_FROM_LE(((SpiceMiniDataHeader *)header)->type);
+ } else {
+ return GUINT16_FROM_LE(((SpiceDataHeader *)header)->type);
+ }
+}
+
+G_GNUC_INTERNAL
+uint32_t spice_header_get_msg_size(uint8_t *header, gboolean is_mini_header)
+{
+ if (is_mini_header) {
+ return GUINT32_FROM_LE(((SpiceMiniDataHeader *)header)->size);
+ } else {
+ return GUINT32_FROM_LE(((SpiceDataHeader *)header)->size);
+ }
+}
+
+static inline int spice_header_get_header_size(gboolean is_mini_header)
+{
+ return is_mini_header ? sizeof(SpiceMiniDataHeader) : sizeof(SpiceDataHeader);
+}
+
+static inline void spice_header_set_msg_serial(uint8_t *header, gboolean is_mini_header,
+ uint64_t serial)
+{
+ if (!is_mini_header) {
+ ((SpiceDataHeader *)header)->serial = GUINT64_TO_LE(serial);
+ }
+}
+
+static inline void spice_header_reset_msg_sub_list(uint8_t *header, gboolean is_mini_header)
+{
+ if (!is_mini_header) {
+ ((SpiceDataHeader *)header)->sub_list = 0;
+ }
+}
+
+static inline uint64_t spice_header_get_in_msg_serial(SpiceMsgIn *in)
+{
+ SpiceChannelPrivate *c = in->channel->priv;
+ uint8_t *header = in->header;
+
+ if (c->use_mini_header) {
+ return c->in_serial;
+ } else {
+ return ((SpiceDataHeader *)header)->serial;
+ }
+}
+
+static inline uint64_t spice_header_get_out_msg_serial(SpiceMsgOut *out)
+{
+ SpiceChannelPrivate *c = out->channel->priv;
+
+ if (c->use_mini_header) {
+ return c->out_serial;
+ } else {
+ return ((SpiceDataHeader *)out->header)->serial;
+ }
+}
+
+static inline uint32_t spice_header_get_msg_sub_list(uint8_t *header, gboolean is_mini_header)
+{
+ if (is_mini_header) {
+ return 0;
+ } else {
+ return GUINT32_FROM_LE(((SpiceDataHeader *)header)->sub_list);
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* private msg api */
+
+G_GNUC_INTERNAL
+SpiceMsgIn *spice_msg_in_new(SpiceChannel *channel)
+{
+ SpiceMsgIn *in;
+
+ g_return_val_if_fail(channel != NULL, NULL);
+
+ in = g_new0(SpiceMsgIn, 1);
+ in->refcount = 1;
+ in->channel = channel;
+
+ return in;
+}
+
+G_GNUC_INTERNAL
+SpiceMsgIn *spice_msg_in_sub_new(SpiceChannel *channel, SpiceMsgIn *parent,
+ SpiceSubMessage *sub)
+{
+ SpiceMsgIn *in;
+
+ g_return_val_if_fail(channel != NULL, NULL);
+
+ in = spice_msg_in_new(channel);
+ spice_header_set_msg_type(in->header, channel->priv->use_mini_header, sub->type);
+ spice_header_set_msg_size(in->header, channel->priv->use_mini_header, sub->size);
+ in->data = (uint8_t*)(sub+1);
+ in->dpos = sub->size;
+ in->parent = parent;
+ spice_msg_in_ref(parent);
+ return in;
+}
+
+G_GNUC_INTERNAL
+void spice_msg_in_ref(SpiceMsgIn *in)
+{
+ g_return_if_fail(in != NULL);
+
+ in->refcount++;
+}
+
+G_GNUC_INTERNAL
+void spice_msg_in_unref(SpiceMsgIn *in)
+{
+ g_return_if_fail(in != NULL);
+
+ in->refcount--;
+ if (in->refcount > 0)
+ return;
+ if (in->parsed)
+ in->pfree(in->parsed);
+ if (in->parent) {
+ spice_msg_in_unref(in->parent);
+ } else {
+ g_free(in->data);
+ }
+ g_free(in);
+}
+
+G_GNUC_INTERNAL
+int spice_msg_in_type(SpiceMsgIn *in)
+{
+ g_return_val_if_fail(in != NULL, -1);
+
+ return spice_header_get_msg_type(in->header, in->channel->priv->use_mini_header);
+}
+
+G_GNUC_INTERNAL
+void *spice_msg_in_parsed(SpiceMsgIn *in)
+{
+ g_return_val_if_fail(in != NULL, NULL);
+
+ return in->parsed;
+}
+
+G_GNUC_INTERNAL
+void *spice_msg_in_raw(SpiceMsgIn *in, int *len)
+{
+ g_return_val_if_fail(in != NULL, NULL);
+ g_return_val_if_fail(len != NULL, NULL);
+
+ *len = in->dpos;
+ return in->data;
+}
+
+static void hexdump(const char *prefix, unsigned char *data, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (i % 16 == 0)
+ fprintf(stderr, "%s:", prefix);
+ if (i % 4 == 0)
+ fprintf(stderr, " ");
+ fprintf(stderr, " %02x", data[i]);
+ if (i % 16 == 15)
+ fprintf(stderr, "\n");
+ }
+ if (i % 16 != 0)
+ fprintf(stderr, "\n");
+}
+
+G_GNUC_INTERNAL
+void spice_msg_in_hexdump(SpiceMsgIn *in)
+{
+ SpiceChannelPrivate *c = in->channel->priv;
+
+ fprintf(stderr, "--\n<< hdr: %s serial %" PRIu64 " type %u size %u sub-list %u\n",
+ c->name, spice_header_get_in_msg_serial(in),
+ spice_header_get_msg_type(in->header, c->use_mini_header),
+ spice_header_get_msg_size(in->header, c->use_mini_header),
+ spice_header_get_msg_sub_list(in->header, c->use_mini_header));
+ hexdump("<< msg", in->data, in->dpos);
+}
+
+G_GNUC_INTERNAL
+void spice_msg_out_hexdump(SpiceMsgOut *out, unsigned char *data, int len)
+{
+ SpiceChannelPrivate *c = out->channel->priv;
+
+ fprintf(stderr, "--\n>> hdr: %s serial %" PRIu64 " type %u size %u sub-list %u\n",
+ c->name,
+ spice_header_get_out_msg_serial(out),
+ spice_header_get_msg_type(out->header, c->use_mini_header),
+ spice_header_get_msg_size(out->header, c->use_mini_header),
+ spice_header_get_msg_sub_list(out->header, c->use_mini_header));
+ hexdump(">> msg", data, len);
+}
+
+static gboolean msg_check_read_only (int channel_type, int msg_type)
+{
+ if (msg_type < 100) // those are the common messages
+ return FALSE;
+
+ switch (channel_type) {
+ /* messages allowed to be sent in read-only mode */
+ case SPICE_CHANNEL_MAIN:
+ switch (msg_type) {
+ case SPICE_MSGC_MAIN_CLIENT_INFO:
+ case SPICE_MSGC_MAIN_MIGRATE_CONNECTED:
+ case SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR:
+ case SPICE_MSGC_MAIN_ATTACH_CHANNELS:
+ case SPICE_MSGC_MAIN_MIGRATE_END:
+ return FALSE;
+ }
+ break;
+ case SPICE_CHANNEL_DISPLAY:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+G_GNUC_INTERNAL
+SpiceMsgOut *spice_msg_out_new(SpiceChannel *channel, int type)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ SpiceMsgOut *out;
+
+ g_return_val_if_fail(c != NULL, NULL);
+
+ out = g_new0(SpiceMsgOut, 1);
+ out->refcount = 1;
+ out->channel = channel;
+ out->ro_check = msg_check_read_only(c->channel_type, type);
+
+ out->marshallers = c->marshallers;
+ out->marshaller = spice_marshaller_new();
+
+ out->header = spice_marshaller_reserve_space(out->marshaller,
+ spice_header_get_header_size(c->use_mini_header));
+ spice_marshaller_set_base(out->marshaller, spice_header_get_header_size(c->use_mini_header));
+ spice_header_set_msg_type(out->header, c->use_mini_header, type);
+ spice_header_set_msg_serial(out->header, c->use_mini_header, c->out_serial);
+ spice_header_reset_msg_sub_list(out->header, c->use_mini_header);
+
+ c->out_serial++;
+ return out;
+}
+
+G_GNUC_INTERNAL
+void spice_msg_out_ref(SpiceMsgOut *out)
+{
+ g_return_if_fail(out != NULL);
+
+ out->refcount++;
+}
+
+G_GNUC_INTERNAL
+void spice_msg_out_unref(SpiceMsgOut *out)
+{
+ g_return_if_fail(out != NULL);
+
+ out->refcount--;
+ if (out->refcount > 0)
+ return;
+ spice_marshaller_destroy(out->marshaller);
+ g_free(out);
+}
+
+/* system context */
+static gboolean spice_channel_idle_wakeup(gpointer user_data)
+{
+ SpiceChannel *channel = SPICE_CHANNEL(user_data);
+ SpiceChannelPrivate *c = channel->priv;
+
+ /*
+ * Note:
+ *
+ * - This must be done before the wakeup as that may eventually
+ * call channel_reset() which checks this.
+ * - The lock calls are really necessary, this fixes the following race:
+ * 1) usb-event-thread calls spice_msg_out_send()
+ * 2) spice_msg_out_send calls g_timeout_add_full(...)
+ * 3) we run, set xmit_queue_wakeup_id to 0
+ * 4) spice_msg_out_send stores the result of g_timeout_add_full() in
+ * xmit_queue_wakeup_id, overwriting the 0 we just stored
+ * 5) xmit_queue_wakeup_id now says there is a wakeup pending which is
+ * false
+ */
+ g_mutex_lock(&c->xmit_queue_lock);
+ c->xmit_queue_wakeup_id = 0;
+ g_mutex_unlock(&c->xmit_queue_lock);
+
+ spice_channel_wakeup(channel, FALSE);
+
+ return FALSE;
+}
+
+/* any context (system/co-routine/usb-event-thread) */
+G_GNUC_INTERNAL
+void spice_msg_out_send(SpiceMsgOut *out)
+{
+ SpiceChannelPrivate *c;
+ gboolean was_empty;
+ guint32 size;
+
+ g_return_if_fail(out != NULL);
+ g_return_if_fail(out->channel != NULL);
+ c = out->channel->priv;
+ size = spice_marshaller_get_total_size(out->marshaller);
+
+ g_mutex_lock(&c->xmit_queue_lock);
+ if (c->xmit_queue_blocked) {
+ g_warning("message queue is blocked, dropping message");
+ goto end;
+ }
+
+ was_empty = g_queue_is_empty(&c->xmit_queue);
+ g_queue_push_tail(&c->xmit_queue, out);
+ c->xmit_queue_size = (was_empty) ? size : c->xmit_queue_size + size;
+
+ /* One wakeup is enough to empty the entire queue -> only do a wakeup
+ if the queue was empty, and there isn't one pending already. */
+ if (was_empty && !c->xmit_queue_wakeup_id) {
+ c->xmit_queue_wakeup_id =
+ /* Use g_timeout_add_full so that can specify the priority */
+ g_timeout_add_full(G_PRIORITY_HIGH, 0,
+ spice_channel_idle_wakeup,
+ out->channel, NULL);
+ }
+
+end:
+ g_mutex_unlock(&c->xmit_queue_lock);
+}
+
+/* coroutine context */
+G_GNUC_INTERNAL
+void spice_msg_out_send_internal(SpiceMsgOut *out)
+{
+ g_return_if_fail(out != NULL);
+
+ spice_channel_write_msg(out->channel, out);
+}
+
+/*
+ * Write all 'data' of length 'datalen' bytes out to
+ * the wire
+ */
+/* coroutine context */
+static void spice_channel_flush_wire(SpiceChannel *channel,
+ const void *data,
+ size_t datalen)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ const char *ptr = data;
+ size_t offset = 0;
+ GIOCondition cond;
+
+ while (offset < datalen) {
+ gssize ret;
+ GError *error = NULL;
+
+ if (c->has_error) return;
+
+ cond = 0;
+ if (c->tls) {
+ ret = SSL_write(c->ssl, ptr+offset, datalen-offset);
+ if (ret < 0) {
+ ret = SSL_get_error(c->ssl, ret);
+ if (ret == SSL_ERROR_WANT_READ)
+ cond |= G_IO_IN;
+ if (ret == SSL_ERROR_WANT_WRITE)
+ cond |= G_IO_OUT;
+ ret = -1;
+ }
+ } else {
+ ret = g_pollable_output_stream_write_nonblocking(G_POLLABLE_OUTPUT_STREAM(c->out),
+ ptr+offset, datalen-offset, NULL, &error);
+ if (ret < 0) {
+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
+ cond = G_IO_OUT;
+ } else {
+ CHANNEL_DEBUG(channel, "Send error %s", error->message);
+ }
+ g_clear_error(&error);
+ ret = -1;
+ }
+ }
+ if (ret == -1) {
+ if (cond != 0) {
+ // TODO: should use g_pollable_input/output_stream_create_source() in 2.28 ?
+ g_coroutine_socket_wait(&c->coroutine, c->sock, cond);
+ continue;
+ } else {
+ CHANNEL_DEBUG(channel, "Closing the channel: spice_channel_flush %d", errno);
+ c->has_error = TRUE;
+ return;
+ }
+ }
+ if (ret == 0) {
+ CHANNEL_DEBUG(channel, "Closing the connection: spice_channel_flush");
+ c->has_error = TRUE;
+ return;
+ }
+ offset += ret;
+ }
+}
+
+#ifdef HAVE_SASL
+/*
+ * Encode all buffered data, write all encrypted data out
+ * to the wire
+ */
+static void spice_channel_flush_sasl(SpiceChannel *channel, const void *data, size_t len)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ const char *output;
+ unsigned int outputlen;
+ int err;
+
+ err = sasl_encode(c->sasl_conn, data, len, &output, &outputlen);
+ if (err != SASL_OK) {
+ g_warning ("Failed to encode SASL data %s",
+ sasl_errstring(err, NULL, NULL));
+ c->has_error = TRUE;
+ return;
+ }
+
+ //CHANNEL_DEBUG(channel, "Flush SASL %d: %p %d", len, output, outputlen);
+ spice_channel_flush_wire(channel, output, outputlen);
+}
+#endif
+
+/* coroutine context */
+static void spice_channel_write(SpiceChannel *channel, const void *data, size_t len)
+{
+#ifdef HAVE_SASL
+ SpiceChannelPrivate *c = channel->priv;
+
+ if (c->sasl_conn)
+ spice_channel_flush_sasl(channel, data, len);
+ else
+#endif
+ spice_channel_flush_wire(channel, data, len);
+}
+
+/* coroutine context */
+static void spice_channel_write_msg(SpiceChannel *channel, SpiceMsgOut *out)
+{
+ uint8_t *data;
+ int free_data;
+ size_t len;
+ uint32_t msg_size;
+
+ g_return_if_fail(channel != NULL);
+ g_return_if_fail(out != NULL);
+ g_return_if_fail(channel == out->channel);
+
+ if (out->ro_check &&
+ spice_channel_get_read_only(channel)) {
+ g_warning("Try to send message while read-only. Please report a bug.");
+ return;
+ }
+
+ spice_marshaller_flush(out->marshaller);
+ msg_size = spice_marshaller_get_total_size(out->marshaller) -
+ spice_header_get_header_size(channel->priv->use_mini_header);
+ spice_header_set_msg_size(out->header, channel->priv->use_mini_header, msg_size);
+ data = spice_marshaller_linearize(out->marshaller, 0, &len, &free_data);
+ /* spice_msg_out_hexdump(out, data, len); */
+ spice_channel_write(channel, data, len);
+
+ if (free_data)
+ g_free(data);
+
+ spice_msg_out_unref(out);
+}
+
+#ifdef G_OS_UNIX
+static ssize_t read_fd(int fd, int *msgfd)
+{
+ struct msghdr msg = { NULL, };
+ struct iovec iov[1];
+ union {
+ struct cmsghdr cmsg;
+ char control[CMSG_SPACE(sizeof(int))];
+ } msg_control;
+ struct cmsghdr *cmsg;
+ ssize_t ret;
+ char c;
+
+ iov[0].iov_base = &c;
+ iov[0].iov_len = 1;
+
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = &msg_control;
+ msg.msg_controllen = sizeof(msg_control);
+
+ ret = recvmsg(fd, &msg, 0);
+ if (ret > 0) {
+ for (cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
+ cmsg->cmsg_level != SOL_SOCKET ||
+ cmsg->cmsg_type != SCM_RIGHTS) {
+ continue;
+ }
+
+ memcpy(msgfd, CMSG_DATA(cmsg), sizeof(int));
+ if (*msgfd < 0) {
+ continue;
+ }
+ }
+ }
+ return ret;
+}
+
+G_GNUC_INTERNAL
+gint spice_channel_unix_read_fd(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ gint fd = -1;
+
+ g_return_val_if_fail(g_socket_get_family(c->sock) == G_SOCKET_FAMILY_UNIX, -1);
+
+ while (1) {
+ /* g_socket_receive_message() is not convenient here because it
+ * reads all control messages, and overly complicated to deal with */
+ if (read_fd(g_socket_get_fd(c->sock), &fd) > 0) {
+ break;
+ }
+
+ if (errno == EWOULDBLOCK) {
+ g_coroutine_socket_wait(&c->coroutine, c->sock, G_IO_IN);
+ } else {
+ g_warning("failed to get fd: %s", g_strerror(errno));
+ return -1;
+ }
+ }
+
+ return fd;
+}
+#endif
+
+/*
+ * Read at least 1 more byte of data straight off the wire
+ * into the requested buffer.
+ */
+/* coroutine context */
+static int spice_channel_read_wire(SpiceChannel *channel, void *data, size_t len)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ gssize ret;
+ GIOCondition cond;
+
+reread:
+
+ if (c->has_error) return 0; /* has_error is set by disconnect(), return no error */
+
+ cond = 0;
+ if (c->tls) {
+ ret = SSL_read(c->ssl, data, len);
+ if (ret < 0) {
+ ret = SSL_get_error(c->ssl, ret);
+ if (ret == SSL_ERROR_WANT_READ)
+ cond |= G_IO_IN;
+ if (ret == SSL_ERROR_WANT_WRITE)
+ cond |= G_IO_OUT;
+ ret = -1;
+ }
+ } else {
+ GError *error = NULL;
+ ret = g_pollable_input_stream_read_nonblocking(G_POLLABLE_INPUT_STREAM(c->in),
+ data, len, NULL, &error);
+ if (ret < 0) {
+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
+ cond = G_IO_IN;
+ } else {
+ CHANNEL_DEBUG(channel, "Read error %s", error->message);
+ }
+ g_clear_error(&error);
+ ret = -1;
+ }
+ }
+
+ if (ret == -1) {
+ if (cond != 0) {
+ // TODO: should use g_pollable_input/output_stream_create_source() ?
+ g_coroutine_socket_wait(&c->coroutine, c->sock, cond);
+ goto reread;
+ } else {
+ c->has_error = TRUE;
+ return -errno;
+ }
+ }
+ if (ret == 0) {
+ CHANNEL_DEBUG(channel, "Closing the connection: spice_channel_read() - ret=0");
+ c->has_error = TRUE;
+ return 0;
+ }
+
+ return ret;
+}
+
+#ifdef HAVE_SASL
+/*
+ * Read at least 1 more byte of data out of the SASL decrypted
+ * data buffer, into the internal read buffer
+ */
+static int spice_channel_read_sasl(SpiceChannel *channel, void *data, size_t len)
+{
+ SpiceChannelPrivate *c = channel->priv;
+
+ /* CHANNEL_DEBUG(channel, "Read %lu SASL %p size %d offset %d", len, c->sasl_decoded, */
+ /* c->sasl_decoded_length, c->sasl_decoded_offset); */
+
+ if (c->sasl_decoded == NULL || c->sasl_decoded_length == 0) {
+ char encoded[8192]; /* should stay lower than maxbufsize */
+ int err, ret;
+
+ g_warn_if_fail(c->sasl_decoded_offset == 0);
+
+ ret = spice_channel_read_wire(channel, encoded, sizeof(encoded));
+ if (ret < 0)
+ return ret;
+
+ err = sasl_decode(c->sasl_conn, encoded, ret,
+ &c->sasl_decoded, &c->sasl_decoded_length);
+ if (err != SASL_OK) {
+ g_warning("Failed to decode SASL data %s",
+ sasl_errstring(err, NULL, NULL));
+ c->has_error = TRUE;
+ return -EINVAL;
+ }
+ c->sasl_decoded_offset = 0;
+ }
+
+ if (c->sasl_decoded_length == 0)
+ return 0;
+
+ len = MIN(c->sasl_decoded_length - c->sasl_decoded_offset, len);
+ memcpy(data, c->sasl_decoded + c->sasl_decoded_offset, len);
+ c->sasl_decoded_offset += len;
+
+ if (c->sasl_decoded_offset == c->sasl_decoded_length) {
+ c->sasl_decoded_length = c->sasl_decoded_offset = 0;
+ c->sasl_decoded = NULL;
+ }
+
+ return len;
+}
+#endif
+
+/*
+ * Fill the 'data' buffer up with exactly 'len' bytes worth of data
+ */
+/* coroutine context */
+static int spice_channel_read(SpiceChannel *channel, void *data, size_t length)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ gsize len = length;
+ int ret;
+
+ while (len > 0) {
+ if (c->has_error) return 0; /* has_error is set by disconnect(), return no error */
+
+#ifdef HAVE_SASL
+ if (c->sasl_conn)
+ ret = spice_channel_read_sasl(channel, data, len);
+ else
+#endif
+ ret = spice_channel_read_wire(channel, data, len);
+ if (ret < 0)
+ return ret;
+ g_assert(ret <= len);
+ len -= ret;
+ data = ((char*)data) + ret;
+#if DEBUG
+ if (len > 0)
+ CHANNEL_DEBUG(channel, "still needs %" G_GSIZE_FORMAT, len);
+#endif
+ }
+ c->total_read_bytes += length;
+
+ return length;
+}
+
+/* coroutine context */
+static void spice_channel_failed_authentication(SpiceChannel *channel,
+ gboolean invalidPassword)
+{
+ SpiceChannelPrivate *c = channel->priv;
+
+ if (c->auth_needs_username && c->auth_needs_password)
+ g_set_error_literal(&c->error,
+ SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD_AND_USERNAME,
+ _("Authentication failed: password and username are required"));
+ else if (c->auth_needs_username)
+ g_set_error_literal(&c->error,
+ SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_AUTH_NEEDS_USERNAME,
+ _("Authentication failed: username is required"));
+ else if (c->auth_needs_password)
+ g_set_error_literal(&c->error,
+ SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD,
+ _("Authentication failed: password is required"));
+ else if (invalidPassword)
+ g_set_error_literal(&c->error,
+ SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD,
+ _("Authentication failed: password is too long"));
+ else
+ g_set_error_literal(&c->error,
+ SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD,
+ _("Authentication failed: password is required"));
+
+ c->event = SPICE_CHANNEL_ERROR_AUTH;
+
+ c->has_error = TRUE; /* force disconnect */
+}
+
+/* coroutine context */
+static SpiceChannelEvent spice_channel_send_spice_ticket(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ EVP_PKEY *pubkey;
+ int nRSASize;
+ BIO *bioKey;
+ RSA *rsa;
+ char *password;
+ uint8_t *encrypted;
+ int rc;
+ SpiceChannelEvent ret = SPICE_CHANNEL_ERROR_LINK;
+
+ bioKey = BIO_new(BIO_s_mem());
+ g_return_val_if_fail(bioKey != NULL, ret);
+
+ BIO_write(bioKey, c->peer_msg->pub_key, SPICE_TICKET_PUBKEY_BYTES);
+ pubkey = d2i_PUBKEY_bio(bioKey, NULL);
+ g_return_val_if_fail(pubkey != NULL, ret);
+
+ rsa = pubkey->pkey.rsa;
+ nRSASize = RSA_size(rsa);
+
+ encrypted = g_alloca(nRSASize);
+ /*
+ The use of RSA encryption limit the potential maximum password length.
+ for RSA_PKCS1_OAEP_PADDING it is RSA_size(rsa) - 41.
+ */
+ g_object_get(c->session, "password", &password, NULL);
+ if (password == NULL)
+ password = g_strdup("");
+ if (strlen(password) > SPICE_MAX_PASSWORD_LENGTH) {
+ spice_channel_failed_authentication(channel, TRUE);
+ ret = SPICE_CHANNEL_ERROR_AUTH;
+ goto cleanup;
+ }
+ rc = RSA_public_encrypt(strlen(password) + 1, (uint8_t*)password,
+ encrypted, rsa, RSA_PKCS1_OAEP_PADDING);
+ g_warn_if_fail(rc > 0);
+
+ spice_channel_write(channel, encrypted, nRSASize);
+ ret = SPICE_CHANNEL_NONE;
+
+cleanup:
+ memset(encrypted, 0, nRSASize);
+ EVP_PKEY_free(pubkey);
+ BIO_free(bioKey);
+ g_free(password);
+ return ret;
+}
+
+/* coroutine context */
+static gboolean spice_channel_recv_auth(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ uint32_t link_res;
+ int rc;
+
+ rc = spice_channel_read(channel, &link_res, sizeof(link_res));
+ if (rc != sizeof(link_res)) {
+ CHANNEL_DEBUG(channel, "incomplete auth reply (%d/%" G_GSIZE_FORMAT ")",
+ rc, sizeof(link_res));
+ c->event = SPICE_CHANNEL_ERROR_LINK;
+ return FALSE;
+ }
+
+ if (link_res != SPICE_LINK_ERR_OK) {
+ CHANNEL_DEBUG(channel, "link result: reply %u", link_res);
+ spice_channel_failed_authentication(channel, FALSE);
+ return FALSE;
+ }
+
+ c->state = SPICE_CHANNEL_STATE_READY;
+
+ g_coroutine_signal_emit(channel, signals[SPICE_CHANNEL_EVENT], 0, SPICE_CHANNEL_OPENED);
+
+ if (c->state == SPICE_CHANNEL_STATE_MIGRATION_HANDSHAKE) {
+ spice_channel_send_migration_handshake(channel);
+ }
+
+ if (c->state != SPICE_CHANNEL_STATE_MIGRATING)
+ spice_channel_up(channel);
+
+ return TRUE;
+}
+
+G_GNUC_INTERNAL
+void spice_channel_up(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+
+ CHANNEL_DEBUG(channel, "channel up, state %u", c->state);
+
+ if (SPICE_CHANNEL_GET_CLASS(channel)->channel_up)
+ SPICE_CHANNEL_GET_CLASS(channel)->channel_up(channel);
+}
+
+/* coroutine context */
+static void spice_channel_send_link(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ uint8_t *buffer, *p;
+ int protocol, i;
+
+ c->link_hdr.magic = SPICE_MAGIC;
+ c->link_hdr.size = sizeof(c->link_msg);
+
+ g_object_get(c->session, "protocol", &protocol, NULL);
+ switch (protocol) {
+ case 1: /* protocol 1 == major 1, old 0.4 protocol, last active minor */
+ c->link_hdr.major_version = 1;
+ c->link_hdr.minor_version = 3;
+ c->parser = spice_get_server_channel_parser1(c->channel_type, NULL);
+ c->marshallers = spice_message_marshallers_get1();
+ break;
+ case SPICE_VERSION_MAJOR: /* protocol 2 == current */
+ c->link_hdr.major_version = SPICE_VERSION_MAJOR;
+ c->link_hdr.minor_version = SPICE_VERSION_MINOR;
+ c->parser = spice_get_server_channel_parser(c->channel_type, NULL);
+ c->marshallers = spice_message_marshallers_get();
+ break;
+ default:
+ g_critical("unknown major %d", protocol);
+ return;
+ }
+
+ c->link_hdr.major_version = GUINT32_TO_LE(c->link_hdr.major_version);
+ c->link_hdr.minor_version = GUINT32_TO_LE(c->link_hdr.minor_version);
+
+ c->link_msg.connection_id = GUINT32_TO_LE(spice_session_get_connection_id(c->session));
+ c->link_msg.channel_type = c->channel_type;
+ c->link_msg.channel_id = c->channel_id;
+ c->link_msg.caps_offset = GUINT32_TO_LE(sizeof(c->link_msg));
+
+ c->link_msg.num_common_caps = GUINT32_TO_LE(c->common_caps->len);
+ c->link_msg.num_channel_caps = GUINT32_TO_LE(c->caps->len);
+ c->link_hdr.size += (c->common_caps->len + c->caps->len) * sizeof(uint32_t);
+
+ buffer = g_malloc0(sizeof(c->link_hdr) + c->link_hdr.size);
+ p = buffer;
+
+ c->link_hdr.size = GUINT32_TO_LE(c->link_hdr.size);
+
+ memcpy(p, &c->link_hdr, sizeof(c->link_hdr)); p += sizeof(c->link_hdr);
+ memcpy(p, &c->link_msg, sizeof(c->link_msg)); p += sizeof(c->link_msg);
+
+ for (i = 0; i < c->common_caps->len; i++) {
+ *(uint32_t *)p = GUINT32_TO_LE(g_array_index(c->common_caps, uint32_t, i));
+ p += sizeof(uint32_t);
+ }
+ for (i = 0; i < c->caps->len; i++) {
+ *(uint32_t *)p = GUINT32_TO_LE(g_array_index(c->caps, uint32_t, i));
+ p += sizeof(uint32_t);
+ }
+ CHANNEL_DEBUG(channel, "channel type %d id %d num common caps %u num caps %u",
+ c->channel_type,
+ c->channel_id,
+ c->common_caps->len,
+ c->caps->len);
+ spice_channel_write(channel, buffer, p - buffer);
+ g_free(buffer);
+}
+
+/* coroutine context */
+static gboolean spice_channel_recv_link_hdr(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ int rc;
+
+ rc = spice_channel_read(channel, &c->peer_hdr, sizeof(c->peer_hdr));
+ if (rc != sizeof(c->peer_hdr)) {
+ g_warning("incomplete link header (%d/%" G_GSIZE_FORMAT ")",
+ rc, sizeof(c->peer_hdr));
+ goto error;
+ }
+ if (c->peer_hdr.magic != SPICE_MAGIC) {
+ g_warning("invalid SPICE_MAGIC!");
+ goto error;
+ }
+
+ CHANNEL_DEBUG(channel, "Peer version: %u:%u",
+ GUINT32_FROM_LE(c->peer_hdr.major_version),
+ GUINT32_FROM_LE(c->peer_hdr.minor_version));
+ if (c->peer_hdr.major_version != c->link_hdr.major_version) {
+ g_warning("major mismatch (got %u, expected %u)",
+ c->peer_hdr.major_version, c->link_hdr.major_version);
+ goto error;
+ }
+
+ c->peer_hdr.major_version = GUINT32_FROM_LE(c->peer_hdr.major_version);
+ c->peer_hdr.minor_version = GUINT32_FROM_LE(c->peer_hdr.minor_version);
+ c->peer_hdr.size = GUINT32_FROM_LE(c->peer_hdr.size);
+
+ c->peer_msg = g_malloc0(c->peer_hdr.size);
+ if (c->peer_msg == NULL) {
+ g_warning("invalid peer header size: %u", c->peer_hdr.size);
+ goto error;
+ }
+
+ return TRUE;
+
+error:
+ /* Windows socket seems to give early CONNRESET errors. The server
+ does not linger when closing the socket if the protocol is
+ incompatible. Try with the oldest protocol in this case: */
+ if (c->link_hdr.major_version != 1) {
+ SPICE_DEBUG("%s: error, switching to protocol 1 (spice 0.4)", c->name);
+ c->state = SPICE_CHANNEL_STATE_RECONNECTING;
+ g_object_set(c->session, "protocol", 1, NULL);
+ return FALSE;
+ }
+
+ c->event = SPICE_CHANNEL_ERROR_LINK;
+ return FALSE;
+}
+
+#ifdef HAVE_SASL
+/*
+ * NB, keep in sync with similar method in spice/server/reds.c
+ */
+static gchar *addr_to_string(GSocketAddress *addr)
+{
+ GInetSocketAddress *iaddr = G_INET_SOCKET_ADDRESS(addr);
+ guint16 port;
+ GInetAddress *host;
+ gchar *hoststr;
+ gchar *ret;
+
+ host = g_inet_socket_address_get_address(iaddr);
+ port = g_inet_socket_address_get_port(iaddr);
+ hoststr = g_inet_address_to_string(host);
+
+ ret = g_strdup_printf("%s;%hu", hoststr, port);
+ g_free(hoststr);
+
+ return ret;
+}
+
+static gboolean
+spice_channel_gather_sasl_credentials(SpiceChannel *channel,
+ sasl_interact_t *interact)
+{
+ SpiceChannelPrivate *c;
+ int ninteract;
+ gboolean ret = TRUE;
+
+ g_return_val_if_fail(channel != NULL, FALSE);
+ g_return_val_if_fail(channel->priv != NULL, FALSE);
+
+ c = channel->priv;
+
+ /* FIXME: we could keep connection open and ask connection details if missing */
+
+ for (ninteract = 0 ; interact[ninteract].id != 0 ; ninteract++) {
+ switch (interact[ninteract].id) {
+ case SASL_CB_AUTHNAME:
+ case SASL_CB_USER:
+ c->auth_needs_username = TRUE;
+ break;
+ case SASL_CB_PASS:
+ c->auth_needs_password = TRUE;
+ break;
+ }
+ }
+
+ for (ninteract = 0 ; interact[ninteract].id != 0 ; ninteract++) {
+ switch (interact[ninteract].id) {
+ case SASL_CB_AUTHNAME:
+ case SASL_CB_USER:
+ if (spice_session_get_username(c->session) != NULL) {
+ interact[ninteract].result = spice_session_get_username(c->session);
+ interact[ninteract].len = strlen(interact[ninteract].result);
+ }
+ break;
+
+ case SASL_CB_PASS:
+ if (spice_session_get_password(c->session) == NULL) {
+ /* Even if we reach this point, we have to continue looking for
+ * SASL_CB_AUTHNAME|SASL_CB_USER, otherwise we would return a
+ * wrong error to the applications */
+ ret = FALSE;
+ continue;
+ }
+
+ interact[ninteract].result = spice_session_get_password(c->session);
+ interact[ninteract].len = strlen(interact[ninteract].result);
+ break;
+ }
+ }
+
+ CHANNEL_DEBUG(channel, "Filled SASL interact");
+
+ return ret;
+}
+
+/*
+ *
+ * Init msg from server
+ *
+ * u32 mechlist-length
+ * u8-array mechlist-string
+ *
+ * Start msg to server
+ *
+ * u32 mechname-length
+ * u8-array mechname-string
+ * u32 clientout-length
+ * u8-array clientout-string
+ *
+ * Start msg from server
+ *
+ * u32 serverin-length
+ * u8-array serverin-string
+ * u8 continue
+ *
+ * Step msg to server
+ *
+ * u32 clientout-length
+ * u8-array clientout-string
+ *
+ * Step msg from server
+ *
+ * u32 serverin-length
+ * u8-array serverin-string
+ * u8 continue
+ */
+
+#define SASL_MAX_MECHLIST_LEN 300
+#define SASL_MAX_MECHNAME_LEN 100
+#define SASL_MAX_DATA_LEN (1024 * 1024)
+
+/* Perform the SASL authentication process
+ */
+static gboolean spice_channel_perform_auth_sasl(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c;
+ sasl_conn_t *saslconn = NULL;
+ sasl_security_properties_t secprops;
+ const char *clientout;
+ char *serverin = NULL;
+ unsigned int clientoutlen;
+ int err;
+ char *localAddr = NULL, *remoteAddr = NULL;
+ const void *val;
+ sasl_ssf_t ssf;
+ static const sasl_callback_t saslcb[] = {
+ { .id = SASL_CB_USER },
+ { .id = SASL_CB_AUTHNAME },
+ { .id = SASL_CB_PASS },
+ { .id = 0 },
+ };
+ sasl_interact_t *interact = NULL;
+ guint32 len;
+ char *mechlist = NULL;
+ const char *mechname;
+ gboolean ret = FALSE;
+ GSocketAddress *addr = NULL;
+ guint8 complete;
+
+ g_return_val_if_fail(channel != NULL, FALSE);
+ g_return_val_if_fail(channel->priv != NULL, FALSE);
+
+ c = channel->priv;
+
+ /* Sets up the SASL library as a whole */
+ err = sasl_client_init(NULL);
+ CHANNEL_DEBUG(channel, "Client initialize SASL authentication %d", err);
+ if (err != SASL_OK) {
+ g_critical("failed to initialize SASL library: %d (%s)",
+ err, sasl_errstring(err, NULL, NULL));
+ goto error;
+ }
+
+ /* Get local address in form IPADDR:PORT */
+ addr = g_socket_get_local_address(c->sock, NULL);
+ if (!addr) {
+ g_critical("failed to get local address");
+ goto error;
+ }
+ if ((g_socket_address_get_family(addr) == G_SOCKET_FAMILY_IPV4 ||
+ g_socket_address_get_family(addr) == G_SOCKET_FAMILY_IPV6) &&
+ (localAddr = addr_to_string(addr)) == NULL)
+ goto error;
+ g_clear_object(&addr);
+
+ /* Get remote address in form IPADDR:PORT */
+ addr = g_socket_get_remote_address(c->sock, NULL);
+ if (!addr) {
+ g_critical("failed to get peer address");
+ goto error;
+ }
+ if ((g_socket_address_get_family(addr) == G_SOCKET_FAMILY_IPV4 ||
+ g_socket_address_get_family(addr) == G_SOCKET_FAMILY_IPV6) &&
+ (remoteAddr = addr_to_string(addr)) == NULL)
+ goto error;
+ g_clear_object(&addr);
+
+ CHANNEL_DEBUG(channel, "Client SASL new host:'%s' local:'%s' remote:'%s'",
+ spice_session_get_host(c->session), localAddr, remoteAddr);
+
+ /* Setup a handle for being a client */
+ err = sasl_client_new("spice",
+ spice_session_get_host(c->session),
+ localAddr,
+ remoteAddr,
+ saslcb,
+ SASL_SUCCESS_DATA,
+ &saslconn);
+
+ if (err != SASL_OK) {
+ g_critical("Failed to create SASL client context: %d (%s)",
+ err, sasl_errstring(err, NULL, NULL));
+ goto error;
+ }
+
+ if (c->ssl) {
+ sasl_ssf_t ssf;
+
+ ssf = SSL_get_cipher_bits(c->ssl, NULL);
+ err = sasl_setprop(saslconn, SASL_SSF_EXTERNAL, &ssf);
+ if (err != SASL_OK) {
+ g_critical("cannot set SASL external SSF %d (%s)",
+ err, sasl_errstring(err, NULL, NULL));
+ goto error;
+ }
+ }
+
+ memset(&secprops, 0, sizeof secprops);
+ /* If we've got TLS, we don't care about SSF */
+ secprops.min_ssf = c->ssl ? 0 : 56; /* Equiv to DES supported by all Kerberos */
+ secprops.max_ssf = c->ssl ? 0 : 100000; /* Very strong ! AES == 256 */
+ secprops.maxbufsize = 100000;
+ /* If we're not TLS, then forbid any anonymous or trivially crackable auth */
+ secprops.security_flags = c->ssl ? 0 :
+ SASL_SEC_NOANONYMOUS | SASL_SEC_NOPLAINTEXT;
+
+ err = sasl_setprop(saslconn, SASL_SEC_PROPS, &secprops);
+ if (err != SASL_OK) {
+ g_critical("cannot set security props %d (%s)",
+ err, sasl_errstring(err, NULL, NULL));
+ goto error;
+ }
+
+ /* Get the supported mechanisms from the server */
+ spice_channel_read(channel, &len, sizeof(len));
+ if (c->has_error)
+ goto error;
+ if (len > SASL_MAX_MECHLIST_LEN) {
+ g_critical("mechlistlen %u too long", len);
+ goto error;
+ }
+
+ mechlist = g_malloc0(len + 1);
+ spice_channel_read(channel, mechlist, len);
+ mechlist[len] = '\0';
+ if (c->has_error) {
+ goto error;
+ }
+
+restart:
+ /* Start the auth negotiation on the client end first */
+ CHANNEL_DEBUG(channel, "Client start negotiation mechlist '%s'", mechlist);
+ err = sasl_client_start(saslconn,
+ mechlist,
+ &interact,
+ &clientout,
+ &clientoutlen,
+ &mechname);
+ if (err != SASL_OK && err != SASL_CONTINUE && err != SASL_INTERACT) {
+ g_critical("Failed to start SASL negotiation: %d (%s)",
+ err, sasl_errdetail(saslconn));
+ goto error;
+ }
+
+ /* Need to gather some credentials from the client */
+ if (err == SASL_INTERACT) {
+ if (!spice_channel_gather_sasl_credentials(channel, interact)) {
+ CHANNEL_DEBUG(channel, "Failed to collect auth credentials");
+ goto error;
+ }
+ goto restart;
+ }
+
+ CHANNEL_DEBUG(channel, "Server start negotiation with mech %s. Data %u bytes %p '%s'",
+ mechname, clientoutlen, clientout, clientout);
+
+ if (clientoutlen > SASL_MAX_DATA_LEN) {
+ g_critical("SASL negotiation data too long: %u bytes",
+ clientoutlen);
+ goto error;
+ }
+
+ /* Send back the chosen mechname */
+ len = strlen(mechname);
+ spice_channel_write(channel, &len, sizeof(guint32));
+ spice_channel_write(channel, mechname, len);
+
+ /* NB, distinction of NULL vs "" is *critical* in SASL */
+ if (clientout) {
+ len = clientoutlen + 1;
+ spice_channel_write(channel, &len, sizeof(guint32));
+ spice_channel_write(channel, clientout, len);
+ } else {
+ len = 0;
+ spice_channel_write(channel, &len, sizeof(guint32));
+ }
+
+ if (c->has_error)
+ goto error;
+
+ CHANNEL_DEBUG(channel, "Getting sever start negotiation reply");
+ /* Read the 'START' message reply from server */
+ spice_channel_read(channel, &len, sizeof(len));
+ if (c->has_error)
+ goto error;
+ if (len > SASL_MAX_DATA_LEN) {
+ g_critical("SASL negotiation data too long: %u bytes",
+ len);
+ goto error;
+ }
+
+ /* NB, distinction of NULL vs "" is *critical* in SASL */
+ if (len > 0) {
+ serverin = g_malloc0(len);
+ spice_channel_read(channel, serverin, len);
+ serverin[len - 1] = '\0';
+ len--;
+ } else {
+ serverin = NULL;
+ }
+ spice_channel_read(channel, &complete, sizeof(guint8));
+ if (c->has_error)
+ goto error;
+
+ CHANNEL_DEBUG(channel, "Client start result complete: %d. Data %u bytes %p '%s'",
+ complete, len, serverin, serverin);
+
+ /* Loop-the-loop...
+ * Even if the server has completed, the client must *always* do at least one step
+ * in this loop to verify the server isn't lying about something. Mutual auth */
+ for (;;) {
+ if (complete && err == SASL_OK)
+ break;
+
+ restep:
+ err = sasl_client_step(saslconn,
+ serverin,
+ len,
+ &interact,
+ &clientout,
+ &clientoutlen);
+ if (err != SASL_OK && err != SASL_CONTINUE && err != SASL_INTERACT) {
+ g_critical("Failed SASL step: %d (%s)",
+ err, sasl_errdetail(saslconn));
+ goto error;
+ }
+
+ /* Need to gather some credentials from the client */
+ if (err == SASL_INTERACT) {
+ if (!spice_channel_gather_sasl_credentials(channel,
+ interact)) {
+ CHANNEL_DEBUG(channel, "%s", "Failed to collect auth credentials");
+ goto error;
+ }
+ goto restep;
+ }
+
+ g_clear_pointer(&serverin, g_free);
+
+ CHANNEL_DEBUG(channel, "Client step result %d. Data %u bytes %p '%s'", err, clientoutlen, clientout, clientout);
+
+ /* Previous server call showed completion & we're now locally complete too */
+ if (complete && err == SASL_OK)
+ break;
+
+ /* Not done, prepare to talk with the server for another iteration */
+
+ /* NB, distinction of NULL vs "" is *critical* in SASL */
+ if (clientout) {
+ len = clientoutlen + 1;
+ spice_channel_write(channel, &len, sizeof(guint32));
+ spice_channel_write(channel, clientout, len);
+ } else {
+ len = 0;
+ spice_channel_write(channel, &len, sizeof(guint32));
+ }
+
+ if (c->has_error)
+ goto error;
+
+ CHANNEL_DEBUG(channel, "Server step with %u bytes %p", clientoutlen, clientout);
+
+ spice_channel_read(channel, &len, sizeof(guint32));
+ if (c->has_error)
+ goto error;
+ if (len > SASL_MAX_DATA_LEN) {
+ g_critical("SASL negotiation data too long: %u bytes", len);
+ goto error;
+ }
+
+ /* NB, distinction of NULL vs "" is *critical* in SASL */
+ if (len) {
+ serverin = g_malloc0(len);
+ spice_channel_read(channel, serverin, len);
+ serverin[len - 1] = '\0';
+ len--;
+ } else {
+ serverin = NULL;
+ }
+
+ spice_channel_read(channel, &complete, sizeof(guint8));
+ if (c->has_error)
+ goto error;
+
+ CHANNEL_DEBUG(channel, "Client step result complete: %d. Data %u bytes %p '%s'",
+ complete, len, serverin, serverin);
+
+ /* This server call shows complete, and earlier client step was OK */
+ if (complete) {
+ g_clear_pointer(&serverin, g_free);
+ if (err == SASL_CONTINUE) /* something went wrong */
+ goto complete;
+ break;
+ }
+ }
+
+ /* Check for suitable SSF if non-TLS */
+ if (!c->ssl) {
+ err = sasl_getprop(saslconn, SASL_SSF, &val);
+ if (err != SASL_OK) {
+ g_critical("cannot query SASL ssf on connection %d (%s)",
+ err, sasl_errstring(err, NULL, NULL));
+ goto error;
+ }
+ ssf = *(const int *)val;
+ CHANNEL_DEBUG(channel, "SASL SSF value %u", ssf);
+ if (ssf < 56) { /* 56 == DES level, good for Kerberos */
+ g_critical("negotiation SSF %u was not strong enough", ssf);
+ goto error;
+ }
+ }
+
+complete:
+ CHANNEL_DEBUG(channel, "%s", "SASL authentication complete");
+ spice_channel_read(channel, &len, sizeof(len));
+ if (len == SPICE_LINK_ERR_OK) {
+ ret = TRUE;
+ /* This must come *after* check-auth-result, because the former
+ * is defined to be sent unencrypted, and setting saslconn turns
+ * on the SSF layer encryption processing */
+ c->sasl_conn = saslconn;
+ goto cleanup;
+ }
+
+error:
+ if (saslconn)
+ sasl_dispose(&saslconn);
+
+ spice_channel_failed_authentication(channel, FALSE);
+ ret = FALSE;
+
+cleanup:
+ g_free(localAddr);
+ g_free(remoteAddr);
+ g_free(mechlist);
+ g_free(serverin);
+ g_clear_object(&addr);
+ return ret;
+}
+#endif /* HAVE_SASL */
+
+/* coroutine context */
+static gboolean spice_channel_recv_link_msg(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c;
+ int rc, num_caps, i;
+ uint32_t *caps, num_channel_caps, num_common_caps;
+ SpiceChannelEvent event = SPICE_CHANNEL_ERROR_LINK;
+
+ g_return_val_if_fail(channel != NULL, FALSE);
+ g_return_val_if_fail(channel->priv != NULL, FALSE);
+
+ c = channel->priv;
+
+ rc = spice_channel_read(channel, (uint8_t*)c->peer_msg + c->peer_pos,
+ c->peer_hdr.size - c->peer_pos);
+ c->peer_pos += rc;
+ if (c->peer_pos != c->peer_hdr.size) {
+ g_critical("%s: %s: incomplete link reply (%d/%u)",
+ c->name, __FUNCTION__, rc, c->peer_hdr.size);
+ goto error;
+ }
+ switch (c->peer_msg->error) {
+ case SPICE_LINK_ERR_OK:
+ /* nothing */
+ break;
+ case SPICE_LINK_ERR_NEED_SECURED:
+ c->state = SPICE_CHANNEL_STATE_RECONNECTING;
+ CHANNEL_DEBUG(channel, "switching to tls");
+ c->tls = TRUE;
+ return FALSE;
+ default:
+ g_warning("%s: %s: unhandled error %u",
+ c->name, __FUNCTION__, c->peer_msg->error);
+ goto error;
+ }
+
+ num_channel_caps = GUINT32_FROM_LE(c->peer_msg->num_channel_caps);
+ num_common_caps = GUINT32_FROM_LE(c->peer_msg->num_common_caps);
+
+ num_caps = num_channel_caps + num_common_caps;
+ CHANNEL_DEBUG(channel, "%s: %d caps", __FUNCTION__, num_caps);
+
+ /* see original spice/client code: */
+ /* g_return_if_fail(c->peer_msg + c->peer_msg->caps_offset * sizeof(uint32_t) > c->peer_msg + c->peer_hdr.size); */
+
+ caps = (uint32_t *)((uint8_t *)c->peer_msg + GUINT32_FROM_LE(c->peer_msg->caps_offset));
+
+ g_array_set_size(c->remote_common_caps, num_common_caps);
+ for (i = 0; i < num_common_caps; i++, caps++) {
+ g_array_index(c->remote_common_caps, uint32_t, i) = GUINT32_FROM_LE(*caps);
+ CHANNEL_DEBUG(channel, "got common caps %d:0x%X", i, GUINT32_FROM_LE(*caps));
+ }
+
+ g_array_set_size(c->remote_caps, num_channel_caps);
+ for (i = 0; i < num_channel_caps; i++, caps++) {
+ g_array_index(c->remote_caps, uint32_t, i) = GUINT32_FROM_LE(*caps);
+ CHANNEL_DEBUG(channel, "got channel caps %d:0x%X", i, GUINT32_FROM_LE(*caps));
+ }
+
+ if (!spice_channel_test_common_capability(channel,
+ SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION)) {
+ CHANNEL_DEBUG(channel, "Server supports spice ticket auth only");
+ if ((event = spice_channel_send_spice_ticket(channel)) != SPICE_CHANNEL_NONE)
+ goto error;
+ } else {
+ SpiceLinkAuthMechanism auth = { 0, };
+
+#ifdef HAVE_SASL
+ if (spice_channel_test_common_capability(channel, SPICE_COMMON_CAP_AUTH_SASL)) {
+ CHANNEL_DEBUG(channel, "Choosing SASL mechanism");
+ auth.auth_mechanism = SPICE_COMMON_CAP_AUTH_SASL;
+ spice_channel_write(channel, &auth, sizeof(auth));
+ if (!spice_channel_perform_auth_sasl(channel))
+ return FALSE;
+ } else
+#endif
+ if (spice_channel_test_common_capability(channel, SPICE_COMMON_CAP_AUTH_SPICE)) {
+ auth.auth_mechanism = SPICE_COMMON_CAP_AUTH_SPICE;
+ spice_channel_write(channel, &auth, sizeof(auth));
+ if ((event = spice_channel_send_spice_ticket(channel)) != SPICE_CHANNEL_NONE)
+ goto error;
+ } else {
+ g_warning("No compatible AUTH mechanism");
+ goto error;
+ }
+ }
+ c->use_mini_header = spice_channel_test_common_capability(channel,
+ SPICE_COMMON_CAP_MINI_HEADER);
+ CHANNEL_DEBUG(channel, "use mini header: %d", c->use_mini_header);
+ return TRUE;
+
+error:
+ c->has_error = TRUE;
+ c->event = event;
+ return FALSE;
+}
+
+/* system context */
+G_GNUC_INTERNAL
+void spice_channel_wakeup(SpiceChannel *channel, gboolean cancel)
+{
+ GCoroutine *c;
+
+ g_return_if_fail(SPICE_IS_CHANNEL(channel));
+ c = &channel->priv->coroutine;
+
+ if (cancel)
+ g_coroutine_condition_cancel(c);
+
+ g_coroutine_wakeup(c);
+}
+
+G_GNUC_INTERNAL
+gboolean spice_channel_get_read_only(SpiceChannel *channel)
+{
+ return spice_session_get_read_only(channel->priv->session);
+}
+
+/* coroutine context */
+G_GNUC_INTERNAL
+void spice_channel_recv_msg(SpiceChannel *channel,
+ handler_msg_in msg_handler, gpointer data)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ SpiceMsgIn *in;
+ int msg_size;
+ int msg_type;
+ int sub_list_offset = 0;
+
+ in = spice_msg_in_new(channel);
+
+ /* receive message */
+ spice_channel_read(channel, in->header,
+ spice_header_get_header_size(c->use_mini_header));
+ if (c->has_error)
+ goto end;
+
+ msg_size = spice_header_get_msg_size(in->header, c->use_mini_header);
+ /* FIXME: do not allow others to take ref on in, and use realloc here?
+ * this would avoid malloc/free on each message?
+ */
+ in->data = g_malloc0(msg_size);
+ spice_channel_read(channel, in->data, msg_size);
+ if (c->has_error)
+ goto end;
+ in->dpos = msg_size;
+
+ msg_type = spice_header_get_msg_type(in->header, c->use_mini_header);
+ sub_list_offset = spice_header_get_msg_sub_list(in->header, c->use_mini_header);
+
+ if (msg_type == SPICE_MSG_LIST || sub_list_offset) {
+ SpiceSubMessageList *sub_list;
+ SpiceSubMessage *sub;
+ SpiceMsgIn *sub_in;
+ int i;
+
+ sub_list = (SpiceSubMessageList *)(in->data + sub_list_offset);
+ for (i = 0; i < sub_list->size; i++) {
+ sub = (SpiceSubMessage *)(in->data + sub_list->sub_messages[i]);
+ sub_in = spice_msg_in_sub_new(channel, in, sub);
+ sub_in->parsed = c->parser(sub_in->data, sub_in->data + sub_in->dpos,
+ spice_header_get_msg_type(sub_in->header,
+ c->use_mini_header),
+ c->peer_hdr.minor_version,
+ &sub_in->psize, &sub_in->pfree);
+ if (sub_in->parsed == NULL) {
+ g_critical("failed to parse sub-message: %s type %d",
+ c->name, spice_header_get_msg_type(sub_in->header, c->use_mini_header));
+ goto end;
+ }
+ msg_handler(channel, sub_in, data);
+ spice_msg_in_unref(sub_in);
+ }
+ }
+
+ /* ack message */
+ if (c->message_ack_count) {
+ c->message_ack_count--;
+ if (!c->message_ack_count) {
+ SpiceMsgOut *out = spice_msg_out_new(channel, SPICE_MSGC_ACK);
+ spice_msg_out_send_internal(out);
+ c->message_ack_count = c->message_ack_window;
+ }
+ }
+
+ if (msg_type == SPICE_MSG_LIST) {
+ goto end;
+ }
+
+ /* parse message */
+ in->parsed = c->parser(in->data, in->data + msg_size, msg_type,
+ c->peer_hdr.minor_version, &in->psize, &in->pfree);
+ if (in->parsed == NULL) {
+ g_critical("failed to parse message: %s type %d",
+ c->name, msg_type);
+ goto end;
+ }
+
+ /* process message */
+ /* spice_msg_in_hexdump(in); */
+ msg_handler(channel, in, data);
+
+end:
+ /* If the server uses full header, the serial is not necessarily equal
+ * to c->in_serial (the server can sometimes skip serials) */
+ c->last_message_serial = spice_header_get_in_msg_serial(in);
+ c->in_serial++;
+ spice_msg_in_unref(in);
+}
+
+static const char *to_string[] = {
+ NULL,
+ [ SPICE_CHANNEL_MAIN ] = "main",
+ [ SPICE_CHANNEL_DISPLAY ] = "display",
+ [ SPICE_CHANNEL_INPUTS ] = "inputs",
+ [ SPICE_CHANNEL_CURSOR ] = "cursor",
+ [ SPICE_CHANNEL_PLAYBACK ] = "playback",
+ [ SPICE_CHANNEL_RECORD ] = "record",
+ [ SPICE_CHANNEL_TUNNEL ] = "tunnel",
+ [ SPICE_CHANNEL_SMARTCARD ] = "smartcard",
+ [ SPICE_CHANNEL_USBREDIR ] = "usbredir",
+ [ SPICE_CHANNEL_PORT ] = "port",
+ [ SPICE_CHANNEL_WEBDAV ] = "webdav",
+};
+
+/**
+ * spice_channel_type_to_string:
+ * @type: a channel-type property value
+ *
+ * Convert a channel-type property value to a string.
+ *
+ * Returns: string representation of @type.
+ * Since: 0.20
+ **/
+const gchar* spice_channel_type_to_string(gint type)
+{
+ const char *str = NULL;
+
+ if (type >= 0 && type < G_N_ELEMENTS(to_string)) {
+ str = to_string[type];
+ }
+
+ return str ? str : "unknown channel type";
+}
+
+/**
+ * spice_channel_string_to_type:
+ * @str: a string representation of the channel-type property
+ *
+ * Convert a channel-type property value to a string.
+ *
+ * Returns: the channel-type property value for a @str channel
+ * Since: 0.21
+ **/
+gint spice_channel_string_to_type(const gchar *str)
+{
+ int i;
+
+ g_return_val_if_fail(str != NULL, -1);
+
+ for (i = 0; i < G_N_ELEMENTS(to_string); i++)
+ if (g_strcmp0(str, to_string[i]) == 0)
+ return i;
+
+ return -1;
+}
+
+G_GNUC_INTERNAL
+gchar *spice_channel_supported_string(void)
+{
+ return g_strjoin(", ",
+ spice_channel_type_to_string(SPICE_CHANNEL_MAIN),
+ spice_channel_type_to_string(SPICE_CHANNEL_DISPLAY),
+ spice_channel_type_to_string(SPICE_CHANNEL_INPUTS),
+ spice_channel_type_to_string(SPICE_CHANNEL_CURSOR),
+ spice_channel_type_to_string(SPICE_CHANNEL_PLAYBACK),
+ spice_channel_type_to_string(SPICE_CHANNEL_RECORD),
+#ifdef USE_SMARTCARD
+ spice_channel_type_to_string(SPICE_CHANNEL_SMARTCARD),
+#endif
+#ifdef USE_USBREDIR
+ spice_channel_type_to_string(SPICE_CHANNEL_USBREDIR),
+#endif
+#ifdef USE_PHODAV
+ spice_channel_type_to_string(SPICE_CHANNEL_WEBDAV),
+#endif
+ NULL);
+}
+
+
+/**
+ * spice_channel_new:
+ * @s: the @SpiceSession the channel is linked to
+ * @type: the requested SPICECHANNELPRIVATE type
+ * @id: the channel-id
+ *
+ * Create a new #SpiceChannel of type @type, and channel ID @id.
+ *
+ * Returns: a weak reference to #SpiceChannel, the session owns the reference
+ **/
+SpiceChannel *spice_channel_new(SpiceSession *s, int type, int id)
+{
+ SpiceChannel *channel;
+ GType gtype = 0;
+
+ g_return_val_if_fail(s != NULL, NULL);
+
+ switch (type) {
+ case SPICE_CHANNEL_MAIN:
+ gtype = SPICE_TYPE_MAIN_CHANNEL;
+ break;
+ case SPICE_CHANNEL_DISPLAY:
+ gtype = SPICE_TYPE_DISPLAY_CHANNEL;
+ break;
+ case SPICE_CHANNEL_CURSOR:
+ gtype = SPICE_TYPE_CURSOR_CHANNEL;
+ break;
+ case SPICE_CHANNEL_INPUTS:
+ gtype = SPICE_TYPE_INPUTS_CHANNEL;
+ break;
+ case SPICE_CHANNEL_PLAYBACK:
+ case SPICE_CHANNEL_RECORD: {
+ if (!spice_session_get_audio_enabled(s)) {
+ SPICE_DEBUG("audio channel is disabled, not creating it");
+ return NULL;
+ }
+ gtype = type == SPICE_CHANNEL_RECORD ?
+ SPICE_TYPE_RECORD_CHANNEL : SPICE_TYPE_PLAYBACK_CHANNEL;
+ break;
+ }
+#ifdef USE_SMARTCARD
+ case SPICE_CHANNEL_SMARTCARD: {
+ if (!spice_session_get_smartcard_enabled(s)) {
+ SPICE_DEBUG("smartcard channel is disabled, not creating it");
+ return NULL;
+ }
+ gtype = SPICE_TYPE_SMARTCARD_CHANNEL;
+ break;
+ }
+#endif
+#ifdef USE_USBREDIR
+ case SPICE_CHANNEL_USBREDIR: {
+ if (!spice_session_get_usbredir_enabled(s)) {
+ SPICE_DEBUG("usbredir channel is disabled, not creating it");
+ return NULL;
+ }
+ gtype = SPICE_TYPE_USBREDIR_CHANNEL;
+ break;
+ }
+#endif
+#ifdef USE_PHODAV
+ case SPICE_CHANNEL_WEBDAV: {
+ gtype = SPICE_TYPE_WEBDAV_CHANNEL;
+ break;
+ }
+#endif
+ case SPICE_CHANNEL_PORT:
+ gtype = SPICE_TYPE_PORT_CHANNEL;
+ break;
+ default:
+ SPICE_DEBUG("unsupported channel kind: %s: %d",
+ spice_channel_type_to_string(type), type);
+ return NULL;
+ }
+ channel = SPICE_CHANNEL(g_object_new(gtype,
+ "spice-session", s,
+ "channel-type", type,
+ "channel-id", id,
+ NULL));
+ return channel;
+}
+
+/**
+ * spice_channel_destroy:
+ * @channel: a #SpiceChannel
+ *
+ * Disconnect and unref the @channel.
+ *
+ * Deprecated: 0.27: this function has been deprecated because it is
+ * misleading, the object is not actually destroyed. Instead, it is
+ * recommended to call explicitely spice_channel_disconnect() and
+ * g_object_unref().
+ **/
+void spice_channel_destroy(SpiceChannel *channel)
+{
+ g_return_if_fail(channel != NULL);
+
+ CHANNEL_DEBUG(channel, "channel destroy");
+ spice_channel_disconnect(channel, SPICE_CHANNEL_NONE);
+ g_object_unref(channel);
+}
+
+/* any context */
+static void spice_channel_flushed(SpiceChannel *channel, gboolean success)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ GSList *l;
+
+ for (l = c->flushing; l != NULL; l = l->next) {
+ g_task_return_boolean(G_TASK(l->data), success);
+ }
+
+ g_slist_free_full(c->flushing, g_object_unref);
+ c->flushing = NULL;
+}
+
+/* coroutine context */
+static void spice_channel_iterate_write(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ SpiceMsgOut *out;
+
+ do {
+ g_mutex_lock(&c->xmit_queue_lock);
+ out = g_queue_pop_head(&c->xmit_queue);
+ g_mutex_unlock(&c->xmit_queue_lock);
+ if (out) {
+ guint32 size = spice_marshaller_get_total_size(out->marshaller);
+ c->xmit_queue_size = (c->xmit_queue_size < size) ? 0 : c->xmit_queue_size - size;
+ spice_channel_write_msg(channel, out);
+ }
+ } while (out);
+
+ spice_channel_flushed(channel, TRUE);
+}
+
+/* coroutine context */
+static void spice_channel_iterate_read(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+
+ g_coroutine_socket_wait(&c->coroutine, c->sock, G_IO_IN);
+
+ /* treat all incoming data (block on message completion) */
+ while (!c->has_error &&
+ c->state != SPICE_CHANNEL_STATE_MIGRATING &&
+ g_pollable_input_stream_is_readable(G_POLLABLE_INPUT_STREAM(c->in))
+ ) { do
+ spice_channel_recv_msg(channel,
+ (handler_msg_in)SPICE_CHANNEL_GET_CLASS(channel)->handle_msg, NULL);
+#ifdef HAVE_SASL
+ /* flush the sasl buffer too */
+ while (c->sasl_decoded != NULL);
+#else
+ while (FALSE);
+#endif
+ }
+
+}
+
+static gboolean wait_migration(gpointer data)
+{
+ SpiceChannel *channel = SPICE_CHANNEL(data);
+ SpiceChannelPrivate *c = channel->priv;
+
+ if (c->state != SPICE_CHANNEL_STATE_MIGRATING) {
+ CHANNEL_DEBUG(channel, "unfreeze channel");
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* coroutine context */
+static gboolean spice_channel_iterate(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+
+ if (c->state == SPICE_CHANNEL_STATE_MIGRATING &&
+ !g_coroutine_condition_wait(&c->coroutine, wait_migration, channel))
+ CHANNEL_DEBUG(channel, "migration wait cancelled");
+
+ /* flush any pending write and read */
+ if (!c->has_error)
+ SPICE_CHANNEL_GET_CLASS(channel)->iterate_write(channel);
+ if (!c->has_error)
+ SPICE_CHANNEL_GET_CLASS(channel)->iterate_read(channel);
+
+ if (c->has_error) {
+ GIOCondition ret;
+
+ if (!c->sock)
+ return FALSE;
+
+ /* We don't want to report an error if the socket was closed gracefully
+ * on the other end (VM shutdown) */
+ ret = g_socket_condition_check(c->sock, G_IO_IN | G_IO_ERR);
+
+ if (ret & G_IO_ERR) {
+ CHANNEL_DEBUG(channel, "channel got error");
+
+ if (c->state > SPICE_CHANNEL_STATE_CONNECTING) {
+ if (c->state == SPICE_CHANNEL_STATE_READY)
+ c->event = SPICE_CHANNEL_ERROR_IO;
+ else
+ c->event = SPICE_CHANNEL_ERROR_LINK;
+ }
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* we use an idle function to allow the coroutine to exit before we actually
+ * unref the object since the coroutine's state is part of the object */
+static gboolean spice_channel_delayed_unref(gpointer data)
+{
+ SpiceChannel *channel = SPICE_CHANNEL(data);
+ SpiceChannelPrivate *c = channel->priv;
+ gboolean was_ready = c->state == SPICE_CHANNEL_STATE_READY;
+ SpiceSession *session;
+
+ CHANNEL_DEBUG(channel, "Delayed unref channel %p", channel);
+
+ g_return_val_if_fail(c->coroutine.coroutine.exited == TRUE, FALSE);
+
+ c->state = SPICE_CHANNEL_STATE_UNCONNECTED;
+
+ session = spice_channel_get_session(channel);
+ if (session && spice_session_is_for_migration(session)) {
+ /* error during migration - abort migration */
+ spice_session_abort_migration(session);
+ return FALSE;
+ }
+
+ if (c->event != SPICE_CHANNEL_NONE) {
+ g_coroutine_signal_emit(channel, signals[SPICE_CHANNEL_EVENT], 0, c->event);
+ c->event = SPICE_CHANNEL_NONE;
+ g_clear_error(&c->error);
+ }
+
+ if (was_ready)
+ g_coroutine_signal_emit(channel, signals[SPICE_CHANNEL_EVENT], 0, SPICE_CHANNEL_CLOSED);
+
+ g_object_unref(G_OBJECT(data));
+
+ return FALSE;
+}
+
+static X509_LOOKUP_METHOD spice_x509_mem_lookup = {
+ "spice_x509_mem_lookup",
+ 0
+};
+
+static int spice_channel_load_ca(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ STACK_OF(X509_INFO) *inf;
+ X509_INFO *itmp;
+ X509_LOOKUP *lookup;
+ BIO *in;
+ int i, count = 0;
+ guint8 *ca;
+ guint size;
+ const gchar *ca_file;
+ int rc;
+
+ g_return_val_if_fail(c->ctx != NULL, 0);
+
+ lookup = X509_STORE_add_lookup(c->ctx->cert_store, &spice_x509_mem_lookup);
+ ca_file = spice_session_get_ca_file(c->session);
+ spice_session_get_ca(c->session, &ca, &size);
+
+ CHANNEL_DEBUG(channel, "Load CA, file: %s, data: %p", ca_file, ca);
+
+ if (ca != NULL) {
+ in = BIO_new_mem_buf(ca, size);
+ inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
+ BIO_free(in);
+
+ for (i = 0; i < sk_X509_INFO_num(inf); i++) {
+ itmp = sk_X509_INFO_value(inf, i);
+ if (itmp->x509) {
+ X509_STORE_add_cert(lookup->store_ctx, itmp->x509);
+ count++;
+ }
+ if (itmp->crl) {
+ X509_STORE_add_crl(lookup->store_ctx, itmp->crl);
+ count++;
+ }
+ }
+
+ sk_X509_INFO_pop_free(inf, X509_INFO_free);
+ }
+
+ if (ca_file != NULL) {
+ rc = SSL_CTX_load_verify_locations(c->ctx, ca_file, NULL);
+ if (rc != 1)
+ g_warning("loading ca certs from %s failed", ca_file);
+ else
+ count++;
+ }
+
+ if (count == 0) {
+ rc = SSL_CTX_set_default_verify_paths(c->ctx);
+ if (rc != 1)
+ g_warning("loading ca certs from default location failed");
+ else
+ count++;
+ }
+
+ return count;
+}
+
+/**
+ * spice_channel_get_error:
+ * @channel: a #SpiceChannel
+ *
+ * Retrieves the #GError currently set on channel, if the #SpiceChannel
+ * is in error state and can provide additional error details.
+ *
+ * Returns: the pointer to the error, or %NULL
+ * Since: 0.24
+ **/
+const GError* spice_channel_get_error(SpiceChannel *self)
+{
+ SpiceChannelPrivate *c;
+
+ g_return_val_if_fail(SPICE_IS_CHANNEL(self), NULL);
+ c = self->priv;
+
+ return c->error;
+}
+
+/* coroutine context */
+static void *spice_channel_coroutine(void *data)
+{
+ SpiceChannel *channel = SPICE_CHANNEL(data);
+ SpiceChannelPrivate *c = channel->priv;
+ guint verify;
+ int rc, delay_val = 1;
+ /* When some other SSL/TLS version becomes obsolete, add it to this
+ * variable. */
+ long ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
+
+ CHANNEL_DEBUG(channel, "Started background coroutine %p", &c->coroutine);
+
+ if (spice_session_get_client_provided_socket(c->session)) {
+ if (c->fd < 0) {
+ g_critical("fd not provided!");
+ c->event = SPICE_CHANNEL_ERROR_CONNECT;
+ goto cleanup;
+ }
+
+ if (!(c->sock = g_socket_new_from_fd(c->fd, NULL))) {
+ CHANNEL_DEBUG(channel, "Failed to open socket from fd %d", c->fd);
+ c->event = SPICE_CHANNEL_ERROR_CONNECT;
+ goto cleanup;
+ }
+
+ g_socket_set_blocking(c->sock, FALSE);
+ g_socket_set_keepalive(c->sock, TRUE);
+ c->conn = g_socket_connection_factory_create_connection(c->sock);
+ goto connected;
+ }
+
+
+reconnect:
+ c->conn = spice_session_channel_open_host(c->session, channel, &c->tls, &c->error);
+ if (c->conn == NULL) {
+ if (!c->error && !c->tls) {
+ CHANNEL_DEBUG(channel, "trying with TLS port");
+ c->tls = true; /* FIXME: does that really work with provided fd */
+ goto reconnect;
+ } else {
+ CHANNEL_DEBUG(channel, "Connect error");
+ c->event = SPICE_CHANNEL_ERROR_CONNECT;
+ goto cleanup;
+ }
+ }
+ c->sock = g_object_ref(g_socket_connection_get_socket(c->conn));
+
+ if (c->tls) {
+ c->ctx = SSL_CTX_new(SSLv23_method());
+ if (c->ctx == NULL) {
+ g_critical("SSL_CTX_new failed");
+ c->event = SPICE_CHANNEL_ERROR_TLS;
+ goto cleanup;
+ }
+
+ SSL_CTX_set_options(c->ctx, ssl_options);
+
+ verify = spice_session_get_verify(c->session);
+ if (verify &
+ (SPICE_SESSION_VERIFY_SUBJECT | SPICE_SESSION_VERIFY_HOSTNAME)) {
+ rc = spice_channel_load_ca(channel);
+ if (rc == 0) {
+ g_warning("no cert loaded");
+ if (verify & SPICE_SESSION_VERIFY_PUBKEY) {
+ g_warning("only pubkey active");
+ verify = SPICE_SESSION_VERIFY_PUBKEY;
+ } else {
+ c->event = SPICE_CHANNEL_ERROR_TLS;
+ goto cleanup;
+ }
+ }
+ }
+
+ {
+ const gchar *ciphers = spice_session_get_ciphers(c->session);
+ if (ciphers != NULL) {
+ rc = SSL_CTX_set_cipher_list(c->ctx, ciphers);
+ if (rc != 1)
+ g_warning("loading cipher list %s failed", ciphers);
+ }
+ }
+
+ c->ssl = SSL_new(c->ctx);
+ if (c->ssl == NULL) {
+ g_critical("SSL_new failed");
+ c->event = SPICE_CHANNEL_ERROR_TLS;
+ goto cleanup;
+ }
+
+
+ BIO *bio = bio_new_giostream(G_IO_STREAM(c->conn));
+ SSL_set_bio(c->ssl, bio, bio);
+
+ {
+ guint8 *pubkey;
+ guint pubkey_len;
+
+ spice_session_get_pubkey(c->session, &pubkey, &pubkey_len);
+ c->sslverify = spice_openssl_verify_new(c->ssl, verify,
+ spice_session_get_host(c->session),
+ (char*)pubkey, pubkey_len,
+ spice_session_get_cert_subject(c->session));
+ }
+
+ssl_reconnect:
+ rc = SSL_connect(c->ssl);
+ if (rc <= 0) {
+ rc = SSL_get_error(c->ssl, rc);
+ if (rc == SSL_ERROR_WANT_READ || rc == SSL_ERROR_WANT_WRITE) {
+ g_coroutine_socket_wait(&c->coroutine, c->sock, G_IO_OUT|G_IO_ERR|G_IO_HUP);
+ goto ssl_reconnect;
+ } else {
+ g_warning("%s: SSL_connect: %s",
+ c->name, ERR_error_string(rc, NULL));
+ c->event = SPICE_CHANNEL_ERROR_TLS;
+ goto cleanup;
+ }
+ }
+ }
+
+connected:
+ c->has_error = FALSE;
+ c->in = g_io_stream_get_input_stream(G_IO_STREAM(c->conn));
+ c->out = g_io_stream_get_output_stream(G_IO_STREAM(c->conn));
+
+ rc = setsockopt(g_socket_get_fd(c->sock), IPPROTO_TCP, TCP_NODELAY,
+ (const char*)&delay_val, sizeof(delay_val));
+ if ((rc != 0)
+#ifdef ENOTSUP
+ && (errno != ENOTSUP)
+#endif
+ ) {
+ g_warning("%s: could not set sockopt TCP_NODELAY: %s", c->name,
+ strerror(errno));
+ }
+
+ spice_channel_send_link(channel);
+ if (!spice_channel_recv_link_hdr(channel) ||
+ !spice_channel_recv_link_msg(channel) ||
+ !spice_channel_recv_auth(channel))
+ goto cleanup;
+
+ while (spice_channel_iterate(channel))
+ ;
+
+cleanup:
+ CHANNEL_DEBUG(channel, "Coroutine exit %s", c->name);
+
+ spice_channel_reset(channel, FALSE);
+
+ if (c->state == SPICE_CHANNEL_STATE_RECONNECTING ||
+ c->state == SPICE_CHANNEL_STATE_SWITCHING) {
+ g_warn_if_fail(c->event == SPICE_CHANNEL_NONE);
+ channel_connect(channel, c->tls);
+ g_object_unref(channel);
+ } else
+ g_idle_add(spice_channel_delayed_unref, data);
+
+ /* Co-routine exits now - the SpiceChannel object may no longer exist,
+ so don't do anything else now unless you like SEGVs */
+ return NULL;
+}
+
+static gboolean connect_delayed(gpointer data)
+{
+ SpiceChannel *channel = data;
+ SpiceChannelPrivate *c = channel->priv;
+ struct coroutine *co;
+
+ CHANNEL_DEBUG(channel, "Open coroutine starting %p", channel);
+ c->connect_delayed_id = 0;
+
+ co = &c->coroutine.coroutine;
+
+ co->stack_size = 16 << 20; /* 16Mb */
+ co->entry = spice_channel_coroutine;
+ co->release = NULL;
+
+ coroutine_init(co);
+ coroutine_yieldto(co, channel);
+
+ return FALSE;
+}
+
+/* any context */
+static gboolean channel_connect(SpiceChannel *channel, gboolean tls)
+{
+ SpiceChannelPrivate *c = channel->priv;
+
+ g_return_val_if_fail(c != NULL, FALSE);
+
+ if (c->session == NULL || c->channel_type == -1 || c->channel_id == -1) {
+ /* unset properties or unknown channel type */
+ g_warning("%s: channel setup incomplete", __FUNCTION__);
+ return false;
+ }
+
+ c->state = SPICE_CHANNEL_STATE_CONNECTING;
+ c->tls = tls;
+
+ if (spice_session_get_client_provided_socket(c->session)) {
+ if (c->fd == -1) {
+ CHANNEL_DEBUG(channel, "requesting fd");
+ /* FIXME: no way for client to provide fd atm. */
+ /* It could either chain on parent channel.. */
+ /* or register migration channel on parent session, or ? */
+ g_signal_emit(channel, signals[SPICE_CHANNEL_OPEN_FD], 0, c->tls);
+ return true;
+ }
+ }
+
+ c->xmit_queue_blocked = FALSE;
+
+ g_return_val_if_fail(c->sock == NULL, FALSE);
+ g_object_ref(G_OBJECT(channel)); /* Unref'd when co-routine exits */
+
+ /* we connect in idle, to let previous coroutine exit, if present */
+ c->connect_delayed_id = g_idle_add(connect_delayed, channel);
+
+ return true;
+}
+
+/**
+ * spice_channel_connect:
+ * @channel: a #SpiceChannel
+ *
+ * Connect the channel, using #SpiceSession connection informations
+ *
+ * Returns: %TRUE on success.
+ **/
+gboolean spice_channel_connect(SpiceChannel *channel)
+{
+ g_return_val_if_fail(SPICE_IS_CHANNEL(channel), FALSE);
+ SpiceChannelPrivate *c = channel->priv;
+
+ if (c->state >= SPICE_CHANNEL_STATE_CONNECTING)
+ return TRUE;
+
+ g_return_val_if_fail(channel->priv->fd == -1, FALSE);
+
+ return channel_connect(channel, FALSE);
+}
+
+/**
+ * spice_channel_open_fd:
+ * @channel: a #SpiceChannel
+ * @fd: a file descriptor (socket) or -1.
+ * request mechanism
+ *
+ * Connect the channel using @fd socket.
+ *
+ * If @fd is -1, a valid fd will be requested later via the
+ * SpiceChannel::open-fd signal.
+ *
+ * Returns: %TRUE on success.
+ **/
+gboolean spice_channel_open_fd(SpiceChannel *channel, int fd)
+{
+ SpiceChannelPrivate *c;
+
+ g_return_val_if_fail(SPICE_IS_CHANNEL(channel), FALSE);
+ g_return_val_if_fail(channel->priv != NULL, FALSE);
+ g_return_val_if_fail(channel->priv->fd == -1, FALSE);
+ g_return_val_if_fail(fd >= -1, FALSE);
+
+ c = channel->priv;
+ if (c->state > SPICE_CHANNEL_STATE_CONNECTING) {
+ g_warning("Invalid channel_connect state: %u", c->state);
+ return true;
+ }
+
+ c->fd = fd;
+
+ return channel_connect(channel, FALSE);
+}
+
+/* system or coroutine context */
+static void channel_reset(SpiceChannel *channel, gboolean migrating)
+{
+ SpiceChannelPrivate *c = channel->priv;
+
+ CHANNEL_DEBUG(channel, "channel reset");
+ if (c->connect_delayed_id) {
+ g_source_remove(c->connect_delayed_id);
+ c->connect_delayed_id = 0;
+ }
+
+#ifdef HAVE_SASL
+ if (c->sasl_conn) {
+ sasl_dispose(&c->sasl_conn);
+ c->sasl_conn = NULL;
+ c->sasl_decoded_offset = c->sasl_decoded_length = 0;
+ }
+#endif
+
+ g_clear_pointer(&c->sslverify, spice_openssl_verify_free);
+ g_clear_pointer(&c->ssl, SSL_free);
+ g_clear_pointer(&c->ctx, SSL_CTX_free);
+
+ g_clear_object(&c->conn);
+ g_clear_object(&c->sock);
+
+ c->fd = -1;
+
+ c->auth_needs_username = FALSE;
+ c->auth_needs_password = FALSE;
+
+ g_clear_pointer(&c->peer_msg, g_free);
+ c->peer_pos = 0;
+
+ g_mutex_lock(&c->xmit_queue_lock);
+ c->xmit_queue_blocked = TRUE; /* Disallow queuing new messages */
+ gboolean was_empty = g_queue_is_empty(&c->xmit_queue);
+ g_queue_foreach(&c->xmit_queue, (GFunc)spice_msg_out_unref, NULL);
+ g_queue_clear(&c->xmit_queue);
+ if (c->xmit_queue_wakeup_id) {
+ g_source_remove(c->xmit_queue_wakeup_id);
+ c->xmit_queue_wakeup_id = 0;
+ }
+ g_mutex_unlock(&c->xmit_queue_lock);
+ spice_channel_flushed(channel, was_empty);
+
+ g_array_set_size(c->remote_common_caps, 0);
+ g_array_set_size(c->remote_caps, 0);
+ g_array_set_size(c->common_caps, 0);
+ /* Restore our default capabilities in case the channel gets re-used */
+ spice_channel_set_common_capability(channel, SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION);
+ spice_channel_set_common_capability(channel, SPICE_COMMON_CAP_MINI_HEADER);
+ spice_channel_reset_capabilities(channel);
+
+ if (c->state == SPICE_CHANNEL_STATE_SWITCHING)
+ spice_session_set_migration_state(spice_channel_get_session(channel),
+ SPICE_SESSION_MIGRATION_NONE);
+}
+
+/* system or coroutine context */
+G_GNUC_INTERNAL
+void spice_channel_reset(SpiceChannel *channel, gboolean migrating)
+{
+ CHANNEL_DEBUG(channel, "reset %s", migrating ? "migrating" : "");
+ SPICE_CHANNEL_GET_CLASS(channel)->channel_reset(channel, migrating);
+}
+
+/**
+ * spice_channel_disconnect:
+ * @channel: a #SpiceChannel
+ * @reason: a channel event emitted on main context (or #SPICE_CHANNEL_NONE)
+ *
+ * Close the socket and reset connection specific data. Finally, emit
+ * @reason #SpiceChannel::channel-event on main context if not
+ * #SPICE_CHANNEL_NONE.
+ **/
+void spice_channel_disconnect(SpiceChannel *channel, SpiceChannelEvent reason)
+{
+ SpiceChannelPrivate *c;
+
+ CHANNEL_DEBUG(channel, "channel disconnect %u", reason);
+
+ g_return_if_fail(SPICE_IS_CHANNEL(channel));
+ g_return_if_fail(channel->priv != NULL);
+
+ c = channel->priv;
+
+ if (c->state == SPICE_CHANNEL_STATE_UNCONNECTED)
+ return;
+
+ if (reason == SPICE_CHANNEL_SWITCHING)
+ c->state = SPICE_CHANNEL_STATE_SWITCHING;
+
+ c->has_error = TRUE; /* break the loop */
+
+ if (c->state == SPICE_CHANNEL_STATE_MIGRATING) {
+ c->state = SPICE_CHANNEL_STATE_READY;
+ } else
+ spice_channel_wakeup(channel, TRUE);
+
+ if (reason != SPICE_CHANNEL_NONE)
+ g_signal_emit(G_OBJECT(channel), signals[SPICE_CHANNEL_EVENT], 0, reason);
+}
+
+static gboolean test_capability(GArray *caps, guint32 cap)
+{
+ guint32 c, word_index = cap / 32;
+ gboolean ret;
+
+ if (caps == NULL)
+ return FALSE;
+
+ if (caps->len < word_index + 1)
+ return FALSE;
+
+ c = g_array_index(caps, guint32, word_index);
+ ret = (c & (1 << (cap % 32))) != 0;
+
+ SPICE_DEBUG("test cap %u in 0x%X: %s", cap, c, ret ? "yes" : "no");
+ return ret;
+}
+
+/**
+ * spice_channel_test_capability:
+ * @channel: a #SpiceChannel
+ * @cap: a capability
+ *
+ * Test availability of remote "channel kind capability".
+ *
+ * Returns: %TRUE if @cap (channel kind capability) is available.
+ **/
+gboolean spice_channel_test_capability(SpiceChannel *self, guint32 cap)
+{
+ SpiceChannelPrivate *c;
+
+ g_return_val_if_fail(SPICE_IS_CHANNEL(self), FALSE);
+
+ c = self->priv;
+ return test_capability(c->remote_caps, cap);
+}
+
+/**
+ * spice_channel_test_common_capability:
+ * @channel: a #SpiceChannel
+ * @cap: a capability
+ *
+ * Test availability of remote "common channel capability".
+ *
+ * Returns: %TRUE if @cap (common channel capability) is available.
+ **/
+gboolean spice_channel_test_common_capability(SpiceChannel *self, guint32 cap)
+{
+ SpiceChannelPrivate *c;
+
+ g_return_val_if_fail(SPICE_IS_CHANNEL(self), FALSE);
+
+ c = self->priv;
+ return test_capability(c->remote_common_caps, cap);
+}
+
+static void set_capability(GArray *caps, guint32 cap)
+{
+ guint word_index = cap / 32;
+
+ g_return_if_fail(caps != NULL);
+
+ if (caps->len <= word_index)
+ g_array_set_size(caps, word_index + 1);
+
+ g_array_index(caps, guint32, word_index) =
+ g_array_index(caps, guint32, word_index) | (1 << (cap % 32));
+}
+
+/**
+ * spice_channel_set_capability:
+ * @channel: a #SpiceChannel
+ * @cap: a capability
+ *
+ * Enable specific channel-kind capability.
+ * Deprecated: 0.13: this function has been removed
+ **/
+#undef spice_channel_set_capability
+void spice_channel_set_capability(SpiceChannel *channel, guint32 cap)
+{
+ SpiceChannelPrivate *c;
+
+ g_return_if_fail(SPICE_IS_CHANNEL(channel));
+
+ c = channel->priv;
+ set_capability(c->caps, cap);
+}
+
+G_GNUC_INTERNAL
+void spice_caps_set(GArray *caps, guint32 cap, const gchar *desc)
+{
+ g_return_if_fail(caps != NULL);
+ g_return_if_fail(desc != NULL);
+
+ if (g_strcmp0(g_getenv(desc), "0") == 0)
+ return;
+
+ set_capability(caps, cap);
+}
+
+G_GNUC_INTERNAL
+SpiceSession* spice_channel_get_session(SpiceChannel *channel)
+{
+ g_return_val_if_fail(SPICE_IS_CHANNEL(channel), NULL);
+
+ return channel->priv->session;
+}
+
+G_GNUC_INTERNAL
+enum spice_channel_state spice_channel_get_state(SpiceChannel *channel)
+{
+ g_return_val_if_fail(SPICE_IS_CHANNEL(channel),
+ SPICE_CHANNEL_STATE_UNCONNECTED);
+
+ return channel->priv->state;
+}
+
+G_GNUC_INTERNAL
+guint64 spice_channel_get_queue_size (SpiceChannel *channel)
+{
+ guint64 size;
+ SpiceChannelPrivate *c = channel->priv;
+ g_mutex_lock(&c->xmit_queue_lock);
+ size = c->xmit_queue_size;
+ g_mutex_unlock(&c->xmit_queue_lock);
+ return size;
+}
+
+G_GNUC_INTERNAL
+void spice_channel_swap(SpiceChannel *channel, SpiceChannel *swap, gboolean swap_msgs)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ SpiceChannelPrivate *s = swap->priv;
+
+ g_return_if_fail(c != NULL);
+ g_return_if_fail(s != NULL);
+
+ g_return_if_fail(s->session != NULL);
+ g_return_if_fail(s->sock != NULL);
+
+#define SWAP(Field) ({ \
+ typeof (c->Field) Field = c->Field; \
+ c->Field = s->Field; \
+ s->Field = Field; \
+})
+
+ /* TODO: split channel in 2 objects: a controller and a swappable
+ state object */
+ SWAP(sock);
+ SWAP(conn);
+ SWAP(in);
+ SWAP(out);
+ SWAP(ctx);
+ SWAP(ssl);
+ SWAP(sslverify);
+ SWAP(tls);
+ SWAP(use_mini_header);
+ if (swap_msgs) {
+ SWAP(xmit_queue);
+ SWAP(xmit_queue_blocked);
+ SWAP(in_serial);
+ SWAP(out_serial);
+ }
+ SWAP(caps);
+ SWAP(common_caps);
+ SWAP(remote_caps);
+ SWAP(remote_common_caps);
+#ifdef HAVE_SASL
+ SWAP(sasl_conn);
+ SWAP(sasl_decoded);
+ SWAP(sasl_decoded_length);
+ SWAP(sasl_decoded_offset);
+#endif
+}
+
+/* coroutine context */
+static void spice_channel_handle_msg(SpiceChannel *channel, SpiceMsgIn *msg)
+{
+ SpiceChannelClass *klass = SPICE_CHANNEL_GET_CLASS(channel);
+ int type = spice_msg_in_type(msg);
+ spice_msg_handler handler;
+
+ g_return_if_fail(type < klass->priv->handlers->len);
+ if (type > SPICE_MSG_BASE_LAST && channel->priv->disable_channel_msg)
+ return;
+
+ handler = g_array_index(klass->priv->handlers, spice_msg_handler, type);
+ g_return_if_fail(handler != NULL);
+ handler(channel, msg);
+}
+
+static void spice_channel_reset_capabilities(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ g_array_set_size(c->caps, 0);
+
+ if (SPICE_CHANNEL_GET_CLASS(channel)->channel_reset_capabilities) {
+ SPICE_CHANNEL_GET_CLASS(channel)->channel_reset_capabilities(channel);
+ }
+}
+
+static void spice_channel_send_migration_handshake(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+
+ if (SPICE_CHANNEL_GET_CLASS(channel)->channel_send_migration_handshake) {
+ SPICE_CHANNEL_GET_CLASS(channel)->channel_send_migration_handshake(channel);
+ } else {
+ c->state = SPICE_CHANNEL_STATE_MIGRATING;
+ }
+}
+
+/**
+ * spice_channel_flush_async:
+ * @channel: a #SpiceChannel
+ * @cancellable: (allow-none): optional GCancellable object, %NULL to ignore
+ * @callback: (scope async): callback to call when the request is satisfied
+ * @user_data: (closure): the data to pass to callback function
+ *
+ * Forces an asynchronous write of all user-space buffered data for
+ * the given channel.
+ *
+ * When the operation is finished callback will be called. You can
+ * then call spice_channel_flush_finish() to get the result of the
+ * operation.
+ *
+ * Since: 0.15
+ **/
+void spice_channel_flush_async(SpiceChannel *self, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data)
+{
+ GTask *task;
+ SpiceChannelPrivate *c;
+ gboolean was_empty;
+
+ g_return_if_fail(SPICE_IS_CHANNEL(self));
+ c = self->priv;
+
+ if (c->state != SPICE_CHANNEL_STATE_READY) {
+ g_task_report_new_error(self, callback, user_data,
+ spice_channel_flush_async,
+ SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "The channel is not ready yet");
+ return;
+ }
+
+ task = g_task_new(self, cancellable, callback, user_data);
+
+ g_mutex_lock(&c->xmit_queue_lock);
+ was_empty = g_queue_is_empty(&c->xmit_queue);
+ g_mutex_unlock(&c->xmit_queue_lock);
+ if (was_empty) {
+ g_task_return_boolean(task, TRUE);
+ g_object_unref(task);
+ return;
+ }
+
+ c->flushing = g_slist_append(c->flushing, task);
+}
+
+/**
+ * spice_channel_flush_finish:
+ * @channel: a #SpiceChannel
+ * @result: a #GAsyncResult
+ * @error: a #GError location to store the error occurring, or %NULL
+ * to ignore.
+ *
+ * Finishes flushing a channel.
+ *
+ * Returns: %TRUE if flush operation succeeded, %FALSE otherwise.
+ * Since: 0.15
+ **/
+gboolean spice_channel_flush_finish(SpiceChannel *self, GAsyncResult *result,
+ GError **error)
+{
+ GTask *task;
+
+ g_return_val_if_fail(SPICE_IS_CHANNEL(self), FALSE);
+ g_return_val_if_fail(result != NULL, FALSE);
+
+ task = G_TASK(result);
+
+ g_return_val_if_fail(g_task_is_valid(task, self),
+ FALSE);
+
+ CHANNEL_DEBUG(self, "flushed finished!");
+ return g_task_propagate_boolean(task, error);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_CHANNEL_H__
+#define __SPICE_CLIENT_CHANNEL_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include <gio/gio.h>
+
+#include "spice-types.h"
+#include "spice-glib-enums.h"
+#include "spice-util.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_CHANNEL (spice_channel_get_type ())
+#define SPICE_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_CHANNEL, SpiceChannel))
+#define SPICE_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_CHANNEL, SpiceChannelClass))
+#define SPICE_IS_CHANNEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_CHANNEL))
+#define SPICE_IS_CHANNEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_CHANNEL))
+#define SPICE_CHANNEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_CHANNEL, SpiceChannelClass))
+
+typedef struct _SpiceMsgIn SpiceMsgIn;
+typedef struct _SpiceMsgOut SpiceMsgOut;
+
+/**
+ * SpiceChannelEvent:
+ * @SPICE_CHANNEL_NONE: no event, or ignored event
+ * @SPICE_CHANNEL_OPENED: connection is authentified and ready
+ * @SPICE_CHANNEL_SWITCHING: disconnecting from the current host and connecting to the target host.
+ * @SPICE_CHANNEL_CLOSED: connection is closed normally (sent if channel was ready)
+ * @SPICE_CHANNEL_ERROR_CONNECT: connection error
+ * @SPICE_CHANNEL_ERROR_TLS: SSL error
+ * @SPICE_CHANNEL_ERROR_LINK: error during link process
+ * @SPICE_CHANNEL_ERROR_AUTH: authentication error
+ * @SPICE_CHANNEL_ERROR_IO: IO error
+ *
+ * An event, emitted by #SpiceChannel::channel-event signal.
+ **/
+typedef enum
+{
+ SPICE_CHANNEL_NONE = 0,
+ SPICE_CHANNEL_OPENED = 10,
+ SPICE_CHANNEL_SWITCHING,
+ SPICE_CHANNEL_CLOSED,
+ SPICE_CHANNEL_ERROR_CONNECT = 20,
+ SPICE_CHANNEL_ERROR_TLS,
+ SPICE_CHANNEL_ERROR_LINK,
+ SPICE_CHANNEL_ERROR_AUTH,
+ SPICE_CHANNEL_ERROR_IO,
+} SpiceChannelEvent;
+
+/**
+ * SpiceChannel:
+ *
+ * The #SpiceChannel struct is opaque and should not be accessed directly.
+ */
+struct _SpiceChannel
+{
+ GObject parent;
+ SpiceChannelPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+typedef struct _SpiceChannelClassPrivate SpiceChannelClassPrivate;
+
+/**
+ * SpiceChannelClass:
+ * @parent_class: Parent class.
+ * @channel_event: Signal class handler for the #SpiceChannel::channel_event signal.
+ * @open_fd: Signal class handler for the #SpiceChannel::open_fd signal.
+ *
+ * Class structure for #SpiceChannel.
+ */
+struct _SpiceChannelClass
+{
+ GObjectClass parent_class;
+
+ /*< public >*/
+ /* signals, main context */
+ void (*channel_event)(SpiceChannel *channel, SpiceChannelEvent event);
+ void (*open_fd)(SpiceChannel *channel, int with_tls);
+
+ /*< private >*/
+ /* virtual methods, coroutine context */
+ void (*handle_msg)(SpiceChannel *channel, SpiceMsgIn *msg);
+ void (*channel_up)(SpiceChannel *channel);
+ void (*iterate_write)(SpiceChannel *channel);
+ void (*iterate_read)(SpiceChannel *channel);
+
+ /*< private >*/
+ /* virtual method, any context */
+ gpointer deprecated;
+ void (*channel_reset)(SpiceChannel *channel, gboolean migrating);
+ void (*channel_reset_capabilities)(SpiceChannel *channel);
+
+ /*< private >*/
+ /* virtual methods, coroutine context */
+ void (*channel_send_migration_handshake)(SpiceChannel *channel);
+
+ SpiceChannelClassPrivate *priv;
+ /*
+ * If adding fields to this struct, remove corresponding
+ * amount of padding to avoid changing overall struct size
+ */
+ gchar _spice_reserved[SPICE_RESERVED_PADDING - 2 * sizeof(void *)];
+};
+
+GType spice_channel_get_type(void);
+
+typedef void (*spice_msg_handler)(SpiceChannel *channel, SpiceMsgIn *in);
+
+SpiceChannel *spice_channel_new(SpiceSession *s, int type, int id);
+gboolean spice_channel_connect(SpiceChannel *channel);
+gboolean spice_channel_open_fd(SpiceChannel *channel, int fd);
+void spice_channel_disconnect(SpiceChannel *channel, SpiceChannelEvent reason);
+gboolean spice_channel_test_capability(SpiceChannel *channel, guint32 cap);
+gboolean spice_channel_test_common_capability(SpiceChannel *channel, guint32 cap);
+void spice_channel_flush_async(SpiceChannel *channel, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+gboolean spice_channel_flush_finish(SpiceChannel *channel, GAsyncResult *result, GError **error);
+#ifndef SPICE_DISABLE_DEPRECATED
+SPICE_DEPRECATED
+void spice_channel_set_capability(SpiceChannel *channel, guint32 cap);
+SPICE_DEPRECATED
+void spice_channel_destroy(SpiceChannel *channel);
+#endif
+
+const gchar* spice_channel_type_to_string(gint type);
+gint spice_channel_string_to_type(const gchar *str);
+
+const GError* spice_channel_get_error(SpiceChannel *channel);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_CHANNEL_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011,2012 Red Hat, Inc.
+ Copyright (C) 2009 Kay Sievers <kay.sievers@vrfy.org>
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <gio/gunixinputstream.h>
+#include <polkit/polkit.h>
+#include <acl/libacl.h>
+
+#define FATAL_ERROR(...) \
+ do { \
+ /* We print the error both to stdout, for the app invoking us and \
+ stderr for the end user */ \
+ fprintf(stdout, "Error " __VA_ARGS__); \
+ fprintf(stderr, "spice-client-glib-usb-helper: Error " __VA_ARGS__); \
+ exit_status = 1; \
+ cleanup(); \
+ } while (0)
+
+#define ERROR(...) \
+ do { \
+ fprintf(stdout, __VA_ARGS__); \
+ cleanup(); \
+ } while (0)
+
+enum state {
+ STATE_WAITING_FOR_BUS_N_DEV,
+ STATE_WAITING_FOR_POL_KIT,
+ STATE_WAITING_FOR_STDIN_EOF,
+};
+
+static enum state state = STATE_WAITING_FOR_BUS_N_DEV;
+static int exit_status;
+static int busnum, devnum;
+static char path[PATH_MAX];
+static GMainLoop *loop;
+static GDataInputStream *stdin_stream;
+static GCancellable *polkit_cancellable;
+static PolkitSubject *subject;
+static PolkitAuthority *authority;
+
+/*
+ * This function is a copy of the same function in udev, written by Kay
+ * Sievers, you can find it in udev in extras/udev-acl/udev-acl.c
+ */
+static int set_facl(const char* filename, uid_t uid, int add)
+{
+ int get;
+ acl_t acl;
+ acl_entry_t entry = NULL;
+ acl_entry_t e;
+ acl_permset_t permset;
+ int ret;
+
+ /* don't touch ACLs for root */
+ if (uid == 0)
+ return 0;
+
+ /* read current record */
+ acl = acl_get_file(filename, ACL_TYPE_ACCESS);
+ if (!acl)
+ return -1;
+
+ /* locate ACL_USER entry for uid */
+ get = acl_get_entry(acl, ACL_FIRST_ENTRY, &e);
+ while (get == 1) {
+ acl_tag_t t;
+
+ acl_get_tag_type(e, &t);
+ if (t == ACL_USER) {
+ uid_t *u;
+
+ u = (uid_t*)acl_get_qualifier(e);
+ if (u == NULL) {
+ ret = -1;
+ goto out;
+ }
+ if (*u == uid) {
+ entry = e;
+ acl_free(u);
+ break;
+ }
+ acl_free(u);
+ }
+
+ get = acl_get_entry(acl, ACL_NEXT_ENTRY, &e);
+ }
+
+ /* remove ACL_USER entry for uid */
+ if (!add) {
+ if (entry == NULL) {
+ ret = 0;
+ goto out;
+ }
+ acl_delete_entry(acl, entry);
+ goto update;
+ }
+
+ /* create ACL_USER entry for uid */
+ if (entry == NULL) {
+ ret = acl_create_entry(&acl, &entry);
+ if (ret != 0)
+ goto out;
+ acl_set_tag_type(entry, ACL_USER);
+ acl_set_qualifier(entry, &uid);
+ }
+
+ /* add permissions for uid */
+ acl_get_permset(entry, &permset);
+ acl_add_perm(permset, ACL_READ|ACL_WRITE);
+update:
+ /* update record */
+ acl_calc_mask(&acl);
+ ret = acl_set_file(filename, ACL_TYPE_ACCESS, acl);
+
+out:
+ acl_free(acl);
+ return ret;
+}
+
+static void cleanup(void)
+{
+ g_cancellable_cancel(polkit_cancellable);
+
+ if (state == STATE_WAITING_FOR_STDIN_EOF)
+ set_facl(path, getuid(), 0);
+
+ if (loop)
+ g_main_loop_quit(loop);
+}
+
+/* Not available in polkit < 0.101 */
+#ifndef HAVE_POLKIT_AUTHORIZATION_RESULT_GET_DISMISSED
+static gboolean
+polkit_authorization_result_get_dismissed(PolkitAuthorizationResult *result)
+{
+ gboolean ret;
+ PolkitDetails *details;
+
+ g_return_val_if_fail(POLKIT_IS_AUTHORIZATION_RESULT(result), FALSE);
+
+ ret = FALSE;
+ details = polkit_authorization_result_get_details(result);
+ if (details != NULL && polkit_details_lookup(details, "polkit.dismissed"))
+ ret = TRUE;
+
+ return ret;
+}
+#endif
+
+static void check_authorization_cb(PolkitAuthority *authority,
+ GAsyncResult *res, gpointer data)
+{
+ PolkitAuthorizationResult *result;
+ GError *err = NULL;
+ struct stat stat_buf;
+
+ g_clear_object(&polkit_cancellable);
+
+ result = polkit_authority_check_authorization_finish(authority, res, &err);
+ if (err) {
+ FATAL_ERROR("PoliciKit error: %s\n", err->message);
+ g_error_free(err);
+ return;
+ }
+
+ if (polkit_authorization_result_get_dismissed(result)) {
+ ERROR("CANCELED\n");
+ return;
+ }
+
+ if (!polkit_authorization_result_get_is_authorized(result)) {
+ ERROR("Not authorized\n");
+ return;
+ }
+
+ snprintf(path, PATH_MAX, "/dev/bus/usb/%03d/%03d", busnum, devnum);
+
+ if (stat(path, &stat_buf) != 0) {
+ FATAL_ERROR("statting %s: %s\n", path, strerror(errno));
+ return;
+ }
+ if (!S_ISCHR(stat_buf.st_mode)) {
+ FATAL_ERROR("%s is not a character device\n", path);
+ return;
+ }
+
+ if (set_facl(path, getuid(), 1)) {
+ FATAL_ERROR("setting facl: %s\n", strerror(errno));
+ return;
+ }
+
+ fprintf(stdout, "SUCCESS\n");
+ fflush(stdout);
+ state = STATE_WAITING_FOR_STDIN_EOF;
+}
+
+static void stdin_read_complete(GObject *src, GAsyncResult *res, gpointer data)
+{
+ char *s, *ep;
+ GError *err = NULL;
+ gsize len;
+
+ s = g_data_input_stream_read_line_finish(G_DATA_INPUT_STREAM(src), res,
+ &len, &err);
+ if (!s) {
+ if (err) {
+ FATAL_ERROR("Reading from stdin: %s\n", err->message);
+ g_error_free(err);
+ return;
+ }
+
+ switch (state) {
+ case STATE_WAITING_FOR_BUS_N_DEV:
+ FATAL_ERROR("EOF while waiting for bus and device num\n");
+ break;
+ case STATE_WAITING_FOR_POL_KIT:
+ ERROR("Cancelled while waiting for authorization\n");
+ break;
+ case STATE_WAITING_FOR_STDIN_EOF:
+ cleanup();
+ break;
+ }
+ return;
+ }
+
+ switch (state) {
+ case STATE_WAITING_FOR_BUS_N_DEV:
+ busnum = strtol(s, &ep, 10);
+ if (!isspace(*ep)) {
+ FATAL_ERROR("Invalid busnum / devnum: %s\n", s);
+ break;
+ }
+ devnum = strtol(ep, &ep, 10);
+ if (*ep != '\0') {
+ FATAL_ERROR("Invalid busnum / devnum: %s\n", s);
+ break;
+ }
+
+ /*
+ * The set_facl() call is a no-op for root, so no need to ask PolKit
+ * and then if ok call set_facl(), when called by a root process.
+ */
+ if (getuid() != 0) {
+ polkit_cancellable = g_cancellable_new();
+ polkit_authority_check_authorization(
+ authority, subject, "org.spice-space.lowlevelusbaccess", NULL,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
+ polkit_cancellable,
+ (GAsyncReadyCallback)check_authorization_cb, NULL);
+ state = STATE_WAITING_FOR_POL_KIT;
+ } else {
+ fprintf(stdout, "SUCCESS\n");
+ fflush(stdout);
+ state = STATE_WAITING_FOR_STDIN_EOF;
+ }
+
+ g_data_input_stream_read_line_async(stdin_stream, G_PRIORITY_DEFAULT,
+ NULL, stdin_read_complete, NULL);
+ break;
+ default:
+ FATAL_ERROR("Unexpected extra input in state %u: %s\n", state, s);
+ }
+ g_free(s);
+}
+
+/* Fix for polkit 0.97 and later */
+#ifndef HAVE_POLKIT_AUTHORITY_GET_SYNC
+static PolkitAuthority *
+polkit_authority_get_sync (GCancellable *cancellable, GError **error)
+{
+ PolkitAuthority *authority;
+
+ authority = polkit_authority_get ();
+ if (!authority)
+ g_set_error (error, 0, 0, "failed to get the PolicyKit authority");
+
+ return authority;
+}
+#endif
+
+#ifndef HAVE_CLEARENV
+extern char **environ;
+
+static int
+clearenv (void)
+{
+ if (environ != NULL)
+ environ[0] = NULL;
+ return 0;
+}
+#endif
+
+int main(void)
+{
+ pid_t parent_pid;
+ GInputStream *stdin_unix_stream;
+
+ /* Nuke the environment to get a well-known and sanitized
+ * environment to avoid attacks via e.g. the DBUS_SYSTEM_BUS_ADDRESS
+ * environment variable and similar.
+ */
+ if (clearenv () != 0) {
+ FATAL_ERROR("Error clearing environment: %s\n", g_strerror (errno));
+ return 1;
+ }
+
+ loop = g_main_loop_new(NULL, FALSE);
+
+ authority = polkit_authority_get_sync(NULL, NULL);
+ parent_pid = getppid ();
+ if (parent_pid == 1) {
+ FATAL_ERROR("Parent process was reaped by init(1)\n");
+ return 1;
+ }
+ /* Do what pkexec does */
+ subject = polkit_unix_process_new_for_owner(parent_pid, 0, getuid ());
+
+ stdin_unix_stream = g_unix_input_stream_new(STDIN_FILENO, 0);
+ stdin_stream = g_data_input_stream_new(stdin_unix_stream);
+ g_data_input_stream_set_newline_type(stdin_stream,
+ G_DATA_STREAM_NEWLINE_TYPE_LF);
+ g_clear_object(&stdin_unix_stream);
+ g_data_input_stream_read_line_async(stdin_stream, G_PRIORITY_DEFAULT, NULL,
+ stdin_read_complete, NULL);
+
+ g_main_loop_run(loop);
+
+ g_clear_object(&polkit_cancellable);
+ g_object_unref(stdin_stream);
+ g_object_unref(authority);
+ g_object_unref(subject);
+ g_main_loop_unref(loop);
+
+ return exit_status;
+}
--- /dev/null
+(define-method set_display
+ (of-object "SpiceMainChannel")
+ (c-name "spice_main_set_display")
+ (return-type "none")
+ (parameters
+ '("int" "id")
+ '("int" "x")
+ '("int" "y")
+ '("int" "width")
+ '("int" "height")
+ )
+)
+
+(define-method clipboard_grab
+ (of-object "SpiceMainChannel")
+ (c-name "spice_main_clipboard_grab")
+ (return-type "none")
+ (parameters
+ '("int*" "types")
+ '("int" "ntypes")
+ )
+)
+
+(define-method clipboard_release
+ (of-object "SpiceMainChannel")
+ (c-name "spice_main_clipboard_release")
+ (return-type "none")
+)
+
+(define-method motion
+ (of-object "SpiceInputsChannel")
+ (c-name "spice_inputs_motion")
+ (return-type "none")
+ (parameters
+ '("gint" "dx")
+ '("gint" "dy")
+ '("gint" "button_state")
+ )
+)
+
+(define-method position
+ (of-object "SpiceInputsChannel")
+ (c-name "spice_inputs_position")
+ (return-type "none")
+ (parameters
+ '("gint" "x")
+ '("gint" "y")
+ '("gint" "display")
+ '("gint" "button_state")
+ )
+)
+
+(define-method button_press
+ (of-object "SpiceInputsChannel")
+ (c-name "spice_inputs_button_press")
+ (return-type "none")
+ (parameters
+ '("gint" "button")
+ '("gint" "button_state")
+ )
+)
+
+(define-method button_release
+ (of-object "SpiceInputsChannel")
+ (c-name "spice_inputs_button_release")
+ (return-type "none")
+ (parameters
+ '("gint" "button")
+ '("gint" "button_state")
+ )
+)
+
+(define-method key_press
+ (of-object "SpiceInputsChannel")
+ (c-name "spice_inputs_key_press")
+ (return-type "none")
+ (parameters
+ '("guint" "keyval")
+ )
+)
+
+(define-method key_release
+ (of-object "SpiceInputsChannel")
+ (c-name "spice_inputs_key_release")
+ (return-type "none")
+ (parameters
+ '("guint" "keyval")
+ )
+)
+
+(define-method set_key_locks
+ (of-object "SpiceInputsChannel")
+ (c-name "spice_inputs_set_key_locks")
+ (return-type "none")
+ (parameters
+ '("guint" "locks")
+ )
+)
+
+(define-enum ClientError
+ (in-module "Spice")
+ (c-name "SpiceClientError")
+ (values
+ '("failed" "SPICE_CLIENT_ERROR_FAILED")
+ )
+)
+
+(define-function spice_audio_new
+ (c-name "spice_audio_new")
+ (is-constructor-of "SpiceAudio")
+ (return-type "SpiceAudio*")
+ (parameters
+ '("SpiceSession*" "session")
+ '("GMainContext*" "context")
+ '("const-char*" "name")
+ )
+)
--- /dev/null
+/*
+ Copyright (C) 2015 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_GTK_H__
+#define __SPICE_CLIENT_GTK_H__
+
+#include "spice-client.h"
+
+#define __SPICE_CLIENT_GTK_H_INSIDE__
+
+#include "spice-grabsequence.h"
+#include "spice-gtk-session.h"
+#include "spice-widget-enums.h"
+#include "spice-widget.h"
+#include "usb-device-widget.h"
+
+#undef __SPICE_CLIENT_GTK_H_INSIDE__
+
+#endif /* __SPICE_CLIENT_GTK_H__ */
--- /dev/null
+%%
+headers
+#include <Python.h>
+#include "pygobject.h"
+#include "spice-common.h"
+#include "spice-widget.h"
+#include "spice-gtk-session.h"
+#include "spice-audio.h"
+#include "usb-device-widget.h"
+%%
+modulename spice_client_gtk
+%%
+import gobject.GObject as PyGObject_Type
+import gtk.DrawingArea as PyGtkDrawingArea_Type
+import gtk.Widget as PyGtkWidget_Type
+import gtk.VBox as PyGtkVBox_Type
+%%
+ignore-glob
+ *_get_type
+%%
+%%
+override spice_display_send_keys kwargs
+static PyObject*
+_wrap_spice_display_send_keys(PyGObject *self,
+ PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"keys", "kind", NULL};
+ PyObject *keyList;
+ int kind = SPICE_DISPLAY_KEY_EVENT_CLICK;
+ int i, len;
+ guint *keys;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O|I:SpiceDisplay.send_keys", kwlist,
+ &keyList, &kind))
+ return NULL;
+
+ if (!PyList_Check(keyList))
+ return NULL;
+
+ len = PyList_Size(keyList);
+ keys = g_malloc0(sizeof(guint)*len);
+
+ for (i = 0 ; i < len ; i++) {
+ PyObject *val;
+ char *sym;
+ val = PyList_GetItem(keyList, i);
+ sym = PyString_AsString(val);
+ if (!sym) {
+ g_free(keys);
+ return NULL;
+ }
+ keys[i] = gdk_keyval_from_name(sym);
+ }
+
+ spice_display_send_keys(SPICE_DISPLAY(self->obj), keys, len, kind);
+ g_free(keys);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+%%
+override spice_display_get_grab_keys kwargs
+static PyObject*
+_wrap_spice_display_get_grab_keys(PyGObject *self,
+ PyObject *args, PyObject *kwargs)
+{
+ SpiceGrabSequence *seq;
+ PyObject *keyList;
+ int i;
+
+ seq = spice_display_get_grab_keys(SPICE_DISPLAY(self->obj));
+
+ keyList = PyList_New(0);
+ for (i = 0 ; i < seq->nkeysyms ; i++)
+ PyList_Append(keyList, PyInt_FromLong(seq->keysyms[i]));
+
+ return keyList;
+}
+%%
+override spice_display_set_grab_keys kwargs
+static PyObject*
+_wrap_spice_display_set_grab_keys(PyGObject *self,
+ PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"keys", NULL};
+ PyObject *keyList;
+ int i;
+ guint nkeysyms;
+ guint *keysyms;
+ SpiceGrabSequence *seq;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O|I:SpiceDisplay.set_grab_keys", kwlist,
+ &keyList))
+ return NULL;
+
+ if (!PyList_Check(keyList))
+ return NULL;
+
+ nkeysyms = PyList_Size(keyList);
+ keysyms = g_new0(guint, nkeysyms);
+
+ for (i = 0 ; i < nkeysyms ; i++) {
+ PyObject *val = PyList_GetItem(keyList, i);
+ keysyms[i] = (guint)PyInt_AsLong(val);
+ }
+
+ seq = spice_grab_sequence_new(nkeysyms, keysyms);
+ g_free(keysyms);
+
+ spice_display_set_grab_keys(SPICE_DISPLAY(self->obj), seq);
+
+ spice_grab_sequence_free(seq);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+%%
+override spice_session_get_channels
+static PyObject*
+_wrap_spice_session_get_channels(PyGObject *self,
+ PyObject *args, PyObject *kwargs)
+{
+ PyObject *py_list;
+ GList *list, *tmp;
+ PyObject *chann;
+
+ list = spice_session_get_channels(SPICE_SESSION(self->obj));
+
+ if ((py_list = PyList_New(0)) == NULL) {
+ return NULL;
+ }
+ for (tmp = list; tmp != NULL; tmp = tmp->next) {
+ chann = pygobject_new(G_OBJECT(tmp->data));
+ if (chann == NULL) {
+ Py_DECREF(py_list);
+ return NULL;
+ }
+ PyList_Append(py_list, chann);
+ Py_DECREF(chann);
+ }
+ return py_list;
+}
+%%
+override spice_audio_new
+static int
+_wrap_spice_audio_new(PyGObject *self,
+ PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"session", "context", "name", NULL};
+ PyGObject *session = NULL;
+ PyObject *py_context = NULL;
+ char *name = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O!|Os:SpiceAudio", kwlist,
+ &PySpiceSession_Type, &session,
+ &py_context, &name))
+ return -1;
+
+ self->obj = (GObject *)spice_audio_new(SPICE_SESSION(session->obj), NULL, NULL);
+
+ if (!self->obj) {
+ PyErr_SetString(PyExc_RuntimeError, "could not create SpiceAudio object");
+ return -1;
+ }
+ pygobject_register_wrapper((PyObject *)self);
+ return 0;
+
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <glib.h>
+
+#include "spice-client.h"
+
+/**
+ * spice_client_error_quark:
+ *
+ * Gets a #GQuark representing the string "spice-client-error-quark"
+ *
+ * Returns: the #GQuark representing the string.
+ **/
+GQuark spice_client_error_quark(void)
+{
+ return g_quark_from_static_string("spice-client-error-quark");
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_CLIENT_H__
+#define __SPICE_CLIENT_CLIENT_H__
+
+/* glib */
+#include <glib.h>
+#include <glib-object.h>
+
+#define __SPICE_CLIENT_H_INSIDE__
+
+/* spice-protocol */
+#include <spice/enums.h>
+#include <spice/protocol.h>
+
+/* spice/gtk */
+#include "spice-types.h"
+#include "spice-session.h"
+#include "spice-channel.h"
+#include "spice-option.h"
+#include "spice-uri.h"
+#include "spice-version.h"
+
+#include "channel-main.h"
+#include "channel-display.h"
+#include "channel-cursor.h"
+#include "channel-inputs.h"
+#include "channel-playback.h"
+#include "channel-record.h"
+#include "channel-smartcard.h"
+#include "channel-usbredir.h"
+#include "channel-port.h"
+#include "channel-webdav.h"
+
+#include "smartcard-manager.h"
+#include "usb-device-manager.h"
+#include "spice-audio.h"
+#include "spice-file-transfer-task.h"
+
+G_BEGIN_DECLS
+
+/**
+ * SPICE_CLIENT_ERROR:
+ *
+ * Error domain for spice client errors.
+ */
+#define SPICE_CLIENT_ERROR spice_client_error_quark()
+
+/**
+ * SpiceClientError:
+ * @SPICE_CLIENT_ERROR_FAILED: generic error code
+ * @SPICE_CLIENT_ERROR_USB_DEVICE_REJECTED: device redirection rejected by host
+ * @SPICE_CLIENT_ERROR_USB_DEVICE_LOST: device disconnected (fatal IO error)
+ * @SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD: password is required
+ * @SPICE_CLIENT_ERROR_AUTH_NEEDS_USERNAME: username is required
+ * @SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD_AND_USERNAME: password and username are required
+ * @SPICE_CLIENT_ERROR_USB_SERVICE: USB service error
+ *
+ * Error codes returned by spice-client API.
+ */
+typedef enum
+{
+ SPICE_CLIENT_ERROR_FAILED,
+ SPICE_CLIENT_ERROR_USB_DEVICE_REJECTED,
+ SPICE_CLIENT_ERROR_USB_DEVICE_LOST,
+ SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD,
+ SPICE_CLIENT_ERROR_AUTH_NEEDS_USERNAME,
+ SPICE_CLIENT_ERROR_AUTH_NEEDS_PASSWORD_AND_USERNAME,
+ SPICE_CLIENT_ERROR_USB_SERVICE,
+} SpiceClientError;
+
+#ifndef SPICE_DISABLE_DEPRECATED
+#define SPICE_CLIENT_USB_DEVICE_REJECTED SPICE_CLIENT_ERROR_USB_DEVICE_REJECTED
+#define SPICE_CLIENT_USB_DEVICE_LOST SPICE_CLIENT_ERROR_USB_DEVICE_LOST
+#endif
+
+GQuark spice_client_error_quark(void);
+
+G_END_DECLS
+
+#undef __SPICE_CLIENT_H_INSIDE__
+
+#endif /* __SPICE_CLIENT_CLIENT_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+#include "spice-client.h"
+#include "spice-common.h"
+#include "spice-cmdline.h"
+
+static char *host;
+static char *port;
+static char *tls_port;
+static char *password;
+static char *uri;
+
+static GOptionEntry spice_entries[] = {
+ {
+ .long_name = "uri",
+ .arg = G_OPTION_ARG_STRING,
+ .arg_data = &uri,
+ .description = N_("Spice server uri"),
+ .arg_description = N_("<uri>"),
+ },{
+ .long_name = "host",
+ .short_name = 'h',
+ .arg = G_OPTION_ARG_STRING,
+ .arg_data = &host,
+ .description = N_("Spice server address"),
+ .arg_description = N_("<host>"),
+ },{
+ .long_name = "port",
+ .short_name = 'p',
+ .arg = G_OPTION_ARG_STRING,
+ .arg_data = &port,
+ .description = N_("Spice server port"),
+ .arg_description = N_("<port>"),
+ },{
+ .long_name = "secure-port",
+ .short_name = 's',
+ .arg = G_OPTION_ARG_STRING,
+ .arg_data = &tls_port,
+ .description = N_("Spice server secure port"),
+ .arg_description = N_("<port>"),
+ },{
+ .long_name = "password",
+ .short_name = 'w',
+ .arg = G_OPTION_ARG_STRING,
+ .arg_data = &password,
+ .description = N_("Server password"),
+ .arg_description = N_("<password>"),
+ },{
+ /* end of list */
+ }
+};
+
+GOptionGroup *spice_cmdline_get_option_group(void)
+{
+ GOptionGroup *grp;
+
+ grp = g_option_group_new("spice",
+ _("Spice connection options:"),
+ _("Show Spice options"),
+ NULL, NULL);
+ g_option_group_add_entries(grp, spice_entries);
+
+ return grp;
+}
+
+void spice_cmdline_session_setup(SpiceSession *session)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ if (uri)
+ g_object_set(session, "uri", uri, NULL);
+ if (host)
+ g_object_set(session, "host", host, NULL);
+ if (port)
+ g_object_set(session, "port", port, NULL);
+ if (tls_port)
+ g_object_set(session, "tls-port", tls_port, NULL);
+ if (password)
+ g_object_set(session, "password", password, NULL);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SPICE_CMDLINE_H_
+# define SPICE_CMDLINE_H_
+
+G_BEGIN_DECLS
+
+GOptionGroup *spice_cmdline_get_option_group(void);
+void spice_cmdline_session_setup(SpiceSession *session);
+
+G_END_DECLS
+
+#endif // SPICE_CMDLINE_H_
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef SPICE_COMMON_H_
+# define SPICE_COMMON_H_
+
+/* system */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include "common/mem.h"
+#include "common/messages.h"
+#include "common/marshaller.h"
+
+#include "spice-util.h"
+
+#endif // SPICE_COMMON_H_
--- /dev/null
+/*
+ Copyright (C) 2016 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __SPICE_FILE_TRANSFER_TASK_PRIV_H__
+#define __SPICE_FILE_TRANSFER_TASK_PRIV_H__
+
+#include "config.h"
+
+#include <spice/vd_agent.h>
+
+#include "spice-client.h"
+#include "channel-main.h"
+#include "spice-file-transfer-task.h"
+#include "spice-channel-priv.h"
+
+G_BEGIN_DECLS
+
+void spice_file_transfer_task_completed(SpiceFileTransferTask *self, GError *error);
+guint32 spice_file_transfer_task_get_id(SpiceFileTransferTask *self);
+SpiceMainChannel *spice_file_transfer_task_get_channel(SpiceFileTransferTask *self);
+GCancellable *spice_file_transfer_task_get_cancellable(SpiceFileTransferTask *self);
+GHashTable *spice_file_transfer_task_create_tasks(GFile **files,
+ SpiceMainChannel *channel,
+ GFileCopyFlags flags,
+ GCancellable *cancellable);
+void spice_file_transfer_task_init_task_async(SpiceFileTransferTask *self,
+ GAsyncReadyCallback callback,
+ gpointer userdata);
+GFileInfo *spice_file_transfer_task_init_task_finish(SpiceFileTransferTask *xfer_task,
+ GAsyncResult *result,
+ GError **error);
+void spice_file_transfer_task_read_async(SpiceFileTransferTask *self,
+ GAsyncReadyCallback callback,
+ gpointer userdata);
+gssize spice_file_transfer_task_read_finish(SpiceFileTransferTask *self,
+ GAsyncResult *result,
+ char **buffer,
+ GError **error);
+gboolean spice_file_transfer_task_is_completed(SpiceFileTransferTask *self);
+
+G_END_DECLS
+
+#endif /* __SPICE_FILE_TRANSFER_TASK_PRIV_H__ */
--- /dev/null
+/*
+ Copyright (C) 2016 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include "spice-file-transfer-task-priv.h"
+
+/**
+ * SECTION:file-transfer-task
+ * @short_description: Monitoring file transfers
+ * @title: File Transfer Task
+ * @section_id:
+ * @see_also: #SpiceMainChannel
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * SpiceFileTransferTask is an object that represents a particular file
+ * transfer between the client and the guest. The properties and signals of the
+ * object can be used to monitor the status and result of the transfer. The
+ * Main Channel's #SpiceMainChannel::new-file-transfer signal will be emitted
+ * whenever a new file transfer task is initiated.
+ *
+ * Since: 0.31
+ */
+
+struct _SpiceFileTransferTask
+{
+ GObject parent;
+
+ uint32_t id;
+ gboolean completed;
+ gboolean pending;
+ GFile *file;
+ SpiceMainChannel *channel;
+ GFileInputStream *file_stream;
+ GFileCopyFlags flags;
+ GCancellable *cancellable;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+ char *buffer;
+ uint64_t read_bytes;
+ uint64_t file_size;
+ gint64 start_time;
+ gint64 last_update;
+ GError *error;
+};
+
+struct _SpiceFileTransferTaskClass
+{
+ GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE(SpiceFileTransferTask, spice_file_transfer_task, G_TYPE_OBJECT)
+
+#define FILE_XFER_CHUNK_SIZE (VD_AGENT_MAX_DATA_SIZE * 32)
+
+enum {
+ PROP_TASK_ID = 1,
+ PROP_TASK_CHANNEL,
+ PROP_TASK_CANCELLABLE,
+ PROP_TASK_FILE,
+ PROP_TASK_TOTAL_BYTES,
+ PROP_TASK_TRANSFERRED_BYTES,
+ PROP_TASK_PROGRESS,
+};
+
+enum {
+ SIGNAL_FINISHED,
+ LAST_TASK_SIGNAL
+};
+
+static guint task_signals[LAST_TASK_SIGNAL];
+
+/*******************************************************************************
+ * Helpers
+ ******************************************************************************/
+
+static SpiceFileTransferTask *
+spice_file_transfer_task_new(SpiceMainChannel *channel,
+ GFile *file,
+ GFileCopyFlags flags,
+ GCancellable *cancellable)
+{
+ static uint32_t xfer_id = 1; /* Used to identify task id */
+ GCancellable *task_cancellable = cancellable;
+ SpiceFileTransferTask *self;
+
+ /* if a cancellable object was not provided for the overall operation,
+ * create a separate object for each file so that they can be cancelled
+ * separately */
+ if (!task_cancellable)
+ task_cancellable = g_cancellable_new();
+
+ self = g_object_new(SPICE_TYPE_FILE_TRANSFER_TASK,
+ "id", xfer_id++,
+ "file", file,
+ "channel", channel,
+ "cancellable", task_cancellable,
+ NULL);
+ self->flags = flags;
+
+ /* if we created a GCancellable above, unref it */
+ if (!cancellable)
+ g_object_unref(task_cancellable);
+
+ return self;
+}
+
+static void spice_file_transfer_task_query_info_cb(GObject *obj,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceFileTransferTask *self;
+ GFileInfo *info;
+ GTask *task;
+ GError *error = NULL;
+
+ task = G_TASK(user_data);
+ self = g_task_get_source_object(task);
+
+ g_return_if_fail(self->pending == TRUE);
+ self->pending = FALSE;
+
+ info = g_file_query_info_finish(G_FILE(obj), res, &error);
+ if (self->error) {
+ g_clear_object(&info);
+ g_clear_error(&error);
+ /* Return error previously reported */
+ g_task_return_error(task, g_error_copy(self->error));
+ g_object_unref(task);
+ return;
+ } else if (error) {
+ g_task_return_error(task, error);
+ g_object_unref(task);
+ return;
+ }
+
+ self->file_size =
+ g_file_info_get_attribute_uint64(info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
+
+ /* SpiceFileTransferTask's init is done, handshake for file-transfer will
+ * start soon. First "progress" can be emitted ~ 0% */
+ g_object_notify(G_OBJECT(self), "total-bytes");
+ g_object_notify(G_OBJECT(self), "progress");
+
+ g_task_return_pointer(task, info, g_object_unref);
+ g_object_unref(task);
+}
+
+static void spice_file_transfer_task_read_file_cb(GObject *obj,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceFileTransferTask *self;
+ GTask *task;
+ GError *error = NULL;
+
+ task = G_TASK(user_data);
+ self = g_task_get_source_object(task);
+
+ g_return_if_fail(self->pending == TRUE);
+
+ self->file_stream = g_file_read_finish(G_FILE(obj), res, &error);
+ if (self->error) {
+ g_clear_error(&error);
+ /* Return error previously reported */
+ self->pending = FALSE;
+ g_task_return_error(task, g_error_copy(self->error));
+ g_object_unref(task);
+ return;
+ } else if (error) {
+ self->pending = FALSE;
+ g_task_return_error(task, error);
+ g_object_unref(task);
+ return;
+ }
+
+ g_file_query_info_async(self->file,
+ "standard::*",
+ G_FILE_QUERY_INFO_NONE,
+ G_PRIORITY_DEFAULT,
+ self->cancellable,
+ spice_file_transfer_task_query_info_cb,
+ task);
+}
+
+static void spice_file_transfer_task_read_stream_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer userdata)
+{
+ SpiceFileTransferTask *self;
+ GTask *task;
+ gssize nbytes;
+ GError *error = NULL;
+
+ task = G_TASK(userdata);
+ self = g_task_get_source_object(task);
+
+ g_return_if_fail(self->pending == TRUE);
+ self->pending = FALSE;
+
+ nbytes = g_input_stream_read_finish(G_INPUT_STREAM(self->file_stream), res, &error);
+ if (self->error) {
+ g_clear_error(&error);
+ /* On any pending error on SpiceFileTransferTask */
+ g_task_return_error(task, g_error_copy(self->error));
+ g_object_unref(task);
+ return;
+ } else if (error) {
+ g_task_return_error(task, error);
+ g_object_unref(task);
+ return;
+ }
+
+ self->read_bytes += nbytes;
+
+ if (spice_util_get_debug()) {
+ const GTimeSpan interval = 20 * G_TIME_SPAN_SECOND;
+ gint64 now = g_get_monotonic_time();
+
+ if (interval < now - self->last_update) {
+ gchar *basename = g_file_get_basename(self->file);
+ self->last_update = now;
+ SPICE_DEBUG("read %.2f%% of the file %s",
+ 100.0 * self->read_bytes / self->file_size, basename);
+ g_free(basename);
+ }
+ }
+
+ g_task_return_int(task, nbytes);
+ g_object_unref(task);
+}
+
+/* main context */
+static void spice_file_transfer_task_close_stream_cb(GObject *object,
+ GAsyncResult *close_res,
+ gpointer user_data)
+{
+ SpiceFileTransferTask *self;
+ GError *error = NULL;
+
+ self = user_data;
+
+ if (object) {
+ GInputStream *stream = G_INPUT_STREAM(object);
+ g_input_stream_close_finish(stream, close_res, &error);
+ if (error) {
+ /* This error dont need to report to user, just print a log */
+ SPICE_DEBUG("close file error: %s", error->message);
+ g_clear_error(&error);
+ }
+ }
+
+ if (self->error == NULL && spice_util_get_debug()) {
+ gint64 now = g_get_monotonic_time();
+ gchar *basename = g_file_get_basename(self->file);
+ double seconds = (double) (now - self->start_time) / G_TIME_SPAN_SECOND;
+ gchar *file_size_str = g_format_size(self->file_size);
+ gchar *transfer_speed_str = g_format_size(self->file_size / seconds);
+
+ g_warn_if_fail(self->read_bytes == self->file_size);
+ SPICE_DEBUG("transferred file %s of %s size in %.1f seconds (%s/s)",
+ basename, file_size_str, seconds, transfer_speed_str);
+
+ g_free(basename);
+ g_free(file_size_str);
+ g_free(transfer_speed_str);
+ }
+ g_object_unref(self);
+}
+
+
+/*******************************************************************************
+ * Internal API
+ ******************************************************************************/
+
+G_GNUC_INTERNAL
+void spice_file_transfer_task_completed(SpiceFileTransferTask *self,
+ GError *error)
+{
+ self->completed = TRUE;
+
+ /* In case of multiple errors we only report the first error */
+ if (self->error)
+ g_clear_error(&error);
+ if (error) {
+ gchar *path = g_file_get_path(self->file);
+ SPICE_DEBUG("File %s xfer failed: %s",
+ path, error->message);
+ g_free(path);
+ self->error = error;
+ }
+
+ if (self->pending) {
+ /* Complete but pending is okay only if error is set */
+ if (self->error == NULL) {
+ self->error = g_error_new(SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED,
+ "Cannot complete task in pending state");
+ }
+ return;
+ }
+
+ if (!self->file_stream) {
+ spice_file_transfer_task_close_stream_cb(NULL, NULL, self);
+ goto signal;
+ }
+
+ g_input_stream_close_async(G_INPUT_STREAM(self->file_stream),
+ G_PRIORITY_DEFAULT,
+ self->cancellable,
+ spice_file_transfer_task_close_stream_cb,
+ self);
+ self->pending = TRUE;
+signal:
+ g_signal_emit(self, task_signals[SIGNAL_FINISHED], 0, self->error);
+ /* SpiceFileTransferTask unref is done after input stream is closed */
+}
+
+G_GNUC_INTERNAL
+guint32 spice_file_transfer_task_get_id(SpiceFileTransferTask *self)
+{
+ g_return_val_if_fail(self != NULL, 0);
+ return self->id;
+}
+
+G_GNUC_INTERNAL
+SpiceMainChannel *spice_file_transfer_task_get_channel(SpiceFileTransferTask *self)
+{
+ g_return_val_if_fail(self != NULL, NULL);
+ return self->channel;
+}
+
+G_GNUC_INTERNAL
+GCancellable *spice_file_transfer_task_get_cancellable(SpiceFileTransferTask *self)
+{
+ g_return_val_if_fail(self != NULL, NULL);
+ return self->cancellable;
+}
+
+/* Helper function which only creates a SpiceFileTransferTask per GFile
+ * in @files and returns a HashTable mapping task-id to the task itself
+ * The SpiceFileTransferTask created here has two references, one should be
+ * freed by spice_file_transfer_task_close_stream_cb() after
+ * spice_file_transfer_task_completed() is called and the other reference
+ * belongs to the caller and should be freed upon GHashTable destruction */
+G_GNUC_INTERNAL
+GHashTable *spice_file_transfer_task_create_tasks(GFile **files,
+ SpiceMainChannel *channel,
+ GFileCopyFlags flags,
+ GCancellable *cancellable)
+{
+ GHashTable *xfer_ht;
+ gint i;
+
+ g_return_val_if_fail(files != NULL && files[0] != NULL, NULL);
+
+ xfer_ht = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
+ for (i = 0; files[i] != NULL && !g_cancellable_is_cancelled(cancellable); i++) {
+ SpiceFileTransferTask *xfer_task;
+ guint32 task_id;
+
+ xfer_task = spice_file_transfer_task_new(channel, files[i], flags, cancellable);
+ task_id = spice_file_transfer_task_get_id(xfer_task);
+ g_hash_table_insert(xfer_ht, GUINT_TO_POINTER(task_id), g_object_ref(xfer_task));
+ }
+ return xfer_ht;
+}
+
+G_GNUC_INTERNAL
+void spice_file_transfer_task_init_task_async(SpiceFileTransferTask *self,
+ GAsyncReadyCallback callback,
+ gpointer userdata)
+{
+ GTask *task;
+
+ g_return_if_fail(self != NULL);
+ g_return_if_fail(self->pending == FALSE);
+
+ task = g_task_new(self, self->cancellable, callback, userdata);
+
+ self->pending = TRUE;
+ g_file_read_async(self->file,
+ G_PRIORITY_DEFAULT,
+ self->cancellable,
+ spice_file_transfer_task_read_file_cb,
+ task);
+}
+
+G_GNUC_INTERNAL
+GFileInfo *spice_file_transfer_task_init_task_finish(SpiceFileTransferTask *self,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = G_TASK(result);
+
+ g_return_val_if_fail(self != NULL, NULL);
+ return g_task_propagate_pointer(task, error);
+}
+
+/* Any context */
+G_GNUC_INTERNAL
+void spice_file_transfer_task_read_async(SpiceFileTransferTask *self,
+ GAsyncReadyCallback callback,
+ gpointer userdata)
+{
+ GTask *task;
+
+ g_return_if_fail(self != NULL);
+ if (self->pending) {
+ g_task_report_new_error(self, callback, userdata,
+ spice_file_transfer_task_read_async,
+ SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED,
+ "Cannot read data in pending state");
+ return;
+ }
+
+ /* Notify the progress prior the read to make the info be related to the
+ * data that was already sent. To notify the 100% (completed), channel-main
+ * should call read-async when it expects EOF. */
+ g_object_notify(G_OBJECT(self), "progress");
+ g_object_notify(G_OBJECT(self), "transferred-bytes");
+
+ task = g_task_new(self, self->cancellable, callback, userdata);
+
+ if (self->read_bytes == self->file_size) {
+ /* channel-main might request data after reading the whole file as it
+ * expects EOF. Let's return immediately its request as we don't want to
+ * reach a state where agent says file-transfer SUCCEED but we are in a
+ * PENDING state in SpiceFileTransferTask due reading in idle */
+ g_task_return_int(task, 0);
+ g_object_unref(task);
+ return;
+ }
+
+ self->pending = TRUE;
+ g_input_stream_read_async(G_INPUT_STREAM(self->file_stream),
+ self->buffer,
+ FILE_XFER_CHUNK_SIZE,
+ G_PRIORITY_DEFAULT,
+ self->cancellable,
+ spice_file_transfer_task_read_stream_cb,
+ task);
+}
+
+G_GNUC_INTERNAL
+gssize spice_file_transfer_task_read_finish(SpiceFileTransferTask *self,
+ GAsyncResult *result,
+ char **buffer,
+ GError **error)
+{
+ gssize nbytes;
+ GTask *task = G_TASK(result);
+
+ g_return_val_if_fail(self != NULL, -1);
+
+ nbytes = g_task_propagate_int(task, error);
+ if (nbytes >= 0 && buffer != NULL)
+ *buffer = self->buffer;
+
+ return nbytes;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_file_transfer_task_is_completed(SpiceFileTransferTask *self)
+{
+ g_return_val_if_fail(self != NULL, FALSE);
+
+ /* File transfer is considered over at the first time it is marked as
+ * complete with spice_file_transfer_task_completed. */
+ return self->completed;
+}
+
+/*******************************************************************************
+ * External API
+ ******************************************************************************/
+
+/**
+ * spice_file_transfer_task_get_progress:
+ * @self: a file transfer task
+ *
+ * Convenience function for retrieving the current progress of this file
+ * transfer task.
+ *
+ * Returns: A fractional value between 0 and 1.0
+ *
+ * Since: 0.31
+ **/
+double spice_file_transfer_task_get_progress(SpiceFileTransferTask *self)
+{
+ g_return_val_if_fail(SPICE_IS_FILE_TRANSFER_TASK(self), 0.0);
+
+ if (self->file_size == 0)
+ return 0.0;
+
+ return (double)self->read_bytes / self->file_size;
+}
+
+/**
+ * spice_file_transfer_task_cancel:
+ * @self: a file transfer task
+ *
+ * Cancels the file transfer task. Note that depending on how the file transfer
+ * was initiated, multiple file transfer tasks may share a single
+ * #SpiceFileTransferTask::cancellable object, so canceling one task may result
+ * in the cancellation of other tasks.
+ *
+ * Since: 0.31
+ **/
+void spice_file_transfer_task_cancel(SpiceFileTransferTask *self)
+{
+ g_return_if_fail(SPICE_IS_FILE_TRANSFER_TASK(self));
+
+ g_cancellable_cancel(self->cancellable);
+}
+
+/**
+ * spice_file_transfer_task_get_filename:
+ * @self: a file transfer task
+ *
+ * Gets the name of the file being transferred in this task
+ *
+ * Returns: (transfer full): The basename of the file
+ *
+ * Since: 0.31
+ **/
+char* spice_file_transfer_task_get_filename(SpiceFileTransferTask *self)
+{
+ g_return_val_if_fail(SPICE_IS_FILE_TRANSFER_TASK(self), NULL);
+
+ return g_file_get_basename(self->file);
+}
+
+/**
+ * spice_file_transfer_task_get_total_bytes:
+ * @self: a file transfer task
+ *
+ * Gets the total size in bytes of the file transfer.
+ *
+ * Returns: The total size of the file transfer
+ *
+ * Since: 0.33
+ **/
+guint64 spice_file_transfer_task_get_total_bytes(SpiceFileTransferTask *self)
+{
+ g_return_val_if_fail(SPICE_IS_FILE_TRANSFER_TASK(self), 0);
+ return self->file_size;
+}
+
+
+/**
+ * spice_file_transfer_task_get_transferred_bytes:
+ * @self: a file transfer task
+ *
+ * Gets the number of bytes that have been transferred so far.
+ *
+ * Returns: The number of transferred bytes
+ *
+ * Since: 0.33
+ **/
+guint64 spice_file_transfer_task_get_transferred_bytes(SpiceFileTransferTask *self)
+{
+ g_return_val_if_fail(SPICE_IS_FILE_TRANSFER_TASK(self), 0);
+ return self->read_bytes;
+}
+
+/*******************************************************************************
+ * GObject
+ ******************************************************************************/
+
+static void
+spice_file_transfer_task_get_property(GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceFileTransferTask *self = SPICE_FILE_TRANSFER_TASK(object);
+
+ switch (property_id)
+ {
+ case PROP_TASK_ID:
+ g_value_set_uint(value, self->id);
+ break;
+ case PROP_TASK_FILE:
+ g_value_set_object(value, self->file);
+ break;
+ case PROP_TASK_TOTAL_BYTES:
+ g_value_set_uint64(value, spice_file_transfer_task_get_total_bytes(self));
+ break;
+ case PROP_TASK_TRANSFERRED_BYTES:
+ g_value_set_uint64(value, spice_file_transfer_task_get_transferred_bytes(self));
+ break;
+ case PROP_TASK_PROGRESS:
+ g_value_set_double(value, spice_file_transfer_task_get_progress(self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ }
+}
+
+static void
+spice_file_transfer_task_set_property(GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceFileTransferTask *self = SPICE_FILE_TRANSFER_TASK(object);
+
+ switch (property_id)
+ {
+ case PROP_TASK_ID:
+ self->id = g_value_get_uint(value);
+ break;
+ case PROP_TASK_FILE:
+ self->file = g_value_dup_object(value);
+ break;
+ case PROP_TASK_CHANNEL:
+ self->channel = g_value_dup_object(value);
+ break;
+ case PROP_TASK_CANCELLABLE:
+ self->cancellable = g_value_dup_object(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ }
+}
+
+static void
+spice_file_transfer_task_dispose(GObject *object)
+{
+ SpiceFileTransferTask *self = SPICE_FILE_TRANSFER_TASK(object);
+
+ g_clear_object(&self->file);
+ g_clear_object(&self->file_stream);
+ g_clear_error(&self->error);
+
+ G_OBJECT_CLASS(spice_file_transfer_task_parent_class)->dispose(object);
+}
+
+static void
+spice_file_transfer_task_finalize(GObject *object)
+{
+ SpiceFileTransferTask *self = SPICE_FILE_TRANSFER_TASK(object);
+
+ g_free(self->buffer);
+
+ G_OBJECT_CLASS(spice_file_transfer_task_parent_class)->finalize(object);
+}
+
+static void
+spice_file_transfer_task_constructed(GObject *object)
+{
+ SpiceFileTransferTask *self = SPICE_FILE_TRANSFER_TASK(object);
+
+ if (spice_util_get_debug()) {
+ gchar *basename = g_file_get_basename(self->file);
+ self->start_time = g_get_monotonic_time();
+ self->last_update = self->start_time;
+
+ SPICE_DEBUG("transfer of file %s has started", basename);
+ g_free(basename);
+ }
+}
+
+static void
+spice_file_transfer_task_class_init(SpiceFileTransferTaskClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+ object_class->get_property = spice_file_transfer_task_get_property;
+ object_class->set_property = spice_file_transfer_task_set_property;
+ object_class->finalize = spice_file_transfer_task_finalize;
+ object_class->dispose = spice_file_transfer_task_dispose;
+ object_class->constructed = spice_file_transfer_task_constructed;
+
+ /**
+ * SpiceFileTransferTask:id:
+ *
+ * The ID of the file transfer task
+ *
+ * Since: 0.31
+ **/
+ g_object_class_install_property(object_class, PROP_TASK_ID,
+ g_param_spec_uint("id",
+ "id",
+ "The id of the task",
+ 0, G_MAXUINT, 0,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceFileTransferTask:channel:
+ *
+ * The main channel that owns the file transfer task
+ *
+ * Since: 0.31
+ **/
+ g_object_class_install_property(object_class, PROP_TASK_CHANNEL,
+ g_param_spec_object("channel",
+ "channel",
+ "The channel transferring the file",
+ SPICE_TYPE_MAIN_CHANNEL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceFileTransferTask:cancellable:
+ *
+ * A cancellable object used to cancel the file transfer
+ *
+ * Since: 0.31
+ **/
+ g_object_class_install_property(object_class, PROP_TASK_CANCELLABLE,
+ g_param_spec_object("cancellable",
+ "cancellable",
+ "The object used to cancel the task",
+ G_TYPE_CANCELLABLE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceFileTransferTask:file:
+ *
+ * The file that is being transferred in this file transfer task
+ *
+ * Since: 0.31
+ **/
+ g_object_class_install_property(object_class, PROP_TASK_FILE,
+ g_param_spec_object("file",
+ "File",
+ "The file being transferred",
+ G_TYPE_FILE,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceFileTransferTask:total-bytes:
+ *
+ * The total size in bytes of this file transfer.
+ *
+ * Since: 0.33
+ **/
+ g_object_class_install_property(object_class, PROP_TASK_TOTAL_BYTES,
+ g_param_spec_uint64("total-bytes",
+ "Total bytes",
+ "The size in bytes of the file transferred",
+ 0, G_MAXUINT64, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+
+ /**
+ * SpiceFileTransferTask:transferred-bytes:
+ *
+ * The number of bytes that have been transferred so far.
+ *
+ * Since: 0.33
+ **/
+ g_object_class_install_property(object_class, PROP_TASK_TRANSFERRED_BYTES,
+ g_param_spec_uint64("transferred-bytes",
+ "Transferred bytes",
+ "The number of bytes transferred",
+ 0, G_MAXUINT64, 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+
+ /**
+ * SpiceFileTransferTask:progress:
+ *
+ * The current state of the file transfer. This value indicates a
+ * fraction, and ranges from 0 to 1.0. Listen for change notifications on
+ * this property to be updated whenever the file transfer progress changes.
+ *
+ * Since: 0.31
+ **/
+ g_object_class_install_property(object_class, PROP_TASK_PROGRESS,
+ g_param_spec_double("progress",
+ "Progress",
+ "The percentage of the file transferred",
+ 0.0, 1.0, 0.0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceFileTransferTask::finished:
+ * @task: the file transfer task that emitted the signal
+ * @error: (transfer none): the error state of the transfer. Will be %NULL
+ * if the file transfer was successful.
+ *
+ * The #SpiceFileTransferTask::finished signal is emitted when the file
+ * transfer has completed transferring to the guest.
+ *
+ * Since: 0.31
+ **/
+ task_signals[SIGNAL_FINISHED] = g_signal_new("finished", SPICE_TYPE_FILE_TRANSFER_TASK,
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ G_TYPE_ERROR);
+}
+
+static void
+spice_file_transfer_task_init(SpiceFileTransferTask *self)
+{
+ self->buffer = g_malloc0(FILE_XFER_CHUNK_SIZE);
+}
--- /dev/null
+/*
+ Copyright (C) 2010-2015 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __SPICE_FILE_TRANSFER_TASK_H__
+#define __SPICE_FILE_TRANSFER_TASK_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include "spice-client.h"
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_FILE_TRANSFER_TASK spice_file_transfer_task_get_type()
+
+#define SPICE_FILE_TRANSFER_TASK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_FILE_TRANSFER_TASK, SpiceFileTransferTask))
+#define SPICE_FILE_TRANSFER_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_FILE_TRANSFER_TASK, SpiceFileTransferTaskClass))
+#define SPICE_IS_FILE_TRANSFER_TASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_FILE_TRANSFER_TASK))
+#define SPICE_IS_FILE_TRANSFER_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_FILE_TRANSFER_TASK))
+#define SPICE_FILE_TRANSFER_TASK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_FILE_TRANSFER_TASK, SpiceFileTransferTaskClass))
+
+typedef struct _SpiceFileTransferTask SpiceFileTransferTask;
+typedef struct _SpiceFileTransferTaskClass SpiceFileTransferTaskClass;
+
+GType spice_file_transfer_task_get_type(void) G_GNUC_CONST;
+
+char* spice_file_transfer_task_get_filename(SpiceFileTransferTask *self);
+void spice_file_transfer_task_cancel(SpiceFileTransferTask *self);
+guint64 spice_file_transfer_task_get_total_bytes(SpiceFileTransferTask *self);
+guint64 spice_file_transfer_task_get_transferred_bytes(SpiceFileTransferTask *self);
+double spice_file_transfer_task_get_progress(SpiceFileTransferTask *self);
+
+G_END_DECLS
+
+#endif /* __SPICE_FILE_TRANSFER_TASK_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2016 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <common/macros.h>
+
+#ifdef G_OS_WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
+
+BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ if (fdwReason == DLL_PROCESS_ATTACH) {
+ char *basedir =
+ g_win32_get_package_installation_directory_of_module(hinstDLL);
+ char *localedir = g_build_filename(basedir, "share", "locale", NULL);
+ bindtextdomain(GETTEXT_PACKAGE, localedir);
+ g_free(localedir);
+ g_free(basedir);
+ bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+ }
+ return TRUE;
+}
+
+#else
+
+SPICE_CONSTRUCTOR_FUNC(i18n_init)
+{
+ bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+}
+
+#endif
--- /dev/null
+spice_audio_get
+spice_audio_get_type
+spice_audio_new
+spice_channel_connect
+spice_channel_destroy
+spice_channel_disconnect
+spice_channel_event_get_type
+spice_channel_flush_async
+spice_channel_flush_finish
+spice_channel_get_error
+spice_channel_get_type
+spice_channel_new
+spice_channel_open_fd
+spice_channel_set_capability
+spice_channel_string_to_type
+spice_channel_test_capability
+spice_channel_test_common_capability
+spice_channel_type_to_string
+spice_client_error_quark
+spice_cursor_channel_get_type
+spice_display_change_preferred_compression
+spice_display_channel_get_type
+spice_display_get_gl_scanout
+spice_display_get_primary
+spice_display_gl_draw_done
+spice_file_transfer_task_cancel
+spice_file_transfer_task_get_filename
+spice_file_transfer_task_get_progress
+spice_file_transfer_task_get_total_bytes
+spice_file_transfer_task_get_transferred_bytes
+spice_file_transfer_task_get_type
+spice_get_option_group
+spice_gl_scanout_free
+spice_gl_scanout_get_type
+spice_g_signal_connect_object
+spice_inputs_button_press
+spice_inputs_button_release
+spice_inputs_channel_get_type
+spice_inputs_key_press
+spice_inputs_key_press_and_release
+spice_inputs_key_release
+spice_inputs_lock_get_type
+spice_inputs_motion
+spice_inputs_position
+spice_inputs_set_key_locks
+spice_main_agent_test_capability
+spice_main_channel_get_type
+spice_main_clipboard_grab
+spice_main_clipboard_notify
+spice_main_clipboard_release
+spice_main_clipboard_request
+spice_main_clipboard_selection_grab
+spice_main_clipboard_selection_notify
+spice_main_clipboard_selection_release
+spice_main_clipboard_selection_request
+spice_main_file_copy_async
+spice_main_file_copy_finish
+spice_main_request_mouse_mode
+spice_main_send_monitor_config
+spice_main_set_display
+spice_main_set_display_enabled
+spice_main_update_display
+spice_main_update_display_enabled
+spice_playback_channel_get_type
+spice_playback_channel_set_delay
+spice_port_channel_get_type
+spice_port_event
+spice_port_write_async
+spice_port_write_finish
+spice_record_channel_get_type
+spice_record_send_data
+spice_session_connect
+spice_session_disconnect
+spice_session_get_channels
+spice_session_get_proxy_uri
+spice_session_get_read_only
+spice_session_get_type
+spice_session_has_channel_type
+spice_session_is_for_migration
+spice_session_migration_get_type
+spice_session_new
+spice_session_open_fd
+spice_session_verify_get_type
+spice_set_session_option
+spice_smartcard_channel_get_type
+spice_smartcard_manager_get
+spice_smartcard_manager_get_readers
+spice_smartcard_manager_get_type
+spice_smartcard_manager_insert_card
+spice_smartcard_manager_remove_card
+spice_smartcard_reader_get_type
+spice_smartcard_reader_insert_card
+spice_smartcard_reader_is_software
+spice_smartcard_reader_remove_card
+spice_uri_get_hostname
+spice_uri_get_password
+spice_uri_get_port
+spice_uri_get_scheme
+spice_uri_get_type
+spice_uri_get_user
+spice_uri_set_hostname
+spice_uri_set_password
+spice_uri_set_port
+spice_uri_set_scheme
+spice_uri_set_user
+spice_uri_to_string
+spice_usb_device_get_description
+spice_usb_device_get_libusb_device
+spice_usb_device_get_type
+spice_usb_device_manager_can_redirect_device
+spice_usb_device_manager_connect_device_async
+spice_usb_device_manager_connect_device_finish
+spice_usb_device_manager_disconnect_device
+spice_usb_device_manager_disconnect_device_async
+spice_usb_device_manager_disconnect_device_finish
+spice_usb_device_manager_get
+spice_usb_device_manager_get_devices
+spice_usb_device_manager_get_devices_with_filter
+spice_usb_device_manager_get_type
+spice_usb_device_manager_is_device_connected
+spice_usb_device_manager_is_redirecting
+spice_usbredir_channel_get_type
+spice_util_get_debug
+spice_util_get_version_string
+spice_util_set_debug
+spice_uuid_to_string
+spice_webdav_channel_get_type
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2016 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_GRABSEQUENCE_PRIV_H__
+#define __SPICE_GRABSEQUENCE_PRIV_H__
+
+#include <glib.h>
+
+struct _SpiceGrabSequence {
+ /*< private >*/
+ guint nkeysyms;
+ guint *keysyms;
+};
+
+#endif
--- /dev/null
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2010 Daniel P. Berrange <dan@berrange.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.0 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <gdk/gdk.h>
+
+#include "spice-grabsequence.h"
+#include "spice-grabsequence-priv.h"
+
+GType spice_grab_sequence_get_type(void)
+{
+ static GType grab_sequence_type = 0;
+ static volatile gsize grab_sequence_type_volatile;
+
+ if (g_once_init_enter(&grab_sequence_type_volatile)) {
+ grab_sequence_type = g_boxed_type_register_static
+ ("SpiceGrabSequence",
+ (GBoxedCopyFunc)spice_grab_sequence_copy,
+ (GBoxedFreeFunc)spice_grab_sequence_free);
+ g_once_init_leave(&grab_sequence_type_volatile,
+ grab_sequence_type);
+ }
+
+ return grab_sequence_type;
+}
+
+
+/**
+ * spice_grab_sequence_new:
+ * @nkeysyms: length of @keysyms
+ * @keysyms: (array length=nkeysyms): the keysym values
+ *
+ * Creates a new grab sequence from a list of keysym values
+ *
+ * Returns: (transfer full): a new grab sequence object
+ */
+SpiceGrabSequence *spice_grab_sequence_new(guint nkeysyms, guint *keysyms)
+{
+ SpiceGrabSequence *sequence;
+
+ sequence = g_new0(SpiceGrabSequence, 1);
+ sequence->nkeysyms = nkeysyms;
+ sequence->keysyms = g_new0(guint, nkeysyms);
+ memcpy(sequence->keysyms, keysyms, sizeof(guint)*nkeysyms);
+
+ return sequence;
+}
+
+
+/**
+ * spice_grab_sequence_new_from_string:
+ * @str: a string of '+' separated key names (ex: "Control_L+Alt_L")
+ *
+ * Creates a new #SpiceGrabSequence from the string representation.
+ *
+ * Returns: a new #SpiceGrabSequence.
+ **/
+SpiceGrabSequence *spice_grab_sequence_new_from_string(const gchar *str)
+{
+ gchar **keysymstr;
+ int i;
+ SpiceGrabSequence *sequence;
+
+ sequence = g_new0(SpiceGrabSequence, 1);
+
+ keysymstr = g_strsplit(str, "+", 5);
+
+ sequence->nkeysyms = 0;
+ while (keysymstr[sequence->nkeysyms])
+ sequence->nkeysyms++;
+
+ sequence->keysyms = g_new0(guint, sequence->nkeysyms);
+ for (i = 0 ; i < sequence->nkeysyms ; i++) {
+ sequence->keysyms[i] =
+ (guint)gdk_keyval_from_name(keysymstr[i]);
+ if (sequence->keysyms[i] == 0) {
+ g_critical("Invalid key: %s", keysymstr[i]);
+ }
+ }
+ g_strfreev(keysymstr);
+
+ return sequence;
+
+}
+
+
+/**
+ * spice_grab_sequence_copy:
+ * @sequence: sequence to copy
+ *
+ * Creates a copy of the @sequence.
+ *
+ * Returns: (transfer full): a copy of @sequence
+ **/
+SpiceGrabSequence *spice_grab_sequence_copy(SpiceGrabSequence *srcSequence)
+{
+ SpiceGrabSequence *sequence;
+
+ sequence = g_new0(SpiceGrabSequence, 1);
+ sequence->nkeysyms = srcSequence->nkeysyms;
+ sequence->keysyms = g_new0(guint, srcSequence->nkeysyms);
+ memcpy(sequence->keysyms, srcSequence->keysyms,
+ sizeof(guint) * sequence->nkeysyms);
+
+ return sequence;
+}
+
+
+/**
+ * spice_grab_sequence_free:
+ * @sequence: a #SpiceGrabSequence
+ *
+ * Free @sequence.
+ **/
+void spice_grab_sequence_free(SpiceGrabSequence *sequence)
+{
+ g_free(sequence->keysyms);
+ g_free(sequence);
+}
+
+
+/**
+ * spice_grab_sequence_as_string:
+ * @sequence: a #SpiceGrabSequence
+ *
+ * Creates a string representing the @sequence.
+ *
+ * Returns: (transfer full): a newly allocated string representing the key sequence
+ **/
+gchar *spice_grab_sequence_as_string(SpiceGrabSequence *sequence)
+{
+ GString *str = g_string_new("");
+ int i;
+
+ for (i = 0 ; i < sequence->nkeysyms ; i++) {
+ if (i > 0)
+ g_string_append_c(str, '+');
+ g_string_append(str, gdk_keyval_name(sequence->keysyms[i]));
+ }
+
+ return g_string_free(str, FALSE);
+
+}
+
+
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
--- /dev/null
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+ * Copyright (C) 2009-2010 Daniel P. Berrange <dan@berrange.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.0 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SPICE_GRAB_SEQUENCE_H
+#define SPICE_GRAB_SEQUENCE_H
+
+#if !defined(__SPICE_CLIENT_GTK_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client-gtk.h> can be included directly"
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_GRAB_SEQUENCE (spice_grab_sequence_get_type ())
+
+/**
+ * SpiceGrabSequence:
+ *
+ * An opaque type that represents a grab sequence.
+ **/
+typedef struct _SpiceGrabSequence SpiceGrabSequence;
+
+GType spice_grab_sequence_get_type(void);
+
+SpiceGrabSequence *spice_grab_sequence_new(guint nkeysyms, guint *keysyms);
+SpiceGrabSequence *spice_grab_sequence_new_from_string(const gchar *str);
+SpiceGrabSequence *spice_grab_sequence_copy(SpiceGrabSequence *sequence);
+void spice_grab_sequence_free(SpiceGrabSequence *sequence);
+gchar *spice_grab_sequence_as_string(SpiceGrabSequence *sequence);
+
+
+G_END_DECLS
+
+#endif /* SPICE_GRAB_SEQUENCE_H */
+
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <gst/gst.h>
+#include <gst/app/gstappsrc.h>
+#include <gst/app/gstappsink.h>
+#include <gst/audio/streamvolume.h>
+
+#include "spice-gstaudio.h"
+#include "spice-common.h"
+#include "spice-session.h"
+#include "spice-util.h"
+
+#define SPICE_GSTAUDIO_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_GSTAUDIO, SpiceGstaudioPrivate))
+
+G_DEFINE_TYPE(SpiceGstaudio, spice_gstaudio, SPICE_TYPE_AUDIO)
+
+struct stream {
+ GstElement *pipe;
+ GstElement *src;
+ GstElement *sink;
+ guint rate;
+ guint channels;
+};
+
+struct _SpiceGstaudioPrivate {
+ SpiceChannel *pchannel;
+ SpiceChannel *rchannel;
+ struct stream playback;
+ struct stream record;
+ guint mmtime_id;
+};
+
+static gboolean connect_channel(SpiceAudio *audio, SpiceChannel *channel);
+static void channel_weak_notified(gpointer data, GObject *where_the_object_was);
+static void spice_gstaudio_get_playback_volume_info_async(SpiceAudio *audio,
+ GCancellable *cancellable, SpiceMainChannel *main_channel,
+ GAsyncReadyCallback callback, gpointer user_data);
+static gboolean spice_gstaudio_get_playback_volume_info_finish(SpiceAudio *audio,
+ GAsyncResult *res, gboolean *mute, guint8 *nchannels, guint16 **volume, GError **error);
+static void spice_gstaudio_get_record_volume_info_async(SpiceAudio *audio,
+ GCancellable *cancellable, SpiceMainChannel *main_channel,
+ GAsyncReadyCallback callback, gpointer user_data);
+static gboolean spice_gstaudio_get_record_volume_info_finish(SpiceAudio *audio,
+ GAsyncResult *res, gboolean *mute, guint8 *nchannels, guint16 **volume, GError **error);
+
+static void spice_gstaudio_finalize(GObject *obj)
+{
+ G_OBJECT_CLASS(spice_gstaudio_parent_class)->finalize(obj);
+}
+
+static void stream_dispose(struct stream *s)
+{
+ if (s->pipe) {
+ gst_element_set_state(s->pipe, GST_STATE_NULL);
+ g_clear_pointer(&s->pipe, gst_object_unref);
+ }
+
+ g_clear_pointer(&s->src, gst_object_unref);
+ g_clear_pointer(&s->sink, gst_object_unref);
+}
+
+static void spice_gstaudio_dispose(GObject *obj)
+{
+ SpiceGstaudio *gstaudio = SPICE_GSTAUDIO(obj);
+ SpiceGstaudioPrivate *p;
+ SPICE_DEBUG("%s", __FUNCTION__);
+ p = gstaudio->priv;
+
+ stream_dispose(&p->playback);
+ stream_dispose(&p->record);
+
+ if (p->pchannel)
+ g_object_weak_unref(G_OBJECT(p->pchannel), channel_weak_notified, gstaudio);
+ p->pchannel = NULL;
+
+ if (p->rchannel)
+ g_object_weak_unref(G_OBJECT(p->rchannel), channel_weak_notified, gstaudio);
+ p->rchannel = NULL;
+
+ if (G_OBJECT_CLASS(spice_gstaudio_parent_class)->dispose)
+ G_OBJECT_CLASS(spice_gstaudio_parent_class)->dispose(obj);
+}
+
+static void spice_gstaudio_init(SpiceGstaudio *gstaudio)
+{
+ gstaudio->priv = SPICE_GSTAUDIO_GET_PRIVATE(gstaudio);
+}
+
+static void spice_gstaudio_class_init(SpiceGstaudioClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceAudioClass *audio_class = SPICE_AUDIO_CLASS(klass);
+
+ audio_class->connect_channel = connect_channel;
+ audio_class->get_playback_volume_info_async = spice_gstaudio_get_playback_volume_info_async;
+ audio_class->get_playback_volume_info_finish = spice_gstaudio_get_playback_volume_info_finish;
+ audio_class->get_record_volume_info_async = spice_gstaudio_get_record_volume_info_async;
+ audio_class->get_record_volume_info_finish = spice_gstaudio_get_record_volume_info_finish;
+
+ gobject_class->finalize = spice_gstaudio_finalize;
+ gobject_class->dispose = spice_gstaudio_dispose;
+
+ g_type_class_add_private(klass, sizeof(SpiceGstaudioPrivate));
+}
+
+static GstFlowReturn record_new_buffer(GstAppSink *appsink, gpointer data)
+{
+ SpiceGstaudio *gstaudio = data;
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+ GstMessage *msg;
+
+ g_return_val_if_fail(p != NULL, GST_FLOW_ERROR);
+
+ msg = gst_message_new_application(GST_OBJECT(p->record.pipe),
+ gst_structure_new_empty ("new-sample"));
+ gst_element_post_message(p->record.pipe, msg);
+ return GST_FLOW_OK;
+}
+
+static void record_stop(SpiceGstaudio *gstaudio)
+{
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+ if (p->record.pipe)
+ gst_element_set_state(p->record.pipe, GST_STATE_READY);
+}
+
+static gboolean record_bus_cb(GstBus *bus, GstMessage *msg, gpointer data)
+{
+ SpiceGstaudio *gstaudio = data;
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+
+ g_return_val_if_fail(p != NULL, FALSE);
+
+ switch (GST_MESSAGE_TYPE(msg)) {
+ case GST_MESSAGE_APPLICATION: {
+ GstSample *s;
+ GstBuffer *buffer;
+ GstMapInfo mapping;
+
+ s = gst_app_sink_pull_sample(GST_APP_SINK(p->record.sink));
+ if (!s) {
+ if (!gst_app_sink_is_eos(GST_APP_SINK(p->record.sink)))
+ g_warning("eos not reached, but can't pull new sample");
+ return TRUE;
+ }
+
+ buffer = gst_sample_get_buffer(s);
+ if (!buffer) {
+ if (!gst_app_sink_is_eos(GST_APP_SINK(p->record.sink)))
+ g_warning("eos not reached, but can't pull new buffer");
+ return TRUE;
+ }
+ if (!gst_buffer_map(buffer, &mapping, GST_MAP_READ)) {
+ return TRUE;
+ }
+
+ spice_record_send_data(SPICE_RECORD_CHANNEL(p->rchannel),
+ /* FIXME: server side doesn't care about ts?
+ what is the unit? ms apparently */
+ mapping.data, mapping.size, 0);
+ gst_buffer_unmap(buffer, &mapping);
+ gst_sample_unref(s);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+static void record_start(SpiceRecordChannel *channel, gint format, gint channels,
+ gint frequency, gpointer data)
+{
+ SpiceGstaudio *gstaudio = data;
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+
+ g_return_if_fail(p != NULL);
+ g_return_if_fail(format == SPICE_AUDIO_FMT_S16);
+
+ if (p->record.pipe &&
+ (p->record.rate != frequency ||
+ p->record.channels != channels)) {
+ record_stop(gstaudio);
+ g_clear_pointer(&p->record.pipe, gst_object_unref);
+ }
+
+ if (!p->record.pipe) {
+ GError *error = NULL;
+ GstBus *bus;
+ gchar *audio_caps =
+ g_strdup_printf("audio/x-raw,format=\"S16LE\",channels=%d,rate=%d,"
+ "layout=interleaved", channels, frequency);
+ gchar *pipeline =
+ g_strdup_printf("autoaudiosrc name=audiosrc ! queue ! audioconvert ! audioresample ! "
+ "appsink caps=\"%s\" name=appsink", audio_caps);
+
+ p->record.pipe = gst_parse_launch(pipeline, &error);
+ if (error != NULL) {
+ g_warning("Failed to create pipeline: %s", error->message);
+ goto cleanup;
+ }
+
+ bus = gst_pipeline_get_bus(GST_PIPELINE(p->record.pipe));
+ gst_bus_add_watch(bus, record_bus_cb, data);
+ gst_object_unref(GST_OBJECT(bus));
+
+ p->record.src = gst_bin_get_by_name(GST_BIN(p->record.pipe), "audiosrc");
+ p->record.sink = gst_bin_get_by_name(GST_BIN(p->record.pipe), "appsink");
+ p->record.rate = frequency;
+ p->record.channels = channels;
+
+ gst_app_sink_set_emit_signals(GST_APP_SINK(p->record.sink), TRUE);
+ spice_g_signal_connect_object(p->record.sink, "new-sample",
+ G_CALLBACK(record_new_buffer), gstaudio, 0);
+
+cleanup:
+ if (error != NULL)
+ g_clear_pointer(&p->record.pipe, gst_object_unref);
+ g_clear_error(&error);
+ g_free(audio_caps);
+ g_free(pipeline);
+ }
+
+ if (p->record.pipe)
+ gst_element_set_state(p->record.pipe, GST_STATE_PLAYING);
+}
+
+static void playback_stop(SpiceGstaudio *gstaudio)
+{
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+
+ if (p->playback.pipe)
+ gst_element_set_state(p->playback.pipe, GST_STATE_READY);
+ if (p->mmtime_id != 0) {
+ g_source_remove(p->mmtime_id);
+ p->mmtime_id = 0;
+ }
+}
+
+static gboolean update_mmtime_timeout_cb(gpointer data)
+{
+ SpiceGstaudio *gstaudio = data;
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+ GstQuery *q;
+
+ q = gst_query_new_latency();
+ if (gst_element_query(p->playback.pipe, q)) {
+ gboolean live;
+ GstClockTime minlat, maxlat;
+ gst_query_parse_latency(q, &live, &minlat, &maxlat);
+ SPICE_DEBUG("got min latency %" GST_TIME_FORMAT ", max latency %"
+ GST_TIME_FORMAT ", live %d", GST_TIME_ARGS (minlat),
+ GST_TIME_ARGS (maxlat), live);
+ spice_playback_channel_set_delay(SPICE_PLAYBACK_CHANNEL(p->pchannel), GST_TIME_AS_MSECONDS(minlat));
+ }
+ gst_query_unref (q);
+
+ return TRUE;
+}
+
+static void playback_start(SpicePlaybackChannel *channel, gint format, gint channels,
+ gint frequency, gpointer data)
+{
+ SpiceGstaudio *gstaudio = data;
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+
+ g_return_if_fail(p != NULL);
+ g_return_if_fail(format == SPICE_AUDIO_FMT_S16);
+
+ if (p->playback.pipe &&
+ (p->playback.rate != frequency ||
+ p->playback.channels != channels)) {
+ playback_stop(gstaudio);
+ g_clear_pointer(&p->playback.pipe, gst_object_unref);
+ }
+
+ if (!p->playback.pipe) {
+ GError *error = NULL;
+ gchar *audio_caps =
+ g_strdup_printf("audio/x-raw,format=\"S16LE\",channels=%d,rate=%d,"
+ "layout=interleaved", channels, frequency);
+ gchar *pipeline = g_strdup (g_getenv("SPICE_GST_AUDIOSINK"));
+ if (pipeline == NULL)
+ pipeline = g_strdup_printf("appsrc is-live=1 do-timestamp=0 caps=\"%s\" name=\"appsrc\" ! queue ! "
+ "audioconvert ! audioresample ! autoaudiosink name=\"audiosink\"", audio_caps);
+ SPICE_DEBUG("audio pipeline: %s", pipeline);
+ p->playback.pipe = gst_parse_launch(pipeline, &error);
+ if (error != NULL) {
+ g_warning("Failed to create pipeline: %s", error->message);
+ goto cleanup;
+ }
+ p->playback.src = gst_bin_get_by_name(GST_BIN(p->playback.pipe), "appsrc");
+ p->playback.sink = gst_bin_get_by_name(GST_BIN(p->playback.pipe), "audiosink");
+ p->playback.rate = frequency;
+ p->playback.channels = channels;
+
+cleanup:
+ if (error != NULL)
+ g_clear_pointer(&p->playback.pipe, gst_object_unref);
+ g_clear_error(&error);
+ g_free(audio_caps);
+ g_free(pipeline);
+ }
+
+ if (p->playback.pipe)
+ gst_element_set_state(p->playback.pipe, GST_STATE_PLAYING);
+
+ if (p->mmtime_id == 0) {
+ update_mmtime_timeout_cb(gstaudio);
+ p->mmtime_id = g_timeout_add_seconds(1, update_mmtime_timeout_cb, gstaudio);
+ }
+}
+
+static void playback_data(SpicePlaybackChannel *channel,
+ gpointer *audio, gint size,
+ gpointer data)
+{
+ SpiceGstaudio *gstaudio = data;
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+ GstBuffer *buf;
+
+ g_return_if_fail(p != NULL);
+
+ audio = g_memdup(audio, size); /* TODO: try to avoid memory copy */
+ buf = gst_buffer_new_wrapped(audio, size);
+ gst_app_src_push_buffer(GST_APP_SRC(p->playback.src), buf);
+}
+
+#define VOLUME_NORMAL 65535
+
+static void playback_volume_changed(GObject *object, GParamSpec *pspec, gpointer data)
+{
+ SpiceGstaudio *gstaudio = data;
+ GstElement *e;
+ guint16 *volume;
+ guint nchannels;
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+ gdouble vol;
+
+ if (!p->playback.sink)
+ return;
+
+ g_object_get(object,
+ "volume", &volume,
+ "nchannels", &nchannels,
+ NULL);
+
+ g_return_if_fail(nchannels > 0);
+
+ vol = 1.0 * volume[0] / VOLUME_NORMAL;
+ SPICE_DEBUG("playback volume changed to %u (%0.2f)", volume[0], 100*vol);
+
+ if (GST_IS_BIN(p->playback.sink))
+ e = gst_bin_get_by_interface(GST_BIN(p->playback.sink), GST_TYPE_STREAM_VOLUME);
+ else
+ e = g_object_ref(p->playback.sink);
+
+ if (GST_IS_STREAM_VOLUME(e))
+ gst_stream_volume_set_volume(GST_STREAM_VOLUME(e), GST_STREAM_VOLUME_FORMAT_CUBIC, vol);
+ else
+ g_object_set(e, "volume", vol, NULL);
+
+ g_object_unref(e);
+}
+
+static void playback_mute_changed(GObject *object, GParamSpec *pspec, gpointer data)
+{
+ SpiceGstaudio *gstaudio = data;
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+ GstElement *e;
+ gboolean mute;
+
+ if (!p->playback.sink)
+ return;
+
+ g_object_get(object, "mute", &mute, NULL);
+ SPICE_DEBUG("playback mute changed to %d", mute);
+
+ if (GST_IS_BIN(p->playback.sink))
+ e = gst_bin_get_by_interface(GST_BIN(p->playback.sink), GST_TYPE_STREAM_VOLUME);
+ else
+ e = g_object_ref(p->playback.sink);
+
+ if (GST_IS_STREAM_VOLUME(e))
+ gst_stream_volume_set_mute(GST_STREAM_VOLUME(e), mute);
+
+ g_object_unref(e);
+}
+
+static void record_volume_changed(GObject *object, GParamSpec *pspec, gpointer data)
+{
+ SpiceGstaudio *gstaudio = data;
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+ GstElement *e;
+ guint16 *volume;
+ guint nchannels;
+ gdouble vol;
+
+ if (!p->record.src)
+ return;
+
+ g_object_get(object,
+ "volume", &volume,
+ "nchannels", &nchannels,
+ NULL);
+
+ g_return_if_fail(nchannels > 0);
+
+ vol = 1.0 * volume[0] / VOLUME_NORMAL;
+ SPICE_DEBUG("record volume changed to %u (%0.2f)", volume[0], 100*vol);
+
+ /* TODO directsoundsrc doesn't support IDirectSoundBuffer_SetVolume */
+ /* TODO pulsesrc doesn't support volume property, it's all coming! */
+
+ if (GST_IS_BIN(p->record.src))
+ e = gst_bin_get_by_interface(GST_BIN(p->record.src), GST_TYPE_STREAM_VOLUME);
+ else
+ e = g_object_ref(p->record.src);
+
+ if (GST_IS_STREAM_VOLUME(e))
+ gst_stream_volume_set_volume(GST_STREAM_VOLUME(e), GST_STREAM_VOLUME_FORMAT_CUBIC, vol);
+ else
+ g_warning("gst lacks volume capabilities on src (TODO)");
+
+ g_object_unref(e);
+}
+
+static void record_mute_changed(GObject *object, GParamSpec *pspec, gpointer data)
+{
+ SpiceGstaudio *gstaudio = data;
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+ GstElement *e;
+ gboolean mute;
+
+ if (!p->record.src)
+ return;
+
+ g_object_get(object, "mute", &mute, NULL);
+ SPICE_DEBUG("record mute changed to %d", mute);
+
+ if (GST_IS_BIN(p->record.src))
+ e = gst_bin_get_by_interface(GST_BIN(p->record.src), GST_TYPE_STREAM_VOLUME);
+ else
+ e = g_object_ref(p->record.src);
+
+ if (GST_IS_STREAM_VOLUME (e))
+ gst_stream_volume_set_mute(GST_STREAM_VOLUME(e), mute);
+ else
+ g_warning("gst lacks mute capabilities on src: %d (TODO)", mute);
+
+ g_object_unref(e);
+}
+
+static void
+channel_weak_notified(gpointer data,
+ GObject *where_the_object_was)
+{
+ SpiceGstaudio *gstaudio = SPICE_GSTAUDIO(data);
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+
+ if (where_the_object_was == (GObject *)p->pchannel) {
+ SPICE_DEBUG("playback closed");
+ playback_stop(gstaudio);
+ p->pchannel = NULL;
+ } else if (where_the_object_was == (GObject *)p->rchannel) {
+ SPICE_DEBUG("record closed");
+ record_stop(gstaudio);
+ p->rchannel = NULL;
+ }
+}
+
+static gboolean connect_channel(SpiceAudio *audio, SpiceChannel *channel)
+{
+ SpiceGstaudio *gstaudio = SPICE_GSTAUDIO(audio);
+ SpiceGstaudioPrivate *p = gstaudio->priv;
+
+ if (SPICE_IS_PLAYBACK_CHANNEL(channel)) {
+ g_return_val_if_fail(p->pchannel == NULL, FALSE);
+
+ p->pchannel = channel;
+ g_object_weak_ref(G_OBJECT(p->pchannel), channel_weak_notified, audio);
+ spice_g_signal_connect_object(channel, "playback-start",
+ G_CALLBACK(playback_start), gstaudio, 0);
+ spice_g_signal_connect_object(channel, "playback-data",
+ G_CALLBACK(playback_data), gstaudio, 0);
+ spice_g_signal_connect_object(channel, "playback-stop",
+ G_CALLBACK(playback_stop), gstaudio, G_CONNECT_SWAPPED);
+ spice_g_signal_connect_object(channel, "notify::volume",
+ G_CALLBACK(playback_volume_changed), gstaudio, 0);
+ spice_g_signal_connect_object(channel, "notify::mute",
+ G_CALLBACK(playback_mute_changed), gstaudio, 0);
+
+ return TRUE;
+ }
+
+ if (SPICE_IS_RECORD_CHANNEL(channel)) {
+ g_return_val_if_fail(p->rchannel == NULL, FALSE);
+
+ p->rchannel = channel;
+ g_object_weak_ref(G_OBJECT(p->rchannel), channel_weak_notified, audio);
+ spice_g_signal_connect_object(channel, "record-start",
+ G_CALLBACK(record_start), gstaudio, 0);
+ spice_g_signal_connect_object(channel, "record-stop",
+ G_CALLBACK(record_stop), gstaudio, G_CONNECT_SWAPPED);
+ spice_g_signal_connect_object(channel, "notify::volume",
+ G_CALLBACK(record_volume_changed), gstaudio, 0);
+ spice_g_signal_connect_object(channel, "notify::mute",
+ G_CALLBACK(record_mute_changed), gstaudio, 0);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+SpiceGstaudio *spice_gstaudio_new(SpiceSession *session, GMainContext *context,
+ const char *name)
+{
+ GError *err = NULL;
+ if (gst_init_check(NULL, NULL, &err)) {
+ return g_object_new(SPICE_TYPE_GSTAUDIO,
+ "session", session,
+ "main-context", context,
+ NULL);
+ }
+
+ g_warning("Disabling GStreamer audio support: %s", err->message);
+ g_clear_error(&err);
+ return NULL;
+}
+
+static void spice_gstaudio_get_playback_volume_info_async(SpiceAudio *audio,
+ GCancellable *cancellable,
+ SpiceMainChannel *main_channel,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task = g_task_new(audio, cancellable, callback, user_data);
+
+ g_task_return_boolean(task, TRUE);
+}
+
+static gboolean spice_gstaudio_get_playback_volume_info_finish(SpiceAudio *audio,
+ GAsyncResult *res,
+ gboolean *mute,
+ guint8 *nchannels,
+ guint16 **volume,
+ GError **error)
+{
+ SpiceGstaudioPrivate *p = SPICE_GSTAUDIO(audio)->priv;
+ GstElement *e;
+ gboolean lmute;
+ gdouble vol;
+ gboolean fake_channel = FALSE;
+ GTask *task = G_TASK(res);
+
+ g_return_val_if_fail(g_task_is_valid(task, audio), FALSE);
+
+ if (g_task_had_error(task)) {
+ /* set out args that should have new alloc'ed memory to NULL */
+ if (volume != NULL) {
+ *volume = NULL;
+ }
+ return g_task_propagate_boolean(task, error);
+ }
+
+ if (p->playback.sink == NULL || p->playback.channels == 0) {
+ SPICE_DEBUG("PlaybackChannel not created yet, force start");
+ /* In order to get system volume, we start the pipeline */
+ playback_start(NULL, SPICE_AUDIO_FMT_S16, 2, 48000, audio);
+ fake_channel = TRUE;
+ }
+
+ if (GST_IS_BIN(p->playback.sink))
+ e = gst_bin_get_by_interface(GST_BIN(p->playback.sink), GST_TYPE_STREAM_VOLUME);
+ else
+ e = g_object_ref(p->playback.sink);
+
+ if (GST_IS_STREAM_VOLUME(e)) {
+ vol = gst_stream_volume_get_volume(GST_STREAM_VOLUME(e), GST_STREAM_VOLUME_FORMAT_CUBIC);
+ lmute = gst_stream_volume_get_mute(GST_STREAM_VOLUME(e));
+ } else {
+ g_object_get(e,
+ "volume", &vol,
+ "mute", &lmute, NULL);
+ }
+ g_object_unref(e);
+
+ if (fake_channel) {
+ SPICE_DEBUG("Stop faked PlaybackChannel");
+ playback_stop(SPICE_GSTAUDIO(audio));
+ }
+
+ if (mute != NULL) {
+ *mute = lmute;
+ }
+
+ if (nchannels != NULL) {
+ *nchannels = p->playback.channels;
+ }
+
+ if (volume != NULL) {
+ gint i;
+ *volume = g_new(guint16, p->playback.channels);
+ for (i = 0; i < p->playback.channels; i++) {
+ (*volume)[i] = (guint16) (vol * VOLUME_NORMAL);
+ SPICE_DEBUG("(playback) volume at %d is %u (%0.2f%%)", i, (*volume)[i], 100*vol);
+ }
+ }
+
+ return g_task_propagate_boolean(task, error);
+}
+
+static void spice_gstaudio_get_record_volume_info_async(SpiceAudio *audio,
+ GCancellable *cancellable,
+ SpiceMainChannel *main_channel,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task = g_task_new(audio, cancellable, callback, user_data);
+
+ g_task_return_boolean(task, TRUE);
+}
+
+static gboolean spice_gstaudio_get_record_volume_info_finish(SpiceAudio *audio,
+ GAsyncResult *res,
+ gboolean *mute,
+ guint8 *nchannels,
+ guint16 **volume,
+ GError **error)
+{
+ SpiceGstaudioPrivate *p = SPICE_GSTAUDIO(audio)->priv;
+ GstElement *e;
+ gboolean lmute;
+ gdouble vol;
+ gboolean fake_channel = FALSE;
+ GTask *task = G_TASK(res);
+
+ g_return_val_if_fail(g_task_is_valid(task, audio), FALSE);
+
+ if (g_task_had_error(task)) {
+ /* set out args that should have new alloc'ed memory to NULL */
+ if (volume != NULL) {
+ *volume = NULL;
+ }
+ return g_task_propagate_boolean(task, error);
+ }
+
+ if (p->record.src == NULL || p->record.channels == 0) {
+ SPICE_DEBUG("RecordChannel not created yet, force start");
+ /* In order to get system volume, we start the pipeline */
+ record_start(NULL, SPICE_AUDIO_FMT_S16, 2, 48000, audio);
+ fake_channel = TRUE;
+ }
+
+ if (GST_IS_BIN(p->record.src))
+ e = gst_bin_get_by_interface(GST_BIN(p->record.src), GST_TYPE_STREAM_VOLUME);
+ else
+ e = g_object_ref(p->record.src);
+
+ if (GST_IS_STREAM_VOLUME(e)) {
+ vol = gst_stream_volume_get_volume(GST_STREAM_VOLUME(e), GST_STREAM_VOLUME_FORMAT_CUBIC);
+ lmute = gst_stream_volume_get_mute(GST_STREAM_VOLUME(e));
+ } else {
+ g_object_get(e,
+ "volume", &vol,
+ "mute", &lmute, NULL);
+ }
+ g_object_unref(e);
+
+ if (fake_channel) {
+ SPICE_DEBUG("Stop faked RecordChannel");
+ record_stop(SPICE_GSTAUDIO(audio));
+ }
+
+ if (mute != NULL) {
+ *mute = lmute;
+ }
+
+ if (nchannels != NULL) {
+ *nchannels = p->record.channels;
+ }
+
+ if (volume != NULL) {
+ gint i;
+ *volume = g_new(guint16, p->record.channels);
+ for (i = 0; i < p->record.channels; i++) {
+ (*volume)[i] = (guint16) (vol * VOLUME_NORMAL);
+ SPICE_DEBUG("(record) volume at %d is %u (%0.2f%%)", i, (*volume)[i], 100*vol);
+ }
+ }
+
+ return g_task_propagate_boolean(task, error);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_GSTAUDIO_H__
+#define __SPICE_CLIENT_GSTAUDIO_H__
+
+#include "spice-client.h"
+#include "spice-audio.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_GSTAUDIO (spice_gstaudio_get_type())
+#define SPICE_GSTAUDIO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_GSTAUDIO, SpiceGstaudio))
+#define SPICE_GSTAUDIO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_GSTAUDIO, SpiceGstaudioClass))
+#define SPICE_IS_GSTAUDIO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_GSTAUDIO))
+#define SPICE_IS_GSTAUDIO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_GSTAUDIO))
+#define SPICE_GSTAUDIO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_GSTAUDIO, SpiceGstaudioClass))
+
+
+typedef struct _SpiceGstaudio SpiceGstaudio;
+typedef struct _SpiceGstaudioClass SpiceGstaudioClass;
+typedef struct _SpiceGstaudioPrivate SpiceGstaudioPrivate;
+
+struct _SpiceGstaudio {
+ SpiceAudio parent;
+ SpiceGstaudioPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+struct _SpiceGstaudioClass {
+ SpiceAudioClass parent_class;
+ /* Do not add fields to this struct */
+};
+
+GType spice_gstaudio_get_type(void);
+
+SpiceGstaudio *spice_gstaudio_new(SpiceSession *session,
+ GMainContext *context, const char *name);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_GSTAUDIO_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010-2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_GTK_SESSION_PRIV_H__
+#define __SPICE_CLIENT_GTK_SESSION_PRIV_H__
+
+#include "spice-gtk-session.h"
+
+G_BEGIN_DECLS
+
+typedef struct _SpiceGtkSessionPrivate SpiceGtkSessionPrivate;
+
+struct _SpiceGtkSession
+{
+ GObject parent;
+ SpiceGtkSessionPrivate *priv;
+};
+
+struct _SpiceGtkSessionClass
+{
+ GObjectClass parent_class;
+};
+
+void spice_gtk_session_request_auto_usbredir(SpiceGtkSession *self,
+ gboolean state);
+gboolean spice_gtk_session_get_read_only(SpiceGtkSession *self);
+void spice_gtk_session_sync_keyboard_modifiers(SpiceGtkSession *self);
+void spice_gtk_session_set_pointer_grabbed(SpiceGtkSession *self, gboolean grabbed);
+gboolean spice_gtk_session_get_pointer_grabbed(SpiceGtkSession *self);
+void spice_gtk_session_set_keyboard_has_focus(SpiceGtkSession *self, gboolean keyboard_has_focus);
+void spice_gtk_session_set_mouse_has_pointer(SpiceGtkSession *self, gboolean mouse_has_pointer);
+gboolean spice_gtk_session_get_keyboard_has_focus(SpiceGtkSession *self);
+gboolean spice_gtk_session_get_mouse_has_pointer(SpiceGtkSession *self);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_GTK_SESSION_PRIV_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010-2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <glib.h>
+
+#ifdef HAVE_X11_XKBLIB_H
+#include <X11/XKBlib.h>
+#include <gdk/gdkx.h>
+#endif
+#ifdef GDK_WINDOWING_X11
+#include <X11/Xlib.h>
+#include <gdk/gdkx.h>
+#endif
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include <gdk/gdkwin32.h>
+#ifndef MAPVK_VK_TO_VSC /* may be undefined in older mingw-headers */
+#define MAPVK_VK_TO_VSC 0
+#endif
+#endif
+
+#include <gtk/gtk.h>
+#include <spice/vd_agent.h>
+#include "desktop-integration.h"
+#include "spice-common.h"
+#include "spice-gtk-session.h"
+#include "spice-gtk-session-priv.h"
+#include "spice-session-priv.h"
+#include "spice-util-priv.h"
+#include "spice-channel-priv.h"
+
+#define CLIPBOARD_LAST (VD_AGENT_CLIPBOARD_SELECTION_SECONDARY + 1)
+
+struct _SpiceGtkSessionPrivate {
+ SpiceSession *session;
+ /* Clipboard related */
+ gboolean auto_clipboard_enable;
+ SpiceMainChannel *main;
+ GtkClipboard *clipboard;
+ GtkClipboard *clipboard_primary;
+ GtkTargetEntry *clip_targets[CLIPBOARD_LAST];
+ guint nclip_targets[CLIPBOARD_LAST];
+ gboolean clip_hasdata[CLIPBOARD_LAST];
+ gboolean clip_grabbed[CLIPBOARD_LAST];
+ gboolean clipboard_by_guest[CLIPBOARD_LAST];
+ /* auto-usbredir related */
+ gboolean auto_usbredir_enable;
+ int auto_usbredir_reqs;
+ gboolean pointer_grabbed;
+ gboolean keyboard_has_focus;
+ gboolean mouse_has_pointer;
+ gboolean sync_modifiers;
+};
+
+/**
+ * SECTION:spice-gtk-session
+ * @short_description: handles GTK connection details
+ * @title: Spice GTK Session
+ * @section_id:
+ * @see_also: #SpiceSession, and the GTK widget #SpiceDisplay
+ * @stability: Stable
+ * @include: spice-client-gtk.h
+ *
+ * The #SpiceGtkSession class is the spice-client-gtk counter part of
+ * #SpiceSession. It contains functionality which should be handled per
+ * session rather then per #SpiceDisplay (one session can have multiple
+ * displays), but which cannot live in #SpiceSession as it depends on
+ * GTK. For example the clipboard functionality.
+ *
+ * There should always be a 1:1 relation between #SpiceGtkSession objects
+ * and #SpiceSession objects. Therefor there is no spice_gtk_session_new,
+ * instead there is spice_gtk_session_get() which ensures this 1:1 relation.
+ *
+ * Client and guest clipboards will be shared automatically if
+ * #SpiceGtkSession:auto-clipboard is set to #TRUE. Alternatively, you
+ * can send / receive clipboard data from client to guest with
+ * spice_gtk_session_copy_to_guest() / spice_gtk_session_paste_from_guest().
+ */
+
+/* ------------------------------------------------------------------ */
+/* Prototypes for private functions */
+static void clipboard_owner_change(GtkClipboard *clipboard,
+ GdkEventOwnerChange *event,
+ gpointer user_data);
+static void channel_new(SpiceSession *session, SpiceChannel *channel,
+ gpointer user_data);
+static void channel_destroy(SpiceSession *session, SpiceChannel *channel,
+ gpointer user_data);
+static gboolean read_only(SpiceGtkSession *self);
+
+/* ------------------------------------------------------------------ */
+/* gobject glue */
+
+#define SPICE_GTK_SESSION_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SPICE_TYPE_GTK_SESSION, SpiceGtkSessionPrivate))
+
+G_DEFINE_TYPE (SpiceGtkSession, spice_gtk_session, G_TYPE_OBJECT);
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_SESSION,
+ PROP_AUTO_CLIPBOARD,
+ PROP_AUTO_USBREDIR,
+ PROP_POINTER_GRABBED,
+ PROP_SYNC_MODIFIERS,
+};
+
+static guint32 get_keyboard_lock_modifiers(void)
+{
+ guint32 modifiers = 0;
+#if GTK_CHECK_VERSION(3,18,0)
+ GdkKeymap *keyboard = gdk_keymap_get_default();
+
+ if (gdk_keymap_get_caps_lock_state(keyboard)) {
+ modifiers |= SPICE_INPUTS_CAPS_LOCK;
+ }
+
+ if (gdk_keymap_get_num_lock_state(keyboard)) {
+ modifiers |= SPICE_INPUTS_NUM_LOCK;
+ }
+
+ if (gdk_keymap_get_scroll_lock_state(keyboard)) {
+ modifiers |= SPICE_INPUTS_SCROLL_LOCK;
+ }
+#else
+#ifdef HAVE_X11_XKBLIB_H
+ Display *x_display = NULL;
+ XKeyboardState keyboard_state;
+
+ GdkScreen *screen = gdk_screen_get_default();
+ if (!GDK_IS_X11_DISPLAY(gdk_screen_get_display(screen))) {
+ SPICE_DEBUG("FIXME: gtk backend is not X11");
+ return 0;
+ }
+
+ x_display = GDK_SCREEN_XDISPLAY(screen);
+ XGetKeyboardControl(x_display, &keyboard_state);
+
+ if (keyboard_state.led_mask & 0x01) {
+ modifiers |= SPICE_INPUTS_CAPS_LOCK;
+ }
+ if (keyboard_state.led_mask & 0x02) {
+ modifiers |= SPICE_INPUTS_NUM_LOCK;
+ }
+ if (keyboard_state.led_mask & 0x04) {
+ modifiers |= SPICE_INPUTS_SCROLL_LOCK;
+ }
+#elif defined(G_OS_WIN32)
+ if (GetKeyState(VK_CAPITAL) & 1) {
+ modifiers |= SPICE_INPUTS_CAPS_LOCK;
+ }
+ if (GetKeyState(VK_NUMLOCK) & 1) {
+ modifiers |= SPICE_INPUTS_NUM_LOCK;
+ }
+ if (GetKeyState(VK_SCROLL) & 1) {
+ modifiers |= SPICE_INPUTS_SCROLL_LOCK;
+ }
+#else
+ g_warning("get_keyboard_lock_modifiers not implemented");
+#endif // HAVE_X11_XKBLIB_H
+#endif // GTK_CHECK_VERSION(3,18,0)
+ return modifiers;
+}
+
+static void spice_gtk_session_sync_keyboard_modifiers_for_channel(SpiceGtkSession *self,
+ SpiceInputsChannel* inputs,
+ gboolean force)
+{
+ guint32 guest_modifiers = 0, client_modifiers = 0;
+
+ g_return_if_fail(SPICE_IS_INPUTS_CHANNEL(inputs));
+
+ if (SPICE_IS_GTK_SESSION(self) && !self->priv->sync_modifiers) {
+ SPICE_DEBUG("Syncing modifiers is disabled");
+ return;
+ }
+
+ g_object_get(inputs, "key-modifiers", &guest_modifiers, NULL);
+ client_modifiers = get_keyboard_lock_modifiers();
+
+ if (force || client_modifiers != guest_modifiers) {
+ CHANNEL_DEBUG(inputs, "client_modifiers:0x%x, guest_modifiers:0x%x",
+ client_modifiers, guest_modifiers);
+ spice_inputs_set_key_locks(inputs, client_modifiers);
+ }
+}
+
+static void keymap_modifiers_changed(GdkKeymap *keymap, gpointer data)
+{
+ SpiceGtkSession *self = data;
+
+ spice_gtk_session_sync_keyboard_modifiers(self);
+}
+
+static void guest_modifiers_changed(SpiceInputsChannel *inputs, gpointer data)
+{
+ SpiceGtkSession *self = data;
+
+ spice_gtk_session_sync_keyboard_modifiers_for_channel(self, inputs, FALSE);
+}
+
+static void spice_gtk_session_init(SpiceGtkSession *self)
+{
+ SpiceGtkSessionPrivate *s;
+ GdkKeymap *keymap = gdk_keymap_get_default();
+
+ s = self->priv = SPICE_GTK_SESSION_GET_PRIVATE(self);
+
+ s->clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+ g_signal_connect(G_OBJECT(s->clipboard), "owner-change",
+ G_CALLBACK(clipboard_owner_change), self);
+ s->clipboard_primary = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
+ g_signal_connect(G_OBJECT(s->clipboard_primary), "owner-change",
+ G_CALLBACK(clipboard_owner_change), self);
+ spice_g_signal_connect_object(keymap, "state-changed",
+ G_CALLBACK(keymap_modifiers_changed), self, 0);
+}
+
+static GObject *
+spice_gtk_session_constructor(GType gtype,
+ guint n_properties,
+ GObjectConstructParam *properties)
+{
+ GObject *obj;
+ SpiceGtkSession *self;
+ SpiceGtkSessionPrivate *s;
+ GList *list;
+ GList *it;
+
+ {
+ /* Always chain up to the parent constructor */
+ GObjectClass *parent_class;
+ parent_class = G_OBJECT_CLASS(spice_gtk_session_parent_class);
+ obj = parent_class->constructor(gtype, n_properties, properties);
+ }
+
+ self = SPICE_GTK_SESSION(obj);
+ s = self->priv;
+ if (!s->session)
+ g_error("SpiceGtKSession constructed without a session");
+
+ g_signal_connect(s->session, "channel-new",
+ G_CALLBACK(channel_new), self);
+ g_signal_connect(s->session, "channel-destroy",
+ G_CALLBACK(channel_destroy), self);
+ list = spice_session_get_channels(s->session);
+ for (it = g_list_first(list); it != NULL; it = g_list_next(it)) {
+ channel_new(s->session, it->data, (gpointer*)self);
+ }
+ g_list_free(list);
+
+ return obj;
+}
+
+static void spice_gtk_session_dispose(GObject *gobject)
+{
+ SpiceGtkSession *self = SPICE_GTK_SESSION(gobject);
+ SpiceGtkSessionPrivate *s = self->priv;
+
+ /* release stuff */
+ if (s->clipboard) {
+ g_signal_handlers_disconnect_by_func(s->clipboard,
+ G_CALLBACK(clipboard_owner_change), self);
+ s->clipboard = NULL;
+ }
+
+ if (s->clipboard_primary) {
+ g_signal_handlers_disconnect_by_func(s->clipboard_primary,
+ G_CALLBACK(clipboard_owner_change), self);
+ s->clipboard_primary = NULL;
+ }
+
+ if (s->session) {
+ g_signal_handlers_disconnect_by_func(s->session,
+ G_CALLBACK(channel_new),
+ self);
+ g_signal_handlers_disconnect_by_func(s->session,
+ G_CALLBACK(channel_destroy),
+ self);
+ s->session = NULL;
+ }
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_gtk_session_parent_class)->dispose)
+ G_OBJECT_CLASS(spice_gtk_session_parent_class)->dispose(gobject);
+}
+
+static void spice_gtk_session_finalize(GObject *gobject)
+{
+ SpiceGtkSession *self = SPICE_GTK_SESSION(gobject);
+ SpiceGtkSessionPrivate *s = self->priv;
+ int i;
+
+ /* release stuff */
+ for (i = 0; i < CLIPBOARD_LAST; ++i) {
+ g_clear_pointer(&s->clip_targets[i], g_free);
+ }
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_gtk_session_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_gtk_session_parent_class)->finalize(gobject);
+}
+
+static void spice_gtk_session_get_property(GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceGtkSession *self = SPICE_GTK_SESSION(gobject);
+ SpiceGtkSessionPrivate *s = self->priv;
+
+ switch (prop_id) {
+ case PROP_SESSION:
+ g_value_set_object(value, s->session);
+ break;
+ case PROP_AUTO_CLIPBOARD:
+ g_value_set_boolean(value, s->auto_clipboard_enable);
+ break;
+ case PROP_AUTO_USBREDIR:
+ g_value_set_boolean(value, s->auto_usbredir_enable);
+ break;
+ case PROP_POINTER_GRABBED:
+ g_value_set_boolean(value, s->pointer_grabbed);
+ break;
+ case PROP_SYNC_MODIFIERS:
+ g_value_set_boolean(value, s->sync_modifiers);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_gtk_session_set_property(GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceGtkSession *self = SPICE_GTK_SESSION(gobject);
+ SpiceGtkSessionPrivate *s = self->priv;
+
+ switch (prop_id) {
+ case PROP_SESSION:
+ s->session = g_value_get_object(value);
+ break;
+ case PROP_AUTO_CLIPBOARD:
+ s->auto_clipboard_enable = g_value_get_boolean(value);
+ break;
+ case PROP_AUTO_USBREDIR: {
+ SpiceDesktopIntegration *desktop_int;
+ gboolean orig_value = s->auto_usbredir_enable;
+
+ s->auto_usbredir_enable = g_value_get_boolean(value);
+ if (s->auto_usbredir_enable == orig_value)
+ break;
+
+ if (s->auto_usbredir_reqs) {
+ SpiceUsbDeviceManager *manager =
+ spice_usb_device_manager_get(s->session, NULL);
+
+ if (!manager)
+ break;
+
+ g_object_set(manager, "auto-connect", s->auto_usbredir_enable,
+ NULL);
+
+ desktop_int = spice_desktop_integration_get(s->session);
+ if (s->auto_usbredir_enable)
+ spice_desktop_integration_inhibit_automount(desktop_int);
+ else
+ spice_desktop_integration_uninhibit_automount(desktop_int);
+ }
+ break;
+ }
+ case PROP_SYNC_MODIFIERS:
+ s->sync_modifiers = g_value_get_boolean(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_gtk_session_class_init(SpiceGtkSessionClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->constructor = spice_gtk_session_constructor;
+ gobject_class->dispose = spice_gtk_session_dispose;
+ gobject_class->finalize = spice_gtk_session_finalize;
+ gobject_class->get_property = spice_gtk_session_get_property;
+ gobject_class->set_property = spice_gtk_session_set_property;
+
+ /**
+ * SpiceGtkSession:session:
+ *
+ * #SpiceSession this #SpiceGtkSession is associated with
+ *
+ * Since: 0.8
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_SESSION,
+ g_param_spec_object("session",
+ "Session",
+ "SpiceSession",
+ SPICE_TYPE_SESSION,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceGtkSession:auto-clipboard:
+ *
+ * When this is true the clipboard gets automatically shared between host
+ * and guest.
+ *
+ * Since: 0.8
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_AUTO_CLIPBOARD,
+ g_param_spec_boolean("auto-clipboard",
+ "Auto clipboard",
+ "Automatically relay clipboard changes between "
+ "host and guest.",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceGtkSession:auto-usbredir:
+ *
+ * Automatically redirect newly plugged in USB devices. Note the auto
+ * redirection only happens when a #SpiceDisplay associated with the
+ * session had keyboard focus.
+ *
+ * Since: 0.8
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_AUTO_USBREDIR,
+ g_param_spec_boolean("auto-usbredir",
+ "Auto USB Redirection",
+ "Automatically redirect newly plugged in USB"
+ "Devices to the guest.",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceGtkSession:pointer-grabbed:
+ *
+ * Returns %TRUE if the pointer is currently grabbed by this session.
+ *
+ * Since: 0.27
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_POINTER_GRABBED,
+ g_param_spec_boolean("pointer-grabbed",
+ "Pointer grabbed",
+ "Whether the pointer is grabbed",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceGtkSession:sync-modifiers:
+ *
+ * Automatically sync modifiers (Caps, Num and Scroll locks) with the guest.
+ *
+ * Since: 0.32
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_SYNC_MODIFIERS,
+ g_param_spec_boolean("sync-modifiers",
+ "Sync modifiers",
+ "Automatically sync modifiers",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_type_class_add_private(klass, sizeof(SpiceGtkSessionPrivate));
+}
+
+/* ---------------------------------------------------------------- */
+/* private functions (clipboard related) */
+
+static GtkClipboard* get_clipboard_from_selection(SpiceGtkSessionPrivate *s,
+ guint selection)
+{
+ if (selection == VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD) {
+ return s->clipboard;
+ } else if (selection == VD_AGENT_CLIPBOARD_SELECTION_PRIMARY) {
+ return s->clipboard_primary;
+ } else {
+ g_warning("Unhandled clipboard selection: %u", selection);
+ return NULL;
+ }
+}
+
+static gint get_selection_from_clipboard(SpiceGtkSessionPrivate *s,
+ GtkClipboard* cb)
+{
+ if (cb == s->clipboard) {
+ return VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
+ } else if (cb == s->clipboard_primary) {
+ return VD_AGENT_CLIPBOARD_SELECTION_PRIMARY;
+ } else {
+ g_warning("Unhandled clipboard");
+ return -1;
+ }
+}
+
+static const struct {
+ const char *xatom;
+ uint32_t vdagent;
+} atom2agent[] = {
+ {
+ .vdagent = VD_AGENT_CLIPBOARD_UTF8_TEXT,
+ .xatom = "UTF8_STRING",
+ },{
+ .vdagent = VD_AGENT_CLIPBOARD_UTF8_TEXT,
+ .xatom = "text/plain;charset=utf-8"
+ },{
+ .vdagent = VD_AGENT_CLIPBOARD_UTF8_TEXT,
+ .xatom = "STRING"
+ },{
+ .vdagent = VD_AGENT_CLIPBOARD_UTF8_TEXT,
+ .xatom = "TEXT"
+ },{
+ .vdagent = VD_AGENT_CLIPBOARD_UTF8_TEXT,
+ .xatom = "text/plain"
+ },{
+ .vdagent = VD_AGENT_CLIPBOARD_IMAGE_PNG,
+ .xatom = "image/png"
+ },{
+ .vdagent = VD_AGENT_CLIPBOARD_IMAGE_BMP,
+ .xatom = "image/bmp"
+ },{
+ .vdagent = VD_AGENT_CLIPBOARD_IMAGE_BMP,
+ .xatom = "image/x-bmp"
+ },{
+ .vdagent = VD_AGENT_CLIPBOARD_IMAGE_BMP,
+ .xatom = "image/x-MS-bmp"
+ },{
+ .vdagent = VD_AGENT_CLIPBOARD_IMAGE_BMP,
+ .xatom = "image/x-win-bitmap"
+ },{
+ .vdagent = VD_AGENT_CLIPBOARD_IMAGE_TIFF,
+ .xatom = "image/tiff"
+ },{
+ .vdagent = VD_AGENT_CLIPBOARD_IMAGE_JPG,
+ .xatom = "image/jpeg"
+ }
+};
+
+typedef struct _WeakRef {
+ GObject *object;
+} WeakRef;
+
+static void weak_notify_cb(WeakRef *weakref, GObject *object)
+{
+ weakref->object = NULL;
+}
+
+static WeakRef* weak_ref(GObject *object)
+{
+ WeakRef *weakref = g_new(WeakRef, 1);
+
+ g_object_weak_ref(object, (GWeakNotify)weak_notify_cb, weakref);
+ weakref->object = object;
+
+ return weakref;
+}
+
+static void weak_unref(WeakRef* weakref)
+{
+ if (weakref->object)
+ g_object_weak_unref(weakref->object, (GWeakNotify)weak_notify_cb, weakref);
+
+ g_free(weakref);
+}
+
+static void clipboard_get_targets(GtkClipboard *clipboard,
+ GdkAtom *atoms,
+ gint n_atoms,
+ gpointer user_data)
+{
+ WeakRef *weakref = user_data;
+ SpiceGtkSession *self = (SpiceGtkSession*)weakref->object;
+ weak_unref(weakref);
+
+ if (self == NULL)
+ return;
+
+ g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+
+ SpiceGtkSessionPrivate *s = self->priv;
+ guint32 types[SPICE_N_ELEMENTS(atom2agent)];
+ char *name;
+ int a, m, t;
+ int selection;
+
+ if (s->main == NULL)
+ return;
+
+ selection = get_selection_from_clipboard(s, clipboard);
+ g_return_if_fail(selection != -1);
+
+ SPICE_DEBUG("%s:", __FUNCTION__);
+ if (spice_util_get_debug()) {
+ for (a = 0; a < n_atoms; a++) {
+ name = gdk_atom_name(atoms[a]);
+ SPICE_DEBUG(" \"%s\"", name);
+ g_free(name);
+ }
+ }
+
+ memset(types, 0, sizeof(types));
+ for (a = 0; a < n_atoms; a++) {
+ name = gdk_atom_name(atoms[a]);
+ for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) {
+ if (strcasecmp(name, atom2agent[m].xatom) != 0) {
+ continue;
+ }
+ /* found match */
+ for (t = 0; t < SPICE_N_ELEMENTS(atom2agent); t++) {
+ if (types[t] == atom2agent[m].vdagent) {
+ /* type already in list */
+ break;
+ }
+ if (types[t] == 0) {
+ /* add type to empty slot */
+ types[t] = atom2agent[m].vdagent;
+ break;
+ }
+ }
+ break;
+ }
+ g_free(name);
+ }
+ for (t = 0; t < SPICE_N_ELEMENTS(atom2agent); t++) {
+ if (types[t] == 0) {
+ break;
+ }
+ }
+ if (!s->clip_grabbed[selection] && t > 0) {
+ s->clip_grabbed[selection] = TRUE;
+
+ if (spice_main_agent_test_capability(s->main, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND))
+ spice_main_clipboard_selection_grab(s->main, selection, types, t);
+ /* Sending a grab causes the agent to do an impicit release */
+ s->nclip_targets[selection] = 0;
+ }
+}
+
+static void clipboard_owner_change(GtkClipboard *clipboard,
+ GdkEventOwnerChange *event,
+ gpointer user_data)
+{
+ g_return_if_fail(SPICE_IS_GTK_SESSION(user_data));
+
+ SpiceGtkSession *self = user_data;
+ SpiceGtkSessionPrivate *s = self->priv;
+ int selection;
+
+ selection = get_selection_from_clipboard(s, clipboard);
+ g_return_if_fail(selection != -1);
+
+ if (s->main == NULL)
+ return;
+
+ if (s->clip_grabbed[selection]) {
+ s->clip_grabbed[selection] = FALSE;
+ if (spice_main_agent_test_capability(s->main, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND))
+ spice_main_clipboard_selection_release(s->main, selection);
+ }
+
+ switch (event->reason) {
+ case GDK_OWNER_CHANGE_NEW_OWNER:
+ if (gtk_clipboard_get_owner(clipboard) == G_OBJECT(self))
+ break;
+
+ s->clipboard_by_guest[selection] = FALSE;
+ s->clip_hasdata[selection] = TRUE;
+ if (s->auto_clipboard_enable && !read_only(self))
+ gtk_clipboard_request_targets(clipboard, clipboard_get_targets,
+ weak_ref(G_OBJECT(self)));
+ break;
+ default:
+ s->clip_hasdata[selection] = FALSE;
+ break;
+ }
+}
+
+typedef struct
+{
+ SpiceGtkSession *self;
+ GMainLoop *loop;
+ GtkSelectionData *selection_data;
+ guint info;
+ guint selection;
+} RunInfo;
+
+static void clipboard_got_from_guest(SpiceMainChannel *main, guint selection,
+ guint type, const guchar *data, guint size,
+ gpointer user_data)
+{
+ RunInfo *ri = user_data;
+ SpiceGtkSessionPrivate *s = ri->self->priv;
+ gchar *conv = NULL;
+
+ g_return_if_fail(selection == ri->selection);
+
+ SPICE_DEBUG("clipboard got data");
+
+ if (atom2agent[ri->info].vdagent == VD_AGENT_CLIPBOARD_UTF8_TEXT) {
+ /* on windows, gtk+ would already convert to LF endings, but
+ not on unix */
+ if (spice_main_agent_test_capability(s->main, VD_AGENT_CAP_GUEST_LINEEND_CRLF)) {
+ conv = spice_dos2unix((gchar*)data, size);
+ size = strlen(conv);
+ }
+
+ gtk_selection_data_set_text(ri->selection_data, conv ?: (gchar*)data, size);
+ } else {
+ gtk_selection_data_set(ri->selection_data,
+ gdk_atom_intern_static_string(atom2agent[ri->info].xatom),
+ 8, data, size);
+ }
+
+ if (g_main_loop_is_running (ri->loop))
+ g_main_loop_quit (ri->loop);
+
+ g_free(conv);
+}
+
+static void clipboard_agent_connected(RunInfo *ri)
+{
+ g_warning("agent status changed, cancel clipboard request");
+
+ if (g_main_loop_is_running(ri->loop))
+ g_main_loop_quit(ri->loop);
+}
+
+static void clipboard_get(GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ guint info, gpointer user_data)
+{
+ g_return_if_fail(SPICE_IS_GTK_SESSION(user_data));
+
+ RunInfo ri = { NULL, };
+ SpiceGtkSession *self = user_data;
+ SpiceGtkSessionPrivate *s = self->priv;
+ gboolean agent_connected = FALSE;
+ gulong clipboard_handler;
+ gulong agent_handler;
+ int selection;
+
+ SPICE_DEBUG("clipboard get");
+
+ selection = get_selection_from_clipboard(s, clipboard);
+ g_return_if_fail(selection != -1);
+ g_return_if_fail(info < SPICE_N_ELEMENTS(atom2agent));
+ g_return_if_fail(s->main != NULL);
+
+ ri.selection_data = selection_data;
+ ri.info = info;
+ ri.loop = g_main_loop_new(NULL, FALSE);
+ ri.selection = selection;
+ ri.self = self;
+
+ clipboard_handler = g_signal_connect(s->main, "main-clipboard-selection",
+ G_CALLBACK(clipboard_got_from_guest),
+ &ri);
+ agent_handler = g_signal_connect_swapped(s->main, "notify::agent-connected",
+ G_CALLBACK(clipboard_agent_connected),
+ &ri);
+
+ spice_main_clipboard_selection_request(s->main, selection,
+ atom2agent[info].vdagent);
+
+
+ g_object_get(s->main, "agent-connected", &agent_connected, NULL);
+ if (!agent_connected) {
+ SPICE_DEBUG("canceled clipboard_get, before running loop");
+ goto cleanup;
+ }
+
+ /* apparently, this is needed to avoid dead-lock, from
+ gtk_dialog_run */
+ gdk_threads_leave();
+ g_main_loop_run(ri.loop);
+ gdk_threads_enter();
+
+cleanup:
+ g_clear_pointer(&ri.loop, g_main_loop_unref);
+ g_signal_handler_disconnect(s->main, clipboard_handler);
+ g_signal_handler_disconnect(s->main, agent_handler);
+}
+
+static void clipboard_clear(GtkClipboard *clipboard, gpointer user_data)
+{
+ SPICE_DEBUG("clipboard_clear");
+ /* We watch for clipboard ownership changes and act on those, so we
+ don't need to do anything here */
+}
+
+static gboolean clipboard_grab(SpiceMainChannel *main, guint selection,
+ guint32* types, guint32 ntypes,
+ gpointer user_data)
+{
+ g_return_val_if_fail(SPICE_IS_GTK_SESSION(user_data), FALSE);
+
+ SpiceGtkSession *self = user_data;
+ SpiceGtkSessionPrivate *s = self->priv;
+ GtkTargetEntry targets[SPICE_N_ELEMENTS(atom2agent)];
+ gboolean target_selected[SPICE_N_ELEMENTS(atom2agent)] = { FALSE, };
+ gboolean found;
+ GtkClipboard* cb;
+ int m, n, i;
+
+ cb = get_clipboard_from_selection(s, selection);
+ g_return_val_if_fail(cb != NULL, FALSE);
+
+ i = 0;
+ for (n = 0; n < ntypes; ++n) {
+ found = FALSE;
+ for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) {
+ if (atom2agent[m].vdagent == types[n] && !target_selected[m]) {
+ found = TRUE;
+ g_return_val_if_fail(i < SPICE_N_ELEMENTS(atom2agent), FALSE);
+ targets[i].target = (gchar*)atom2agent[m].xatom;
+ targets[i].info = m;
+ target_selected[m] = TRUE;
+ i += 1;
+ }
+ }
+ if (!found) {
+ g_warning("clipboard: couldn't find a matching type for: %u",
+ types[n]);
+ }
+ }
+
+ g_free(s->clip_targets[selection]);
+ s->nclip_targets[selection] = i;
+ s->clip_targets[selection] = g_memdup(targets, sizeof(GtkTargetEntry) * i);
+ /* Receiving a grab implies we've released our own grab */
+ s->clip_grabbed[selection] = FALSE;
+
+ if (read_only(self) ||
+ !s->auto_clipboard_enable ||
+ s->nclip_targets[selection] == 0)
+ goto skip_grab_clipboard;
+
+ if (!gtk_clipboard_set_with_owner(cb, targets, i,
+ clipboard_get, clipboard_clear, G_OBJECT(self))) {
+ g_warning("clipboard grab failed");
+ return FALSE;
+ }
+ s->clipboard_by_guest[selection] = TRUE;
+ s->clip_hasdata[selection] = FALSE;
+
+skip_grab_clipboard:
+ return TRUE;
+}
+
+static gboolean check_clipboard_size_limits(SpiceGtkSession *session,
+ gint clipboard_len)
+{
+ int max_clipboard;
+
+ g_object_get(session->priv->main, "max-clipboard", &max_clipboard, NULL);
+ if (max_clipboard != -1 && clipboard_len > max_clipboard) {
+ g_warning("discarded clipboard of size %d (max: %d)",
+ clipboard_len, max_clipboard);
+ return FALSE;
+ } else if (clipboard_len <= 0) {
+ SPICE_DEBUG("discarding empty clipboard");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* This will convert line endings if needed (between Windows/Unix conventions),
+ * and will make sure 'len' does not take into account any trailing \0 as this could
+ * cause some confusion guest side.
+ * The 'len' argument will be modified by this function to the length of the modified
+ * string
+ */
+static char *fixup_clipboard_text(SpiceGtkSession *self, const char *text, int *len)
+{
+ char *conv = NULL;
+ int new_len = *len;
+
+ if (spice_main_agent_test_capability(self->priv->main, VD_AGENT_CAP_GUEST_LINEEND_CRLF)) {
+ conv = spice_unix2dos(text, *len);
+ new_len = strlen(conv);
+ } else {
+ /* On Windows, with some versions of gtk+, GtkSelectionData::length
+ * will include the final '\0'. When a string with this trailing '\0'
+ * is pasted in some linux applications, it will be pasted as <NIL> or
+ * as an invisible character, which is unwanted. Ensure the length we
+ * send to the agent does not include any trailing '\0'
+ * This is gtk+ bug https://bugzilla.gnome.org/show_bug.cgi?id=734670
+ */
+ new_len = strlen(text);
+ }
+
+ *len = new_len;
+ return conv;
+}
+
+static void clipboard_received_text_cb(GtkClipboard *clipboard,
+ const gchar *text,
+ gpointer user_data)
+{
+ WeakRef *weakref = user_data;
+ SpiceGtkSession *self = (SpiceGtkSession*)weakref->object;
+ char *conv = NULL;
+ int len = 0;
+ int selection;
+
+ weak_unref(weakref);
+
+ if (self == NULL)
+ return;
+
+ g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+
+ selection = get_selection_from_clipboard(self->priv, clipboard);
+ g_return_if_fail(selection != -1);
+
+ len = strlen(text);
+ if (!check_clipboard_size_limits(self, len)) {
+ return;
+ }
+
+ /* gtk+ internal utf8 newline is always LF, even on windows */
+ conv = fixup_clipboard_text(self, text, &len);
+ if (!check_clipboard_size_limits(self, len)) {
+ g_free(conv);
+ return;
+ }
+
+ spice_main_clipboard_selection_notify(self->priv->main, selection,
+ VD_AGENT_CLIPBOARD_UTF8_TEXT,
+ (guchar *)(conv ?: text), len);
+ g_free(conv);
+}
+
+static void clipboard_received_cb(GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer user_data)
+{
+ WeakRef *weakref = user_data;
+ SpiceGtkSession *self = (SpiceGtkSession*)weakref->object;
+ weak_unref(weakref);
+
+ if (self == NULL)
+ return;
+
+ g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+
+ SpiceGtkSessionPrivate *s = self->priv;
+ gint len = 0, m;
+ guint32 type = VD_AGENT_CLIPBOARD_NONE;
+ gchar* name;
+ GdkAtom atom;
+ int selection;
+
+ selection = get_selection_from_clipboard(s, clipboard);
+ g_return_if_fail(selection != -1);
+
+ len = gtk_selection_data_get_length(selection_data);
+ if (!check_clipboard_size_limits(self, len)) {
+ return;
+ } else {
+ atom = gtk_selection_data_get_data_type(selection_data);
+ name = gdk_atom_name(atom);
+ for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) {
+ if (strcasecmp(name, atom2agent[m].xatom) == 0) {
+ break;
+ }
+ }
+
+ if (m >= SPICE_N_ELEMENTS(atom2agent)) {
+ g_warning("clipboard_received for unsupported type: %s", name);
+ } else {
+ type = atom2agent[m].vdagent;
+ }
+
+ g_free(name);
+ }
+
+ const guchar *data = gtk_selection_data_get_data(selection_data);
+
+ /* text should be handled through clipboard_received_text_cb(), not
+ * clipboard_received_cb().
+ */
+ g_warn_if_fail(type != VD_AGENT_CLIPBOARD_UTF8_TEXT);
+
+ spice_main_clipboard_selection_notify(s->main, selection, type,
+ data, len);
+}
+
+static gboolean clipboard_request(SpiceMainChannel *main, guint selection,
+ guint type, gpointer user_data)
+{
+ g_return_val_if_fail(SPICE_IS_GTK_SESSION(user_data), FALSE);
+
+ SpiceGtkSession *self = user_data;
+ SpiceGtkSessionPrivate *s = self->priv;
+ GdkAtom atom;
+ GtkClipboard* cb;
+ int m;
+
+ g_return_val_if_fail(s->clipboard_by_guest[selection] == FALSE, FALSE);
+ g_return_val_if_fail(s->clip_grabbed[selection], FALSE);
+
+ if (read_only(self))
+ return FALSE;
+
+ cb = get_clipboard_from_selection(s, selection);
+ g_return_val_if_fail(cb != NULL, FALSE);
+
+ if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) {
+ gtk_clipboard_request_text(cb, clipboard_received_text_cb,
+ weak_ref(G_OBJECT(self)));
+ } else {
+ for (m = 0; m < SPICE_N_ELEMENTS(atom2agent); m++) {
+ if (atom2agent[m].vdagent == type)
+ break;
+ }
+
+ g_return_val_if_fail(m < SPICE_N_ELEMENTS(atom2agent), FALSE);
+
+ atom = gdk_atom_intern_static_string(atom2agent[m].xatom);
+ gtk_clipboard_request_contents(cb, atom, clipboard_received_cb,
+ weak_ref(G_OBJECT(self)));
+ }
+
+ return TRUE;
+}
+
+static void clipboard_release(SpiceMainChannel *main, guint selection,
+ gpointer user_data)
+{
+ g_return_if_fail(SPICE_IS_GTK_SESSION(user_data));
+
+ SpiceGtkSession *self = user_data;
+ SpiceGtkSessionPrivate *s = self->priv;
+ GtkClipboard* clipboard = get_clipboard_from_selection(s, selection);
+
+ if (!clipboard)
+ return;
+
+ s->nclip_targets[selection] = 0;
+
+ if (!s->clipboard_by_guest[selection])
+ return;
+ gtk_clipboard_clear(clipboard);
+ s->clipboard_by_guest[selection] = FALSE;
+}
+
+static void channel_new(SpiceSession *session, SpiceChannel *channel,
+ gpointer user_data)
+{
+ g_return_if_fail(SPICE_IS_GTK_SESSION(user_data));
+
+ SpiceGtkSession *self = user_data;
+ SpiceGtkSessionPrivate *s = self->priv;
+
+ if (SPICE_IS_MAIN_CHANNEL(channel)) {
+ SPICE_DEBUG("Changing main channel from %p to %p", s->main, channel);
+ s->main = SPICE_MAIN_CHANNEL(channel);
+ g_signal_connect(channel, "main-clipboard-selection-grab",
+ G_CALLBACK(clipboard_grab), self);
+ g_signal_connect(channel, "main-clipboard-selection-request",
+ G_CALLBACK(clipboard_request), self);
+ g_signal_connect(channel, "main-clipboard-selection-release",
+ G_CALLBACK(clipboard_release), self);
+ }
+ if (SPICE_IS_INPUTS_CHANNEL(channel)) {
+ spice_g_signal_connect_object(channel, "inputs-modifiers",
+ G_CALLBACK(guest_modifiers_changed), self, 0);
+ spice_gtk_session_sync_keyboard_modifiers_for_channel(self, SPICE_INPUTS_CHANNEL(channel), TRUE);
+ }
+}
+
+static void channel_destroy(SpiceSession *session, SpiceChannel *channel,
+ gpointer user_data)
+{
+ g_return_if_fail(SPICE_IS_GTK_SESSION(user_data));
+
+ SpiceGtkSession *self = user_data;
+ SpiceGtkSessionPrivate *s = self->priv;
+ guint i;
+
+ if (SPICE_IS_MAIN_CHANNEL(channel) && SPICE_MAIN_CHANNEL(channel) == s->main) {
+ s->main = NULL;
+ for (i = 0; i < CLIPBOARD_LAST; ++i) {
+ if (s->clipboard_by_guest[i]) {
+ GtkClipboard *cb = get_clipboard_from_selection(s, i);
+ if (cb)
+ gtk_clipboard_clear(cb);
+ s->clipboard_by_guest[i] = FALSE;
+ }
+ s->clip_grabbed[i] = FALSE;
+ s->nclip_targets[i] = 0;
+ }
+ }
+}
+
+static gboolean read_only(SpiceGtkSession *self)
+{
+ return spice_session_get_read_only(self->priv->session);
+}
+
+/* ---------------------------------------------------------------- */
+/* private functions (usbredir related) */
+G_GNUC_INTERNAL
+void spice_gtk_session_request_auto_usbredir(SpiceGtkSession *self,
+ gboolean state)
+{
+ g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+
+ SpiceGtkSessionPrivate *s = self->priv;
+ SpiceDesktopIntegration *desktop_int;
+ SpiceUsbDeviceManager *manager;
+
+ if (state) {
+ s->auto_usbredir_reqs++;
+ if (s->auto_usbredir_reqs != 1)
+ return;
+ } else {
+ g_return_if_fail(s->auto_usbredir_reqs > 0);
+ s->auto_usbredir_reqs--;
+ if (s->auto_usbredir_reqs != 0)
+ return;
+ }
+
+ if (!s->auto_usbredir_enable)
+ return;
+
+ manager = spice_usb_device_manager_get(s->session, NULL);
+ if (!manager)
+ return;
+
+ g_object_set(manager, "auto-connect", state, NULL);
+
+ desktop_int = spice_desktop_integration_get(s->session);
+ if (state)
+ spice_desktop_integration_inhibit_automount(desktop_int);
+ else
+ spice_desktop_integration_uninhibit_automount(desktop_int);
+}
+
+/* ------------------------------------------------------------------ */
+/* public functions */
+
+/**
+ * spice_gtk_session_get:
+ * @session: #SpiceSession for which to get the #SpiceGtkSession
+ *
+ * Gets the #SpiceGtkSession associated with the passed in #SpiceSession.
+ * A new #SpiceGtkSession instance will be created the first time this
+ * function is called for a certain #SpiceSession.
+ *
+ * Note that this function returns a weak reference, which should not be used
+ * after the #SpiceSession itself has been unref-ed by the caller.
+ *
+ * Returns: (transfer none): a weak reference to the #SpiceGtkSession associated with the passed in #SpiceSession
+ *
+ * Since 0.8
+ **/
+SpiceGtkSession *spice_gtk_session_get(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ SpiceGtkSession *self;
+ static GMutex mutex;
+
+ g_mutex_lock(&mutex);
+ self = g_object_get_data(G_OBJECT(session), "spice-gtk-session");
+ if (self == NULL) {
+ self = g_object_new(SPICE_TYPE_GTK_SESSION, "session", session, NULL);
+ g_object_set_data_full(G_OBJECT(session), "spice-gtk-session", self, g_object_unref);
+ }
+ g_mutex_unlock(&mutex);
+
+ return SPICE_GTK_SESSION(self);
+}
+
+/**
+ * spice_gtk_session_copy_to_guest:
+ * @self: #SpiceGtkSession
+ *
+ * Copy client-side clipboard to guest clipboard.
+ *
+ * Since 0.8
+ **/
+void spice_gtk_session_copy_to_guest(SpiceGtkSession *self)
+{
+ g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+ g_return_if_fail(read_only(self) == FALSE);
+
+ SpiceGtkSessionPrivate *s = self->priv;
+ int selection = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
+
+ if (s->clip_hasdata[selection] && !s->clip_grabbed[selection]) {
+ gtk_clipboard_request_targets(s->clipboard, clipboard_get_targets,
+ weak_ref(G_OBJECT(self)));
+ }
+}
+
+/**
+ * spice_gtk_session_paste_from_guest:
+ * @self: #SpiceGtkSession
+ *
+ * Copy guest clipboard to client-side clipboard.
+ *
+ * Since 0.8
+ **/
+void spice_gtk_session_paste_from_guest(SpiceGtkSession *self)
+{
+ g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+ g_return_if_fail(read_only(self) == FALSE);
+
+ SpiceGtkSessionPrivate *s = self->priv;
+ int selection = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
+
+ if (s->nclip_targets[selection] == 0) {
+ g_warning("Guest clipboard is not available.");
+ return;
+ }
+
+ if (!gtk_clipboard_set_with_owner(s->clipboard, s->clip_targets[selection], s->nclip_targets[selection],
+ clipboard_get, clipboard_clear, G_OBJECT(self))) {
+ g_warning("Clipboard grab failed");
+ return;
+ }
+ s->clipboard_by_guest[selection] = TRUE;
+ s->clip_hasdata[selection] = FALSE;
+}
+
+G_GNUC_INTERNAL
+void spice_gtk_session_sync_keyboard_modifiers(SpiceGtkSession *self)
+{
+ GList *l = NULL, *channels = spice_session_get_channels(self->priv->session);
+
+ for (l = channels; l != NULL; l = l->next) {
+ if (SPICE_IS_INPUTS_CHANNEL(l->data)) {
+ SpiceInputsChannel *inputs = SPICE_INPUTS_CHANNEL(l->data);
+ spice_gtk_session_sync_keyboard_modifiers_for_channel(self, inputs, TRUE);
+ }
+ }
+ g_list_free(channels);
+}
+
+G_GNUC_INTERNAL
+void spice_gtk_session_set_pointer_grabbed(SpiceGtkSession *self, gboolean grabbed)
+{
+ g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+
+ self->priv->pointer_grabbed = grabbed;
+ g_object_notify(G_OBJECT(self), "pointer-grabbed");
+}
+
+G_GNUC_INTERNAL
+gboolean spice_gtk_session_get_pointer_grabbed(SpiceGtkSession *self)
+{
+ g_return_val_if_fail(SPICE_IS_GTK_SESSION(self), FALSE);
+
+ return self->priv->pointer_grabbed;
+}
+
+G_GNUC_INTERNAL
+void spice_gtk_session_set_keyboard_has_focus(SpiceGtkSession *self,
+ gboolean keyboard_has_focus)
+{
+ g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+
+ self->priv->keyboard_has_focus = keyboard_has_focus;
+}
+
+G_GNUC_INTERNAL
+void spice_gtk_session_set_mouse_has_pointer(SpiceGtkSession *self,
+ gboolean mouse_has_pointer)
+{
+ g_return_if_fail(SPICE_IS_GTK_SESSION(self));
+ self->priv->mouse_has_pointer = mouse_has_pointer;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_gtk_session_get_keyboard_has_focus(SpiceGtkSession *self)
+{
+ g_return_val_if_fail(SPICE_IS_GTK_SESSION(self), FALSE);
+
+ return self->priv->keyboard_has_focus;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_gtk_session_get_mouse_has_pointer(SpiceGtkSession *self)
+{
+ g_return_val_if_fail(SPICE_IS_GTK_SESSION(self), FALSE);
+
+ return self->priv->mouse_has_pointer;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010-2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_GTK_SESSION_H__
+#define __SPICE_CLIENT_GTK_SESSION_H__
+
+#if !defined(__SPICE_CLIENT_GTK_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client-gtk.h> can be included directly"
+#endif
+
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_GTK_SESSION (spice_gtk_session_get_type ())
+#define SPICE_GTK_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_GTK_SESSION, SpiceGtkSession))
+#define SPICE_GTK_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_GTK_SESSION, SpiceGtkSessionClass))
+#define SPICE_IS_GTK_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_GTK_SESSION))
+#define SPICE_IS_GTK_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_GTK_SESSION))
+#define SPICE_GTK_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_GTK_SESSION, SpiceGtkSessionClass))
+
+typedef struct _SpiceGtkSession SpiceGtkSession;
+typedef struct _SpiceGtkSessionClass SpiceGtkSessionClass;
+
+GType spice_gtk_session_get_type(void);
+
+SpiceGtkSession *spice_gtk_session_get(SpiceSession *session);
+void spice_gtk_session_copy_to_guest(SpiceGtkSession *self);
+void spice_gtk_session_paste_from_guest(SpiceGtkSession *self);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_GTK_SESSION_H__ */
--- /dev/null
+spice_display_get_grab_keys
+spice_display_get_pixbuf
+spice_display_get_type
+spice_display_key_event_get_type
+spice_display_mouse_ungrab
+spice_display_new
+spice_display_new_with_monitor
+spice_display_send_keys
+spice_display_set_grab_keys
+spice_grab_sequence_as_string
+spice_grab_sequence_copy
+spice_grab_sequence_free
+spice_grab_sequence_get_type
+spice_grab_sequence_new
+spice_grab_sequence_new_from_string
+spice_gtk_session_copy_to_guest
+spice_gtk_session_get
+spice_gtk_session_get_type
+spice_gtk_session_paste_from_guest
+spice_usb_device_widget_get_type
+spice_usb_device_widget_new
--- /dev/null
+VOID:INT,INT
+VOID:INT,INT,INT
+VOID:INT,INT,INT,INT
+VOID:UINT,UINT,UINT,UINT
+VOID:INT,INT,INT,INT,POINTER
+VOID:INT,INT,INT,INT,INT,POINTER
+VOID:POINTER,INT
+BOOLEAN:POINTER,UINT
+BOOLEAN:UINT
+VOID:UINT,POINTER,UINT
+VOID:UINT,UINT,POINTER,UINT
+BOOLEAN:UINT,POINTER,UINT
+BOOLEAN:UINT,UINT
+VOID:OBJECT,OBJECT
+VOID:BOXED,BOXED
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <stdlib.h>
+#include <glib-object.h>
+#include <glib/gi18n-lib.h>
+#include "spice-session.h"
+#include "spice-util.h"
+#include "spice-channel-priv.h"
+#include "usb-device-manager.h"
+
+static GStrv disable_effects = NULL;
+static gint color_depth = 0;
+static char *ca_file = NULL;
+static char *host_subject = NULL;
+static char *smartcard_db = NULL;
+static char *smartcard_certificates = NULL;
+static char *usbredir_auto_redirect_filter = NULL;
+static char *usbredir_redirect_on_connect = NULL;
+static gboolean smartcard = FALSE;
+static gboolean disable_audio = FALSE;
+static gboolean disable_usbredir = FALSE;
+static gint cache_size = 0;
+static gint glz_window_size = 0;
+static gchar *secure_channels = NULL;
+static gchar *shared_dir = NULL;
+static SpiceImageCompression preferred_compression = SPICE_IMAGE_COMPRESSION_INVALID;
+
+G_GNUC_NORETURN
+static void option_version(void)
+{
+ g_print(PACKAGE_STRING "\n");
+ exit(0);
+}
+
+static gboolean option_debug(void)
+{
+ spice_util_set_debug(TRUE);
+ return TRUE;
+}
+
+static gboolean parse_color_depth(const gchar *option_name, const gchar *value,
+ gpointer data, GError **error)
+{
+ unsigned long parsed_depth;
+ char *end;
+
+ if (option_name == NULL) {
+ g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED, _("missing color depth, must be 16 or 32"));
+ return FALSE;
+ }
+
+ parsed_depth = strtoul(value, &end, 0);
+ if (*end != '\0')
+ goto error;
+
+ if ((parsed_depth != 16) && (parsed_depth != 32))
+ goto error;
+
+ color_depth = parsed_depth;
+
+ return TRUE;
+
+error:
+ g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED, _("invalid color depth (%s), must be 16 or 32"), value);
+ return FALSE;
+}
+
+static gboolean parse_disable_effects(const gchar *option_name, const gchar *value,
+ gpointer data, GError **error)
+{
+ GStrv it;
+
+ disable_effects = g_strsplit(value, ",", -1);
+ for (it = disable_effects; *it != NULL; it++) {
+ if ((g_strcmp0(*it, "wallpaper") != 0)
+ && (g_strcmp0(*it, "font-smooth") != 0)
+ && (g_strcmp0(*it, "animation") != 0)
+ && (g_strcmp0(*it, "all") != 0)) {
+ /* Translators: do not translate 'wallpaper', 'font-smooth',
+ * 'animation', 'all' as the user must use these values with the
+ * --spice-disable-effects command line option
+ */
+ g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
+ _("invalid effect name (%s), must be 'wallpaper', 'font-smooth', 'animation' or 'all'"), *it);
+ g_clear_pointer(&disable_effects, g_strfreev);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean parse_secure_channels(const gchar *option_name, const gchar *value,
+ gpointer data, GError **error)
+{
+ gint i;
+ gchar **channels = g_strsplit(value, ",", -1);
+
+ g_return_val_if_fail(channels != NULL, FALSE);
+
+ for (i = 0; channels[i]; i++) {
+ if (g_strcmp0(channels[i], "all") == 0)
+ continue;
+
+ if (spice_channel_string_to_type(channels[i]) == -1) {
+ gchar *supported = spice_channel_supported_string();
+ g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
+ _("invalid channel name (%s), valid names: all, %s"),
+ channels[i], supported);
+ g_free(supported);
+ return FALSE;
+ }
+ }
+
+ g_strfreev(channels);
+
+ secure_channels = g_strdup(value);
+
+ return TRUE;
+}
+
+
+static gboolean parse_usbredir_filter(const gchar *option_name,
+ const gchar *value,
+ gpointer data, GError **error)
+
+{
+ g_warning("--spice-usbredir-filter is deprecated, please use --spice-usbredir-auto-redirect-filter instead");
+ g_free(usbredir_auto_redirect_filter);
+ usbredir_auto_redirect_filter = g_strdup(value);
+ return TRUE;
+}
+
+static gboolean parse_preferred_compression(const gchar *option_name, const gchar *value,
+ gpointer data, GError **error)
+{
+ if (!strcmp(value, "auto-glz")) {
+ preferred_compression = SPICE_IMAGE_COMPRESSION_AUTO_GLZ;
+ } else if (!strcmp(value, "auto-lz")) {
+ preferred_compression = SPICE_IMAGE_COMPRESSION_AUTO_LZ;
+ } else if (!strcmp(value, "quic")) {
+ preferred_compression = SPICE_IMAGE_COMPRESSION_QUIC;
+ } else if (!strcmp(value, "glz")) {
+ preferred_compression = SPICE_IMAGE_COMPRESSION_GLZ;
+ } else if (!strcmp(value, "lz")) {
+ preferred_compression = SPICE_IMAGE_COMPRESSION_LZ;
+#ifdef USE_LZ4
+ } else if (!strcmp(value, "lz4")) {
+ preferred_compression = SPICE_IMAGE_COMPRESSION_LZ4;
+#endif
+ } else if (!strcmp(value, "off")) {
+ preferred_compression = SPICE_IMAGE_COMPRESSION_OFF;
+ } else {
+ preferred_compression = SPICE_IMAGE_COMPRESSION_INVALID;
+ g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
+ _("Image compression algorithm %s not supported"), value);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * spice_get_option_group:
+ *
+ * Gets commandline options.
+ *
+ * Bindings for other languages are available since 0.32
+ *
+ * Returns: (transfer full): a #GOptionGroup for the commandline
+ * arguments specific to Spice. You have to call
+ * spice_set_session_option() after to set the options on a
+ * #SpiceSession.
+ **/
+GOptionGroup* spice_get_option_group(void)
+{
+ const GOptionEntry entries[] = {
+ { "spice-secure-channels", '\0', 0, G_OPTION_ARG_CALLBACK, parse_secure_channels,
+ N_("Force the specified channels to be secured"), "<main,display,inputs,...,all>" },
+ { "spice-disable-effects", '\0', 0, G_OPTION_ARG_CALLBACK, parse_disable_effects,
+ N_("Disable guest display effects"), "<wallpaper,font-smooth,animation,all>" },
+ { "spice-color-depth", '\0', 0, G_OPTION_ARG_CALLBACK, parse_color_depth,
+ N_("Guest display color depth"), "<16,32>" },
+ { "spice-ca-file", '\0', 0, G_OPTION_ARG_FILENAME, &ca_file,
+ N_("Truststore file for secure connections"), N_("<file>") },
+ { "spice-host-subject", '\0', 0, G_OPTION_ARG_STRING, &host_subject,
+ N_("Subject of the host certificate (field=value pairs separated by commas)"), N_("<host-subject>") },
+ { "spice-disable-audio", '\0', 0, G_OPTION_ARG_NONE, &disable_audio,
+ N_("Disable audio support"), NULL },
+ { "spice-smartcard", '\0', 0, G_OPTION_ARG_NONE, &smartcard,
+ N_("Enable smartcard support"), NULL },
+ { "spice-smartcard-certificates", '\0', 0, G_OPTION_ARG_STRING, &smartcard_certificates,
+ N_("Certificates to use for software smartcards (field=values separated by commas)"), N_("<certificates>") },
+ { "spice-smartcard-db", '\0', 0, G_OPTION_ARG_STRING, &smartcard_db,
+ N_("Path to the local certificate database to use for software smartcard certificates"), N_("<certificate-db>") },
+ { "spice-disable-usbredir", '\0', 0, G_OPTION_ARG_NONE, &disable_usbredir,
+ N_("Disable USB redirection support"), NULL },
+ /* Backward compats version of spice-usbredir-auto-redirect-filter */
+ { "spice-usbredir-filter", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK, parse_usbredir_filter,
+ NULL, NULL },
+ { "spice-usbredir-auto-redirect-filter", '\0', 0, G_OPTION_ARG_STRING, &usbredir_auto_redirect_filter,
+ N_("Filter selecting USB devices to be auto-redirected when plugged in"), N_("<filter-string>") },
+ { "spice-usbredir-redirect-on-connect", '\0', 0, G_OPTION_ARG_STRING, &usbredir_redirect_on_connect,
+ N_("Filter selecting USB devices to redirect on connect"), N_("<filter-string>") },
+ { "spice-cache-size", '\0', 0, G_OPTION_ARG_INT, &cache_size,
+ N_("Image cache size"), N_("<bytes>") },
+ { "spice-glz-window-size", '\0', 0, G_OPTION_ARG_INT, &glz_window_size,
+ N_("Glz compression history size"), N_("<bytes>") },
+ { "spice-shared-dir", '\0', 0, G_OPTION_ARG_FILENAME, &shared_dir,
+ N_("Shared directory"), N_("<dir>") },
+ { "spice-preferred-compression", '\0', 0, G_OPTION_ARG_CALLBACK, parse_preferred_compression,
+ N_("Preferred image compression algorithm"),
+#ifdef USE_LZ4
+ "<auto-glz,auto-lz,quic,glz,lz,lz4,off>" },
+#else
+ "<auto-glz,auto-lz,quic,glz,lz,off>" },
+#endif
+
+ { "spice-debug", '\0', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, option_debug,
+ N_("Enable Spice-GTK debugging"), NULL },
+ { "spice-gtk-version", '\0', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, option_version,
+ N_("Display Spice-GTK version information"), NULL },
+ { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
+ };
+ GOptionGroup *grp;
+
+ grp = g_option_group_new("spice", _("Spice Options:"), _("Show Spice Options"), NULL, NULL);
+ g_option_group_add_entries(grp, entries);
+
+ return grp;
+}
+
+/**
+ * spice_set_session_option:
+ * @session: a #SpiceSession to set option upon
+ *
+ * Set various properties on @session, according to the commandline
+ * arguments given to spice_get_option_group() option group.
+ **/
+void spice_set_session_option(SpiceSession *session)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ if (ca_file == NULL) {
+ const char *homedir = g_getenv("HOME");
+ if (!homedir)
+ homedir = g_get_home_dir();
+ ca_file = g_build_filename(homedir, ".spicec", "spice_truststore.pem", NULL);
+ if (!g_file_test(ca_file, G_FILE_TEST_IS_REGULAR))
+ g_clear_pointer(&ca_file, g_free);
+ }
+
+ if (disable_effects) {
+ g_object_set(session, "disable-effects", disable_effects, NULL);
+ }
+
+ if (secure_channels) {
+ GStrv channels;
+ channels = g_strsplit(secure_channels, ",", -1);
+ if (channels)
+ g_object_set(session, "secure-channels", channels, NULL);
+ g_strfreev(channels);
+ }
+
+ if (color_depth)
+ g_object_set(session, "color-depth", color_depth, NULL);
+ if (ca_file)
+ g_object_set(session, "ca-file", ca_file, NULL);
+ if (host_subject)
+ g_object_set(session, "cert-subject", host_subject, NULL);
+ if (smartcard) {
+ g_object_set(session, "enable-smartcard", smartcard, NULL);
+ if (smartcard_certificates) {
+ GStrv certs_strv;
+ certs_strv = g_strsplit(smartcard_certificates, ",", -1);
+ if (certs_strv)
+ g_object_set(session, "smartcard-certificates", certs_strv, NULL);
+ g_strfreev(certs_strv);
+ }
+ if (smartcard_db)
+ g_object_set(session, "smartcard-db", smartcard_db, NULL);
+ }
+ if (usbredir_auto_redirect_filter) {
+ SpiceUsbDeviceManager *m = spice_usb_device_manager_get(session, NULL);
+ if (m)
+ g_object_set(m, "auto-connect-filter",
+ usbredir_auto_redirect_filter, NULL);
+ }
+ if (usbredir_redirect_on_connect) {
+ SpiceUsbDeviceManager *m = spice_usb_device_manager_get(session, NULL);
+ if (m)
+ g_object_set(m, "redirect-on-connect",
+ usbredir_redirect_on_connect, NULL);
+ }
+ if (disable_usbredir)
+ g_object_set(session, "enable-usbredir", FALSE, NULL);
+ if (disable_audio)
+ g_object_set(session, "enable-audio", FALSE, NULL);
+ if (cache_size)
+ g_object_set(session, "cache-size", cache_size, NULL);
+ if (glz_window_size)
+ g_object_set(session, "glz-window-size", glz_window_size, NULL);
+ if (shared_dir)
+ g_object_set(session, "shared-dir", shared_dir, NULL);
+ if (preferred_compression != SPICE_IMAGE_COMPRESSION_INVALID)
+ g_object_set(session, "preferred-compression", preferred_compression, NULL);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef SPICE_OPTION_H
+#define SPICE_OPTION_H
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include <glib.h>
+#include "spice-session.h"
+
+G_BEGIN_DECLS
+
+GOptionGroup* spice_get_option_group(void);
+void spice_set_session_option(SpiceSession *session);
+
+G_END_DECLS
+
+#endif /* SPICE_OPTION_H */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-pulse.h"
+#include "spice-common.h"
+#include "spice-session-priv.h"
+#include "spice-channel-priv.h"
+#include "spice-util-priv.h"
+
+#include <pulse/glib-mainloop.h>
+#include <pulse/pulseaudio.h>
+#include <pulse/ext-stream-restore.h>
+
+#define SPICE_PULSE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_PULSE, SpicePulsePrivate))
+
+struct async_task {
+ SpicePulse *pulse;
+ SpiceMainChannel *main_channel;
+ GTask *gtask;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+ gboolean is_playback;
+ pa_operation *pa_op;
+ gulong cancel_id;
+};
+
+struct stream {
+ pa_sample_spec spec;
+ pa_stream *stream;
+ int state;
+ pa_operation *uncork_op;
+ pa_operation *cork_op;
+ gboolean started;
+ guint num_underflow;
+ gboolean info_updated;
+ gchar *name;
+ pa_ext_stream_restore_info info;
+};
+
+struct _SpicePulsePrivate {
+ SpiceChannel *pchannel;
+ SpiceChannel *rchannel;
+
+ pa_glib_mainloop *mainloop;
+ pa_context *context;
+ int state;
+ struct stream playback;
+ struct stream record;
+ guint last_delay;
+ guint target_delay;
+ struct async_task *pending_restore_task;
+ GList *results;
+};
+
+G_DEFINE_TYPE(SpicePulse, spice_pulse, SPICE_TYPE_AUDIO)
+
+static const char *stream_state_names[] = {
+ [ PA_STREAM_UNCONNECTED ] = "unconnected",
+ [ PA_STREAM_CREATING ] = "creating",
+ [ PA_STREAM_READY ] = "ready",
+ [ PA_STREAM_FAILED ] = "failed",
+ [ PA_STREAM_TERMINATED ] = "terminated",
+};
+
+static const char *context_state_names[] = {
+ [ PA_CONTEXT_UNCONNECTED ] = "unconnected",
+ [ PA_CONTEXT_CONNECTING ] = "connecting",
+ [ PA_CONTEXT_AUTHORIZING ] = "authorizing",
+ [ PA_CONTEXT_SETTING_NAME ] = "setting_name",
+ [ PA_CONTEXT_READY ] = "ready",
+ [ PA_CONTEXT_FAILED ] = "failed",
+ [ PA_CONTEXT_TERMINATED ] = "terminated",
+};
+#define STATE_NAME(array, state) \
+ ((state < G_N_ELEMENTS(array)) ? array[state] : NULL)
+
+static void stream_stop(SpicePulse *pulse, struct stream *s);
+static gboolean connect_channel(SpiceAudio *audio, SpiceChannel *channel);
+static void channel_weak_notified(gpointer data, GObject *where_the_object_was);
+static void spice_pulse_get_playback_volume_info_async(SpiceAudio *audio, GCancellable *cancellable,
+ SpiceMainChannel *main_channel, GAsyncReadyCallback callback, gpointer user_data);
+static gboolean spice_pulse_get_playback_volume_info_finish(SpiceAudio *audio, GAsyncResult *res,
+ gboolean *mute, guint8 *nchannels, guint16 **volume, GError **error);
+static void spice_pulse_get_record_volume_info_async(SpiceAudio *audio, GCancellable *cancellable,
+ SpiceMainChannel *main_channel, GAsyncReadyCallback callback, gpointer user_data);
+static gboolean spice_pulse_get_record_volume_info_finish(SpiceAudio *audio,GAsyncResult *res,
+ gboolean *mute, guint8 *nchannels, guint16 **volume, GError **error);
+static void stream_restore_read_cb(pa_context *context,
+ const pa_ext_stream_restore_info *info, int eol, void *userdata);
+static void spice_pulse_complete_async_task(struct async_task *task, const gchar *err_msg);
+static void spice_pulse_complete_all_async_tasks(SpicePulse *pulse, const gchar *err_msg);
+
+static void spice_pulse_finalize(GObject *obj)
+{
+ SpicePulse *pulse = SPICE_PULSE(obj);
+ SpicePulsePrivate *p;
+
+ p = pulse->priv;
+
+ if (p->context != NULL)
+ pa_context_unref(p->context);
+
+ if (p->mainloop != NULL)
+ pa_glib_mainloop_free(p->mainloop);
+
+ G_OBJECT_CLASS(spice_pulse_parent_class)->finalize(obj);
+}
+
+static void spice_pulse_dispose(GObject *obj)
+{
+ SpicePulse *pulse = SPICE_PULSE(obj);
+ SpicePulsePrivate *p;
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+ p = pulse->priv;
+
+ g_clear_pointer(&p->playback.uncork_op, pa_operation_unref);
+ g_clear_pointer(&p->playback.cork_op, pa_operation_unref);
+ g_clear_pointer(&p->record.uncork_op, pa_operation_unref);
+ g_clear_pointer(&p->record.cork_op, pa_operation_unref);
+
+ if (p->results != NULL)
+ spice_pulse_complete_all_async_tasks(pulse, "PulseAudio is being dispose");
+
+ g_clear_pointer(&p->playback.name, g_free);
+ g_clear_pointer(&p->record.name, g_free);
+
+ if (p->pchannel)
+ g_object_weak_unref(G_OBJECT(p->pchannel), channel_weak_notified, pulse);
+ p->pchannel = NULL;
+
+ if (p->rchannel)
+ g_object_weak_unref(G_OBJECT(p->rchannel), channel_weak_notified, pulse);
+ p->rchannel = NULL;
+
+ G_OBJECT_CLASS(spice_pulse_parent_class)->dispose(obj);
+}
+
+static void spice_pulse_init(SpicePulse *pulse)
+{
+ pulse->priv = SPICE_PULSE_GET_PRIVATE(pulse);
+}
+
+static void spice_pulse_class_init(SpicePulseClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ SpiceAudioClass *audio_class = SPICE_AUDIO_CLASS(klass);
+
+ audio_class->connect_channel = connect_channel;
+ audio_class->get_playback_volume_info_async = spice_pulse_get_playback_volume_info_async;
+ audio_class->get_playback_volume_info_finish = spice_pulse_get_playback_volume_info_finish;
+ audio_class->get_record_volume_info_async = spice_pulse_get_record_volume_info_async;
+ audio_class->get_record_volume_info_finish = spice_pulse_get_record_volume_info_finish;
+
+ gobject_class->finalize = spice_pulse_finalize;
+ gobject_class->dispose = spice_pulse_dispose;
+
+ g_type_class_add_private(klass, sizeof(SpicePulsePrivate));
+}
+
+/* ------------------------------------------------------------------ */
+static void pulse_uncork_cb(pa_stream *pastream, int success, void *data)
+{
+ struct stream *s = data;
+
+ if (!success)
+ g_warning("pulseaudio uncork operation failed");
+
+ g_clear_pointer(&s->uncork_op, pa_operation_unref);
+}
+
+static void stream_uncork(SpicePulse *pulse, struct stream *s)
+{
+ SpicePulsePrivate *p = pulse->priv;
+ pa_operation *o = NULL;
+
+ g_return_if_fail(s->stream);
+
+ if (s->cork_op) {
+ pa_operation_cancel(s->cork_op);
+ g_clear_pointer(&s->cork_op, pa_operation_unref);
+ }
+
+ if (pa_stream_is_corked(s->stream) && !s->uncork_op) {
+ if (!(o = pa_stream_cork(s->stream, 0, pulse_uncork_cb, s))) {
+ g_warning("pa_stream_uncork() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ }
+ s->uncork_op = o;
+ }
+}
+
+static void pulse_flush_cb(pa_stream *pastream, int success, void *data)
+{
+ struct stream *s = data;
+
+ if (!success)
+ g_warning("pulseaudio flush operation failed");
+
+ g_clear_pointer(&s->cork_op, pa_operation_unref);
+}
+
+static void pulse_cork_flush_cb(pa_stream *pastream, int success, void *data)
+{
+ struct stream *s = data;
+
+ if (!success)
+ g_warning("pulseaudio cork operation failed");
+
+ pa_operation_unref(s->cork_op);
+
+ if (!(s->cork_op = pa_stream_flush(s->stream, pulse_flush_cb, s))) {
+ g_warning("pa_stream_flush() failed");
+ }
+}
+
+static void pulse_cork_cb(pa_stream *pastream, int success, void *data)
+{
+ struct stream *s = data;
+
+ SPICE_DEBUG("%s: cork started", __FUNCTION__);
+ if (!success)
+ g_warning("pulseaudio cork operation failed");
+
+ g_clear_pointer(&s->cork_op, pa_operation_unref);
+}
+
+static void stream_cork(SpicePulse *pulse, struct stream *s, gboolean with_flush)
+{
+ SpicePulsePrivate *p = pulse->priv;
+ pa_operation *o = NULL;
+
+ if (s->uncork_op) {
+ pa_operation_cancel(s->uncork_op);
+ g_clear_pointer(&s->uncork_op, pa_operation_unref);
+ }
+
+ if (!pa_stream_is_corked(s->stream) && !s->cork_op) {
+ if (!(o = pa_stream_cork(s->stream, 1,
+ with_flush ? pulse_cork_flush_cb :
+ pulse_cork_cb,
+ s))) {
+ g_warning("pa_stream_cork() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ }
+ s->cork_op = o;
+ }
+}
+
+static void stream_stop(SpicePulse *pulse, struct stream *s)
+{
+ SpicePulsePrivate *p = pulse->priv;
+
+ if (pa_stream_disconnect(s->stream) < 0) {
+ g_warning("pa_stream_disconnect() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ }
+ g_clear_pointer(&s->stream, pa_stream_unref);
+}
+
+static void stream_state_callback(pa_stream *s, void *userdata)
+{
+ SpicePulse *pulse = userdata;
+ SpicePulsePrivate *p;
+
+ p = pulse->priv;
+
+ g_return_if_fail(p != NULL);
+ g_return_if_fail(s != NULL);
+
+ switch (pa_stream_get_state(s)) {
+ case PA_STREAM_CREATING:
+ case PA_STREAM_TERMINATED:
+ case PA_STREAM_READY:
+ break;
+ case PA_STREAM_FAILED:
+ default:
+ g_warning("Stream error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(s))));
+ }
+}
+
+static void stream_underflow_cb(pa_stream *s, void *userdata)
+{
+ SpicePulse *pulse = userdata;
+ SpicePulsePrivate *p;
+
+ SPICE_DEBUG("PA stream underflow!!");
+
+ p = pulse->priv;
+ g_return_if_fail(p != NULL);
+ p->playback.num_underflow++;
+#ifdef PULSE_ADJUST_LATENCY
+ const pa_buffer_attr *buffer_attr;
+ pa_buffer_attr new_buffer_attr;
+ pa_operation *op;
+
+ buffer_attr = pa_stream_get_buffer_attr(s);
+ g_return_if_fail(buffer_attr != NULL);
+
+ new_buffer_attr = *buffer_attr;
+ new_buffer_attr.tlength *= 2;
+ new_buffer_attr.minreq *= 2;
+ op = pa_stream_set_buffer_attr(s, &new_buffer_attr, NULL, NULL);
+ pa_operation_unref(op);
+#endif
+}
+
+static void stream_update_latency_callback(pa_stream *s, void *userdata)
+{
+ SpicePulse *pulse = userdata;
+ pa_usec_t usec;
+ int negative = 0;
+ SpicePulsePrivate *p;
+
+ p = pulse->priv;
+
+ g_return_if_fail(s != NULL);
+ g_return_if_fail(p != NULL);
+
+ if (!p->playback.stream || !p->playback.started)
+ return;
+
+ if (pa_stream_get_latency(s, &usec, &negative) < 0) {
+ g_warning("Failed to get latency: %s", pa_strerror(pa_context_errno(p->context)));
+ return;
+ }
+
+ g_return_if_fail(negative == FALSE);
+ p->last_delay = usec / PA_USEC_PER_MSEC;
+ spice_playback_channel_set_delay(SPICE_PLAYBACK_CHANNEL(p->pchannel), usec / 1000);
+ if (pa_stream_is_corked(p->playback.stream)) {
+ if (p->last_delay >= p->target_delay) {
+ SPICE_DEBUG("%s: uncork playback. delay %u target %u", __FUNCTION__, p->last_delay, p->target_delay);
+ stream_uncork(pulse, &p->playback);
+ } else {
+ SPICE_DEBUG("%s: still corked. delay %u target %u", __FUNCTION__, p->last_delay, p->target_delay);
+ }
+ }
+}
+
+static void create_playback(SpicePulse *pulse)
+{
+ SpicePulsePrivate *p = pulse->priv;
+ pa_stream_flags_t flags;
+ pa_buffer_attr buffer_attr = { 0, };
+
+ g_return_if_fail(p != NULL);
+ g_return_if_fail(p->context != NULL);
+ g_return_if_fail(p->playback.stream == NULL);
+ g_return_if_fail(pa_context_get_state(p->context) == PA_CONTEXT_READY);
+
+ p->playback.state = PA_STREAM_READY;
+ p->playback.stream = pa_stream_new(p->context, "playback",
+ &p->playback.spec, NULL);
+ pa_stream_set_state_callback(p->playback.stream, stream_state_callback, pulse);
+ pa_stream_set_underflow_callback(p->playback.stream, stream_underflow_cb, pulse);
+ pa_stream_set_latency_update_callback(p->playback.stream, stream_update_latency_callback, pulse);
+
+ buffer_attr.maxlength = -1;
+ buffer_attr.tlength = pa_usec_to_bytes(p->target_delay * PA_USEC_PER_MSEC, &p->playback.spec);
+ buffer_attr.prebuf = -1;
+ buffer_attr.minreq = -1;
+ flags = PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE;
+
+ if (pa_stream_connect_playback(p->playback.stream,
+ NULL, &buffer_attr, flags, NULL, NULL) < 0) {
+ g_warning("pa_stream_connect_playback() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ }
+}
+
+static void playback_start(SpicePlaybackChannel *channel, gint format, gint channels,
+ gint frequency, gpointer data)
+{
+ SpicePulse *pulse = data;
+ SpicePulsePrivate *p = pulse->priv;
+ pa_context_state_t state;
+ guint latency;
+
+ g_return_if_fail(p != NULL);
+
+ p->playback.started = TRUE;
+ p->playback.num_underflow = 0;
+ g_object_get(p->pchannel, "min-latency", &latency, NULL);
+
+ if (p->playback.stream &&
+ (p->playback.spec.rate != frequency ||
+ p->playback.spec.channels != channels ||
+ p->target_delay != latency)) {
+ stream_stop(pulse, &p->playback);
+ }
+
+ g_return_if_fail(format == SPICE_AUDIO_FMT_S16);
+ p->playback.spec.format = PA_SAMPLE_S16LE;
+ p->playback.spec.rate = frequency;
+ p->playback.spec.channels = channels;
+ p->target_delay = latency;
+ p->last_delay = 0;
+
+ state = pa_context_get_state(p->context);
+ switch (state) {
+ case PA_CONTEXT_READY:
+ if (p->state != state) {
+ SPICE_DEBUG("%s: pulse context ready", __FUNCTION__);
+ }
+ if (p->playback.stream == NULL) {
+ create_playback(pulse);
+ } else
+ stream_uncork(pulse, &p->playback);
+ break;
+ default:
+ if (p->state != state) {
+ SPICE_DEBUG("%s: pulse context not ready (%s)",
+ __FUNCTION__, STATE_NAME(context_state_names, state));
+ }
+ break;
+ }
+ p->state = state;
+}
+
+static void playback_data(SpicePlaybackChannel *channel,
+ gpointer *audio, gint size,
+ gpointer data)
+{
+ SpicePulse *pulse = data;
+ SpicePulsePrivate *p = pulse->priv;
+ pa_stream_state_t state;
+
+ if (!p->playback.stream)
+ return;
+
+ state = pa_stream_get_state(p->playback.stream);
+ switch (state) {
+ case PA_STREAM_CREATING:
+ SPICE_DEBUG("stream creating, dropping data");
+ break;
+ case PA_STREAM_READY:
+ if (p->playback.state != state) {
+ SPICE_DEBUG("%s: pulse playback stream ready", __FUNCTION__);
+ }
+ if (pa_stream_write(p->playback.stream, audio, size, NULL, 0, PA_SEEK_RELATIVE) < 0) {
+ g_warning("pa_stream_write() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ }
+ break;
+ default:
+ if (p->playback.state != state) {
+ SPICE_DEBUG("%s: pulse playback stream not ready (%s)",
+ __FUNCTION__, STATE_NAME(stream_state_names, state));
+ }
+ break;
+ }
+ p->playback.state = state;
+}
+
+static void playback_stop(SpicePulse *pulse)
+{
+ SpicePulsePrivate *p = pulse->priv;
+
+ SPICE_DEBUG("%s: #underflow %u", __FUNCTION__, p->playback.num_underflow);
+
+ p->playback.started = FALSE;
+ if (!p->playback.stream)
+ return;
+
+ stream_cork(pulse, &p->playback, TRUE);
+}
+
+static void stream_read_callback(pa_stream *s, size_t length, void *data)
+{
+ SpicePulse *pulse = data;
+ SpicePulsePrivate *p = pulse->priv;
+
+ g_return_if_fail(p != NULL);
+
+ while (pa_stream_readable_size(s) > 0) {
+ const void *snddata;
+
+ if (pa_stream_peek(s, &snddata, &length) < 0) {
+ g_warning("pa_stream_peek() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ return;
+ }
+
+ g_return_if_fail(snddata);
+ g_return_if_fail(length > 0);
+
+ if (p->rchannel != NULL)
+ spice_record_send_data(SPICE_RECORD_CHANNEL(p->rchannel),
+ /* FIXME: server side doesn't care about ts?
+ what is the unit? ms apparently */
+ (gpointer)snddata, length, 0);
+
+ if (pa_stream_drop(s) < 0) {
+ g_warning("pa_stream_drop() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ return;
+ }
+ }
+}
+
+static void create_record(SpicePulse *pulse)
+{
+ SpicePulsePrivate *p = pulse->priv;
+ pa_buffer_attr buffer_attr = { 0, };
+ pa_stream_flags_t flags;
+
+ g_return_if_fail(p != NULL);
+ g_return_if_fail(p->context != NULL);
+ g_return_if_fail(p->record.stream == NULL);
+ g_return_if_fail(pa_context_get_state(p->context) == PA_CONTEXT_READY);
+
+ p->record.state = PA_STREAM_READY;
+ p->record.stream = pa_stream_new(p->context, "record",
+ &p->record.spec, NULL);
+ pa_stream_set_read_callback(p->record.stream, stream_read_callback, pulse);
+ pa_stream_set_state_callback(p->record.stream, stream_state_callback, pulse);
+
+ /* FIXME: we might want customizable latency */
+ buffer_attr.maxlength = -1;
+ buffer_attr.prebuf = -1;
+ buffer_attr.fragsize = buffer_attr.tlength = pa_usec_to_bytes(20 * PA_USEC_PER_MSEC, &p->record.spec);
+ buffer_attr.minreq = (uint32_t) -1;
+ flags = PA_STREAM_ADJUST_LATENCY;
+
+ if (pa_stream_connect_record(p->record.stream, NULL, &buffer_attr, flags) < 0) {
+ g_warning("pa_stream_connect_record() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ }
+}
+
+static void record_start(SpiceRecordChannel *channel, gint format, gint channels,
+ gint frequency, gpointer data)
+{
+ SpicePulse *pulse = data;
+ SpicePulsePrivate *p = pulse->priv;
+ pa_context_state_t state;
+
+ p->record.started = TRUE;
+
+ if (p->record.stream &&
+ (p->record.spec.rate != frequency ||
+ p->record.spec.channels != channels)) {
+ stream_stop(pulse, &p->record);
+ }
+
+ g_return_if_fail(format == SPICE_AUDIO_FMT_S16);
+ p->record.spec.format = PA_SAMPLE_S16LE;
+ p->record.spec.rate = frequency;
+ p->record.spec.channels = channels;
+
+ state = pa_context_get_state(p->context);
+ switch (state) {
+ case PA_CONTEXT_READY:
+ if (p->state != state) {
+ SPICE_DEBUG("%s: pulse context ready", __FUNCTION__);
+ }
+ if (p->record.stream == NULL) {
+ create_record(pulse);
+ } else
+ stream_uncork(pulse, &p->record);
+ break;
+ default:
+ if (p->state != state) {
+ g_warning("%s: pulse context not ready (%s)",
+ __FUNCTION__, STATE_NAME(context_state_names, state));
+ }
+ break;
+ }
+ p->state = state;
+}
+
+static void record_stop(SpicePulse *pulse)
+{
+ SpicePulsePrivate *p = pulse->priv;
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+
+ p->record.started = FALSE;
+ if (!p->record.stream)
+ return;
+
+ stream_stop(pulse, &p->record);
+}
+
+static void playback_volume_changed(GObject *object, GParamSpec *pspec, gpointer data)
+{
+ SpicePulse *pulse = data;
+ SpicePulsePrivate *p = pulse->priv;
+ guint16 *volume;
+ guint nchannels;
+ pa_operation *op;
+ pa_cvolume v;
+ guint i;
+
+ g_object_get(object,
+ "volume", &volume,
+ "nchannels", &nchannels,
+ NULL);
+
+ pa_cvolume_init(&v);
+ v.channels = p->playback.spec.channels;
+ for (i = 0; i < nchannels; ++i) {
+ v.values[i] = (PA_VOLUME_NORM - PA_VOLUME_MUTED) * volume[i] / G_MAXUINT16;
+ SPICE_DEBUG("playback volume changed %u", v.values[i]);
+ }
+
+ if (!p->playback.stream ||
+ pa_stream_get_index(p->playback.stream) == PA_INVALID_INDEX)
+ return;
+
+ op = pa_context_set_sink_input_volume(p->context,
+ pa_stream_get_index(p->playback.stream),
+ &v, NULL, NULL);
+ if (!op)
+ g_warning("set_sink_input_volume() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ else
+ pa_operation_unref(op);
+}
+
+static void playback_mute_changed(GObject *object, GParamSpec *pspec, gpointer data)
+{
+ SpicePulse *pulse = data;
+ SpicePulsePrivate *p = pulse->priv;
+ gboolean mute;
+ pa_operation *op;
+
+ g_object_get(object, "mute", &mute, NULL);
+ SPICE_DEBUG("playback mute changed %d", mute);
+
+ if (!p->playback.stream ||
+ pa_stream_get_index(p->playback.stream) == PA_INVALID_INDEX)
+ return;
+
+ op = pa_context_set_sink_input_mute(p->context,
+ pa_stream_get_index(p->playback.stream),
+ mute, NULL, NULL);
+ if (!op)
+ g_warning("set_sink_input_mute() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ else
+ pa_operation_unref(op);
+}
+
+static void playback_min_latency_changed(GObject *object, GParamSpec *pspec, gpointer data)
+{
+
+ SpicePulse *pulse = data;
+ SpicePulsePrivate *p = pulse->priv;
+ guint min_latency;
+
+ g_object_get(object, "min-latency", &min_latency, NULL);
+ p->target_delay = min_latency;
+
+ if (p->last_delay < p->target_delay) {
+ SPICE_DEBUG("%s: corking", __FUNCTION__);
+ if (p->playback.stream)
+ stream_cork(pulse, &p->playback, FALSE);
+ } else {
+ SPICE_DEBUG("%s: not corking. The current delay satisfies the requirement", __FUNCTION__);
+ }
+}
+
+static void record_mute_changed(GObject *object, GParamSpec *pspec, gpointer data)
+{
+ SpicePulse *pulse = data;
+ SpicePulsePrivate *p = pulse->priv;
+ gboolean mute;
+ pa_operation *op;
+
+ g_object_get(object, "mute", &mute, NULL);
+ SPICE_DEBUG("record mute changed %d", mute);
+
+ if (!p->record.stream ||
+ pa_stream_get_device_index(p->record.stream) == PA_INVALID_INDEX)
+ return;
+
+#if PA_CHECK_VERSION(1,0,0)
+ op = pa_context_set_source_output_mute(p->context,
+ pa_stream_get_index(p->record.stream),
+#else
+ op = pa_context_set_source_mute_by_index(p->context,
+ pa_stream_get_device_index(p->record.stream),
+#endif
+ mute, NULL, NULL);
+ if (!op)
+ g_warning("set_source_output_mute() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ else
+ pa_operation_unref(op);
+}
+
+static void record_volume_changed(GObject *object, GParamSpec *pspec, gpointer data)
+{
+ SpicePulse *pulse = data;
+ SpicePulsePrivate *p = pulse->priv;
+ guint16 *volume;
+ guint nchannels;
+ pa_operation *op;
+ pa_cvolume v;
+ guint i;
+
+ g_object_get(object,
+ "volume", &volume,
+ "nchannels", &nchannels,
+ NULL);
+
+ pa_cvolume_init(&v);
+ v.channels = p->record.spec.channels;
+ for (i = 0; i < nchannels; ++i) {
+ v.values[i] = (PA_VOLUME_NORM - PA_VOLUME_MUTED) * volume[i] / G_MAXUINT16;
+ SPICE_DEBUG("record volume changed %u", v.values[i]);
+ }
+
+ if (!p->record.stream ||
+ pa_stream_get_device_index(p->record.stream) == PA_INVALID_INDEX)
+ return;
+
+#if PA_CHECK_VERSION(1,0,0)
+ op = pa_context_set_source_output_volume(p->context,
+ pa_stream_get_index(p->record.stream),
+#else
+ op = pa_context_set_source_volume_by_index(p->context,
+ pa_stream_get_device_index(p->record.stream),
+#endif
+ &v, NULL, NULL);
+ if (!op)
+ g_warning("set_source_output_volume() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ else
+ pa_operation_unref(op);
+}
+
+static void
+channel_weak_notified(gpointer data,
+ GObject *where_the_object_was)
+{
+ SpicePulse *pulse = SPICE_PULSE(data);
+ SpicePulsePrivate *p = pulse->priv;
+
+ if (where_the_object_was == (GObject *)p->pchannel) {
+ SPICE_DEBUG("playback closed");
+ playback_stop(pulse);
+ p->pchannel = NULL;
+ } else if (where_the_object_was == (GObject *)p->rchannel) {
+ SPICE_DEBUG("record closed");
+ record_stop(pulse);
+ p->rchannel = NULL;
+ }
+}
+
+static gboolean connect_channel(SpiceAudio *audio, SpiceChannel *channel)
+{
+ SpicePulse *pulse = SPICE_PULSE(audio);
+ SpicePulsePrivate *p = pulse->priv;
+
+ if (SPICE_IS_PLAYBACK_CHANNEL(channel)) {
+ g_return_val_if_fail(p->pchannel == NULL, FALSE);
+
+ p->pchannel = channel;
+ g_object_weak_ref(G_OBJECT(p->pchannel), channel_weak_notified, audio);
+ spice_g_signal_connect_object(channel, "playback-start",
+ G_CALLBACK(playback_start), pulse, 0);
+ spice_g_signal_connect_object(channel, "playback-data",
+ G_CALLBACK(playback_data), pulse, 0);
+ spice_g_signal_connect_object(channel, "playback-stop",
+ G_CALLBACK(playback_stop), pulse, G_CONNECT_SWAPPED);
+ spice_g_signal_connect_object(channel, "notify::volume",
+ G_CALLBACK(playback_volume_changed), pulse, 0);
+ spice_g_signal_connect_object(channel, "notify::mute",
+ G_CALLBACK(playback_mute_changed), pulse, 0);
+ spice_g_signal_connect_object(channel, "notify::min-latency",
+ G_CALLBACK(playback_min_latency_changed), pulse, 0);
+
+ return TRUE;
+ }
+
+ if (SPICE_IS_RECORD_CHANNEL(channel)) {
+ g_return_val_if_fail(p->rchannel == NULL, FALSE);
+
+ p->rchannel = channel;
+ g_object_weak_ref(G_OBJECT(p->rchannel), channel_weak_notified, audio);
+ spice_g_signal_connect_object(channel, "record-start",
+ G_CALLBACK(record_start), pulse, 0);
+ spice_g_signal_connect_object(channel, "record-stop",
+ G_CALLBACK(record_stop), pulse, G_CONNECT_SWAPPED);
+ spice_g_signal_connect_object(channel, "notify::volume",
+ G_CALLBACK(record_volume_changed), pulse, 0);
+ spice_g_signal_connect_object(channel, "notify::mute",
+ G_CALLBACK(record_mute_changed), pulse, 0);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void context_state_callback(pa_context *c, void *userdata)
+{
+ SpicePulse *pulse = userdata;
+ SpicePulsePrivate *p;
+
+ p = pulse->priv;
+
+ g_return_if_fail(p != NULL);
+ g_return_if_fail(c != NULL);
+ switch (pa_context_get_state(c)) {
+ case PA_CONTEXT_CONNECTING:
+ case PA_CONTEXT_AUTHORIZING:
+ case PA_CONTEXT_SETTING_NAME:
+ case PA_CONTEXT_UNCONNECTED:
+ break;
+
+ case PA_CONTEXT_READY: {
+ if (!p->record.stream && p->record.started)
+ create_record(SPICE_PULSE(userdata));
+
+ if (!p->playback.stream && p->playback.started)
+ create_playback(SPICE_PULSE(userdata));
+
+ if (p->pending_restore_task != NULL &&
+ p->pending_restore_task->pa_op == NULL) {
+ pa_operation *op = pa_ext_stream_restore_read(p->context,
+ stream_restore_read_cb,
+ pulse);
+ if (!op)
+ goto context_fail;
+ p->pending_restore_task->pa_op = op;
+ }
+ break;
+ }
+
+ case PA_CONTEXT_FAILED:
+ g_warning("PulseAudio context failed %s",
+ pa_strerror(pa_context_errno(p->context)));
+ goto context_fail;
+
+ case PA_CONTEXT_TERMINATED:
+ default:
+ SPICE_DEBUG("PulseAudio context terminated");
+ goto context_fail;
+ }
+
+ return;
+
+context_fail:
+ if (p->pending_restore_task != NULL) {
+ const gchar *errmsg = pa_strerror(pa_context_errno(p->context));
+ errmsg = (errmsg != NULL) ? errmsg : "PulseAudio context terminated";
+ spice_pulse_complete_all_async_tasks(pulse, errmsg);
+ }
+}
+
+SpicePulse *spice_pulse_new(SpiceSession *session, GMainContext *context,
+ const char *name)
+{
+ SpicePulse *pulse;
+ SpicePulsePrivate *p;
+
+ pulse = g_object_new(SPICE_TYPE_PULSE,
+ "session", session,
+ "main-context", context,
+ NULL);
+ p = pulse->priv;
+
+ p->mainloop = pa_glib_mainloop_new(context);
+ p->state = PA_CONTEXT_READY;
+ p->context = pa_context_new(pa_glib_mainloop_get_api(p->mainloop), name);
+ pa_context_set_state_callback(p->context, context_state_callback, pulse);
+ if (pa_context_connect(p->context, NULL, 0, NULL) < 0) {
+ g_warning("pa_context_connect() failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ goto error;
+ }
+
+ p->playback.name = g_strconcat("sink-input-by-application-name:",
+ g_get_application_name(), NULL);
+ p->record.name = g_strconcat("source-output-by-application-name:",
+ g_get_application_name(), NULL);
+ return pulse;
+
+error:
+ g_object_unref(pulse);
+ return NULL;
+}
+
+static gboolean free_async_task(gpointer user_data)
+{
+ struct async_task *task = user_data;
+
+ if (task == NULL)
+ return G_SOURCE_REMOVE;
+
+ if (task->pa_op != NULL) {
+ pa_operation_cancel(task->pa_op);
+ g_clear_pointer(&task->pa_op, pa_operation_unref);
+ }
+
+ if (task->pulse) {
+ if (task->pulse->priv->pending_restore_task == task) {
+ task->pulse->priv->pending_restore_task = NULL;
+ }
+ g_object_unref(task->pulse);
+ }
+
+ if (task->main_channel)
+ g_object_unref(task->main_channel);
+
+ if (task->pa_op != NULL)
+ pa_operation_unref(task->pa_op);
+
+ g_cancellable_disconnect(g_task_get_cancellable(task->gtask), task->cancel_id);
+
+ if (task->gtask)
+ g_object_unref(task->gtask);
+
+ g_free(task);
+ return G_SOURCE_REMOVE;
+}
+
+static void cancel_task(GCancellable *cancellable, gpointer user_data)
+{
+ struct async_task *task = user_data;
+ g_return_if_fail(task != NULL);
+
+#if GLIB_CHECK_VERSION(2,40,0)
+ free_async_task(task);
+#else
+ /* This must be done now otherwise pulseaudio may return to a
+ * cancelled task operation before free_async_task is called */
+ if (task->pa_op != NULL) {
+ pa_operation_cancel(task->pa_op);
+ g_clear_pointer(&task->pa_op, pa_operation_unref);
+ }
+
+ /* Clear the pending_restore_task reference to avoid triggering a
+ * pa_operation when context state is in READY state */
+ if (task->pulse->priv->pending_restore_task == task) {
+ task->pulse->priv->pending_restore_task = NULL;
+ }
+
+ /* FIXME: https://bugzilla.gnome.org/show_bug.cgi?id=705395
+ * Free the memory in idle */
+ g_idle_add(free_async_task, task);
+#endif
+}
+
+static void complete_task(SpicePulse *pulse, struct async_task *task, const gchar *err_msg)
+{
+ SpicePulsePrivate *p = pulse->priv;
+
+ /* If we do have any err_msg, we failed */
+ if (err_msg != NULL) {
+ g_task_return_new_error(task->gtask,
+ SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED,
+ "restore-info failed: %s",
+ err_msg);
+ /* Volume-info does not change if stream is not found */
+ } else if ((task->is_playback == TRUE && p->playback.info_updated == FALSE) ||
+ (task->is_playback == FALSE && p->record.info_updated == FALSE)) {
+ g_task_return_new_error(task->gtask,
+ SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED,
+ "Stream not found by pulse");
+ } else {
+ g_task_return_boolean(task->gtask, TRUE);
+ }
+}
+
+static void spice_pulse_complete_async_task(struct async_task *task, const gchar *err_msg)
+{
+ SpicePulsePrivate *p;
+
+ g_return_if_fail(task != NULL);
+ p = task->pulse->priv;
+
+ complete_task(task->pulse, task, err_msg);
+ if (p->results != NULL) {
+ p->results = g_list_remove(p->results, task);
+ SPICE_DEBUG("Number of async task is %u", g_list_length(p->results));
+ }
+ free_async_task(task);
+}
+
+static void spice_pulse_complete_all_async_tasks(SpicePulse *pulse, const gchar *err_msg)
+{
+ SpicePulsePrivate *p;
+ GList *it;
+
+ g_return_if_fail(pulse != NULL);
+ p = pulse->priv;
+
+ /* Complete all tasks in list */
+ for(it = p->results; it != NULL; it = it->next) {
+ struct async_task *task = it->data;
+ complete_task(pulse, task, err_msg);
+ free_async_task(task);
+ }
+ g_clear_pointer(&p->results, g_list_free);
+ SPICE_DEBUG("All async tasks completed");
+}
+
+static void stream_restore_read_cb(pa_context *context,
+ const pa_ext_stream_restore_info *info,
+ int eol,
+ void *userdata)
+{
+ SpicePulsePrivate *p = SPICE_PULSE(userdata)->priv;
+ struct stream *pstream = NULL;
+
+ if (eol ||
+ (p->playback.info_updated == TRUE &&
+ p->record.info_updated == TRUE)) {
+ /* We only have one pa_operation running the stream-restore-info
+ * which retrieves volume-info from both Playback and Record channels;
+ * We can complete all async tasks now that this operation ended.
+ * (or we already have the volume-info we want)
+ * Note: the following function cancel the current pa_operation */
+ spice_pulse_complete_all_async_tasks(SPICE_PULSE(userdata), NULL);
+ return;
+ }
+
+ if (g_strcmp0(info->name, p->playback.name) == 0) {
+ pstream = &p->playback;
+ } else if (g_strcmp0(info->name, p->record.name) == 0) {
+ pstream = &p->record;
+ } else {
+ /* This is not the stream you are looking for. */
+ return;
+ }
+
+ if (info->channel_map.channels == 0) {
+ SPICE_DEBUG("Number of channels stored is zero. Ignore. (%s)", info->name);
+ return;
+ }
+
+ pstream->info_updated = TRUE;
+ pstream->info.name = pstream->name;
+ pstream->info.mute = info->mute;
+ pstream->info.channel_map = info->channel_map;
+ pstream->info.volume = info->volume;
+}
+
+#if PA_CHECK_VERSION(1,0,0)
+static void source_output_info_cb(pa_context *context,
+ const pa_source_output_info *info,
+ int eol,
+ void *userdata)
+#else
+static void source_info_cb(pa_context *context,
+ const pa_source_info *info,
+ int eol,
+ void *userdata)
+#endif
+{
+ struct async_task *task = userdata;
+ SpicePulsePrivate *p = task->pulse->priv;
+ struct stream *pstream = &p->record;
+
+ if (eol) {
+ spice_pulse_complete_async_task(task, NULL);
+ return;
+ }
+
+ pstream->info_updated = TRUE;
+ pstream->info.name = pstream->name;
+ pstream->info.mute = info->mute;
+ pstream->info.channel_map = info->channel_map;
+ pstream->info.volume = info->volume;
+}
+
+static void sink_input_info_cb(pa_context *context,
+ const pa_sink_input_info *info,
+ int eol,
+ void *userdata)
+{
+ struct async_task *task = userdata;
+ SpicePulsePrivate *p = task->pulse->priv;
+ struct stream *pstream = &p->playback;
+
+ if (eol) {
+ spice_pulse_complete_async_task(task, NULL);
+ return;
+ }
+
+ pstream->info_updated = TRUE;
+ pstream->info.name = pstream->name;
+ pstream->info.mute = info->mute;
+ pstream->info.channel_map = info->channel_map;
+ pstream->info.volume = info->volume;
+}
+
+/* to avoid code duplication */
+static void pulse_stream_restore_info_async(gboolean is_playback,
+ SpiceAudio *audio,
+ GCancellable *cancellable,
+ SpiceMainChannel *main_channel,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SpicePulsePrivate *p = SPICE_PULSE(audio)->priv;
+ GTask *gtask;
+ struct async_task *task = g_malloc0(sizeof(struct async_task));
+ pa_operation *op = NULL;
+
+ gtask = g_task_new(audio, cancellable, callback, user_data);
+
+ task->gtask = gtask;
+ task->pulse = g_object_ref(audio);
+ task->callback = callback;
+ task->user_data = user_data;
+ task->is_playback = is_playback;
+ task->main_channel = g_object_ref(main_channel);
+ task->pa_op = NULL;
+
+ if (cancellable)
+ task->cancel_id = g_cancellable_connect(cancellable, G_CALLBACK(cancel_task), task, NULL);
+
+ /* If Playback/Record stream is created we use pulse API to get volume-info
+ * from those streams directly. If the stream is not created, retrieve last
+ * volume/mute values from Pulse database using the application name;
+ * If we already have retrieved volume-info from Pulse database then it is
+ * safe to return the volume-info we already have in <stream>info */
+
+ if (is_playback == TRUE &&
+ p->playback.stream != NULL &&
+ pa_stream_get_index(p->playback.stream) != PA_INVALID_INDEX) {
+ SPICE_DEBUG("Playback stream is created - get-sink-input-info");
+ p->playback.info_updated = FALSE;
+ op = pa_context_get_sink_input_info(p->context,
+ pa_stream_get_index(p->playback.stream),
+ sink_input_info_cb,
+ task);
+ if (!op)
+ goto fail;
+ task->pa_op = op;
+
+ } else if (is_playback == FALSE &&
+ p->record.stream != NULL &&
+ pa_stream_get_index(p->record.stream) != PA_INVALID_INDEX) {
+ SPICE_DEBUG("Record stream is created - get-source-output-info");
+ p->record.info_updated = FALSE;
+#if PA_CHECK_VERSION(1,0,0)
+ op = pa_context_get_source_output_info(p->context,
+ pa_stream_get_index(p->record.stream),
+ source_output_info_cb,
+ task);
+#else
+ op = pa_context_get_source_info_by_index(p->context,
+ pa_stream_get_device_index(p->record.stream),
+ source_info_cb,
+ task);
+#endif
+ if (!op)
+ goto fail;
+ task->pa_op = op;
+
+ } else {
+ if (p->playback.info.name != NULL ||
+ p->record.info.name != NULL) {
+ /* If the pstream->info.name is set then we already have updated
+ * volume information. We can complete the request now */
+ SPICE_DEBUG("Return the volume-information we already have");
+ spice_pulse_complete_async_task(task, NULL);
+ return;
+ }
+
+ if (p->results == NULL) {
+ SPICE_DEBUG("Streams are not created - ext-stream-restore");
+ p->playback.info_updated = FALSE;
+ p->record.info_updated = FALSE;
+
+ if (pa_context_get_state(p->context) == PA_CONTEXT_READY) {
+ /* Restore value from pulse db */
+ op = pa_ext_stream_restore_read(p->context, stream_restore_read_cb, audio);
+ if (!op)
+ goto fail;
+ task->pa_op = op;
+ } else {
+ /* It is possible that we want to get volume-info before the
+ * context is in READY state. In this case, we wait for the
+ * context state change to READY. */
+ p->pending_restore_task = task;
+ }
+ }
+ }
+
+ p->results = g_list_append(p->results, task);
+ SPICE_DEBUG ("Number of async task is %u", g_list_length(p->results));
+ return;
+
+fail:
+ if (!op) {
+ g_task_report_new_error(audio,
+ callback,
+ user_data,
+ pulse_stream_restore_info_async,
+ SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED,
+ "Volume-Info failed: %s",
+ pa_strerror(pa_context_errno(p->context)));
+ free_async_task(task);
+ }
+}
+
+/* to avoid code duplication */
+static gboolean pulse_stream_restore_info_finish(gboolean is_playback,
+ SpiceAudio *audio,
+ GAsyncResult *res,
+ gboolean *mute,
+ guint8 *nchannels,
+ guint16 **volume,
+ GError **error)
+{
+ SpicePulsePrivate *p = SPICE_PULSE(audio)->priv;
+ struct stream *pstream = (is_playback) ? &p->playback : &p->record;
+ GTask *task = G_TASK(res);
+
+ g_return_val_if_fail(g_task_is_valid(task, G_OBJECT(audio)), FALSE);
+
+ if (g_task_had_error(task)) {
+ /* set out args that should have new alloc'ed memory to NULL */
+ if (volume != NULL) {
+ *volume = NULL;
+ }
+ return g_task_propagate_boolean(task, error);
+ }
+
+ if (mute != NULL) {
+ *mute = (pstream->info.mute) ? TRUE : FALSE;
+ }
+
+ if (nchannels != NULL) {
+ *nchannels = pstream->info.channel_map.channels;
+ }
+
+ if (volume != NULL) {
+ gint i;
+ *volume = g_new(guint16, pstream->info.channel_map.channels);
+ for (i = 0; i < pstream->info.channel_map.channels; i++) {
+ (*volume)[i] = MIN(pstream->info.volume.values[i], G_MAXUINT16);
+ SPICE_DEBUG("(%s) volume at channel %d is %u",
+ (is_playback) ? "playback" : "record", i, (*volume)[i]);
+ }
+ }
+
+ return g_task_propagate_boolean(task, error);
+}
+
+static void spice_pulse_get_playback_volume_info_async(SpiceAudio *audio,
+ GCancellable *cancellable,
+ SpiceMainChannel *main_channel,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ pulse_stream_restore_info_async(TRUE, audio, cancellable, main_channel, callback, user_data);
+}
+
+static gboolean spice_pulse_get_playback_volume_info_finish(SpiceAudio *audio,
+ GAsyncResult *res,
+ gboolean *mute,
+ guint8 *nchannels,
+ guint16 **volume,
+ GError **error)
+{
+ return pulse_stream_restore_info_finish(TRUE, audio, res, mute,
+ nchannels, volume, error);
+}
+
+static void spice_pulse_get_record_volume_info_async(SpiceAudio *audio,
+ GCancellable *cancellable,
+ SpiceMainChannel *main_channel,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ pulse_stream_restore_info_async(FALSE, audio, cancellable, main_channel, callback, user_data);
+}
+
+static gboolean spice_pulse_get_record_volume_info_finish(SpiceAudio *audio,
+ GAsyncResult *res,
+ gboolean *mute,
+ guint8 *nchannels,
+ guint16 **volume,
+ GError **error)
+{
+ return pulse_stream_restore_info_finish(FALSE, audio, res, mute,
+ nchannels, volume, error);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_PULSE_H__
+#define __SPICE_CLIENT_PULSE_H__
+
+#include "spice-client.h"
+#include "spice-audio.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_PULSE (spice_pulse_get_type())
+#define SPICE_PULSE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_PULSE, SpicePulse))
+#define SPICE_PULSE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_PULSE, SpicePulseClass))
+#define SPICE_IS_PULSE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_PULSE))
+#define SPICE_IS_PULSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_PULSE))
+#define SPICE_PULSE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_PULSE, SpicePulseClass))
+
+
+typedef struct _SpicePulse SpicePulse;
+typedef struct _SpicePulseClass SpicePulseClass;
+typedef struct _SpicePulsePrivate SpicePulsePrivate;
+
+struct _SpicePulse {
+ SpiceAudio parent;
+ SpicePulsePrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+struct _SpicePulseClass {
+ SpiceAudioClass parent_class;
+ /* Do not add fields to this struct */
+};
+
+GType spice_pulse_get_type(void);
+
+SpicePulse *spice_pulse_new(SpiceSession *session,
+ GMainContext *context,
+ const char *name);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_PULSE_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_SESSION_PRIV_H__
+#define __SPICE_CLIENT_SESSION_PRIV_H__
+
+#include "config.h"
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#ifdef USE_PHODAV
+#include <libphodav/phodav.h>
+#else
+typedef struct _PhodavServer PhodavServer;
+#endif
+
+#include "desktop-integration.h"
+#include "spice-session.h"
+#include "spice-gtk-session.h"
+#include "spice-channel-cache.h"
+#include "decode.h"
+
+G_BEGIN_DECLS
+
+#define WEBDAV_MAGIC_SIZE 16
+
+SpiceSession *spice_session_new_from_session(SpiceSession *session);
+
+void spice_session_set_connection_id(SpiceSession *session, int id);
+int spice_session_get_connection_id(SpiceSession *session);
+gboolean spice_session_get_client_provided_socket(SpiceSession *session);
+
+GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceChannel *channel,
+ gboolean *use_tls, GError **error);
+void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel);
+void spice_session_channel_migrate(SpiceSession *session, SpiceChannel *channel);
+
+void spice_session_set_mm_time(SpiceSession *session, guint32 time);
+guint32 spice_session_get_mm_time(SpiceSession *session);
+
+void spice_session_switching_disconnect(SpiceSession *session);
+void spice_session_start_migrating(SpiceSession *session,
+ gboolean full_migration);
+void spice_session_abort_migration(SpiceSession *session);
+void spice_session_set_migration_state(SpiceSession *session, SpiceSessionMigration state);
+
+void spice_session_set_port(SpiceSession *session, int port, gboolean tls);
+void spice_session_get_pubkey(SpiceSession *session, guint8 **pubkey, guint *size);
+guint spice_session_get_verify(SpiceSession *session);
+const gchar* spice_session_get_username(SpiceSession *session);
+const gchar* spice_session_get_password(SpiceSession *session);
+const gchar* spice_session_get_host(SpiceSession *session);
+const gchar* spice_session_get_cert_subject(SpiceSession *session);
+const gchar* spice_session_get_ciphers(SpiceSession *session);
+const gchar* spice_session_get_ca_file(SpiceSession *session);
+void spice_session_get_ca(SpiceSession *session, guint8 **ca, guint *size);
+
+void spice_session_set_caches_hints(SpiceSession *session,
+ uint32_t pci_ram_size,
+ uint32_t n_display_channels);
+void spice_session_get_caches(SpiceSession *session,
+ display_cache **images,
+ SpiceGlzDecoderWindow **glz_window);
+void spice_session_palettes_clear(SpiceSession *session);
+void spice_session_images_clear(SpiceSession *session);
+void spice_session_migrate_end(SpiceSession *session);
+gboolean spice_session_migrate_after_main_init(SpiceSession *session);
+SpiceChannel* spice_session_lookup_channel(SpiceSession *session, gint id, gint type);
+void spice_session_set_uuid(SpiceSession *session, guint8 uuid[16]);
+void spice_session_set_name(SpiceSession *session, const gchar *name);
+gboolean spice_session_is_playback_active(SpiceSession *session);
+guint32 spice_session_get_playback_latency(SpiceSession *session);
+void spice_session_sync_playback_latency(SpiceSession *session);
+const gchar* spice_session_get_shared_dir(SpiceSession *session);
+void spice_session_set_shared_dir(SpiceSession *session, const gchar *dir);
+gboolean spice_session_get_audio_enabled(SpiceSession *session);
+gboolean spice_session_get_smartcard_enabled(SpiceSession *session);
+gboolean spice_session_get_usbredir_enabled(SpiceSession *session);
+
+const guint8* spice_session_get_webdav_magic(SpiceSession *session);
+PhodavServer *spice_session_get_webdav_server(SpiceSession *session);
+PhodavServer* channel_webdav_server_new(SpiceSession *session);
+guint spice_session_get_n_display_channels(SpiceSession *session);
+void spice_session_set_main_channel(SpiceSession *session, SpiceChannel *channel);
+gboolean spice_session_set_migration_session(SpiceSession *session, SpiceSession *mig_session);
+SpiceAudio *spice_audio_get(SpiceSession *session, GMainContext *context);
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_SESSION_PRIV_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <gio/gio.h>
+#include <glib.h>
+#ifdef G_OS_UNIX
+#include <gio/gunixsocketaddress.h>
+#endif
+#include "common/ring.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+#include "spice-channel-priv.h"
+#include "spice-util-priv.h"
+#include "spice-session-priv.h"
+#include "gio-coroutine.h"
+#include "wocky-http-proxy.h"
+#include "spice-uri-priv.h"
+#include "channel-playback-priv.h"
+#include "spice-audio.h"
+
+struct channel {
+ SpiceChannel *channel;
+ RingItem link;
+};
+
+#define IMAGES_CACHE_SIZE_DEFAULT (1024 * 1024 * 80)
+#define MIN_GLZ_WINDOW_SIZE_DEFAULT (1024 * 1024 * 12)
+#define MAX_GLZ_WINDOW_SIZE_DEFAULT MIN((LZ_MAX_WINDOW_SIZE * 4), 1024 * 1024 * 64)
+
+struct _SpiceSessionPrivate {
+ char *host;
+ char *unix_path;
+ char *port;
+ char *tls_port;
+ char *username;
+ char *password;
+ char *ca_file;
+ char *ciphers;
+ GByteArray *pubkey;
+ GByteArray *ca;
+ char *cert_subject;
+ guint verify;
+ gboolean read_only;
+ SpiceURI *proxy;
+ gchar *shared_dir;
+ gboolean share_dir_ro;
+
+ /* whether to enable audio */
+ gboolean audio;
+
+ /* whether to enable smartcard event forwarding to the server */
+ gboolean smartcard;
+
+ /* list of certificates to use for the software smartcard reader if
+ * enabled. For now, it has to contain exactly 3 certificates for
+ * the software reader to be functional
+ */
+ GStrv smartcard_certificates;
+
+ /* path to the local certificate database to use to lookup the
+ * certificates stored in 'certificates'. If NULL, libcacard will
+ * fallback to using a default database.
+ */
+ char * smartcard_db;
+
+ /* whether to enable USB redirection */
+ gboolean usbredir;
+
+ /* Set when a usbredir channel has requested the keyboard grab to be
+ temporarily released (because it is going to invoke policykit) */
+ gboolean inhibit_keyboard_grab;
+
+ GStrv disable_effects;
+ GStrv secure_channels;
+ gint color_depth;
+
+ int connection_id;
+ int protocol;
+ SpiceChannel *cmain; /* weak reference */
+ Ring channels;
+ guint32 mm_time;
+ gboolean client_provided_sockets;
+ guint64 mm_time_at_clock;
+ SpiceSession *migration;
+ GList *migration_left;
+ SpiceSessionMigration migration_state;
+ gboolean full_migration; /* seamless migration indicator */
+ guint disconnecting;
+ gboolean migrate_wait_init;
+ guint after_main_init;
+ gboolean for_migration;
+
+ display_cache *images;
+ display_cache *palettes;
+ SpiceGlzDecoderWindow *glz_window;
+ int images_cache_size;
+ int glz_window_size;
+ uint32_t pci_ram_size;
+ uint32_t n_display_channels;
+ guint8 uuid[16];
+ gchar *name;
+ SpiceImageCompression preferred_compression;
+
+ /* associated objects */
+ SpiceAudio *audio_manager;
+ SpiceUsbDeviceManager *usb_manager;
+ SpicePlaybackChannel *playback_channel;
+ PhodavServer *webdav;
+};
+
+
+/**
+ * SECTION:spice-session
+ * @short_description: handles connection details, and active channels
+ * @title: Spice Session
+ * @section_id:
+ * @see_also: #SpiceChannel, and the GTK widget #SpiceDisplay
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * The #SpiceSession class handles all the #SpiceChannel connections.
+ * It's also the class that contains connections informations, such as
+ * #SpiceSession:host and #SpiceSession:port.
+ *
+ * You can simply set the property #SpiceSession:uri to something like
+ * "spice://127.0.0.1?port=5930" to configure your connection details.
+ *
+ * You may want to connect to #SpiceSession::channel-new signal, to be
+ * informed of the availability of channels and to interact with
+ * them.
+ *
+ * For example, when the #SpiceInputsChannel is available and get the
+ * event #SPICE_CHANNEL_OPENED, you can send key events with
+ * spice_inputs_key_press(). When the #SpiceMainChannel is available,
+ * you can start sharing the clipboard... .
+ *
+ *
+ * Once #SpiceSession properties set, you can call
+ * spice_session_connect() to start connecting and communicating with
+ * a Spice server.
+ */
+
+/* ------------------------------------------------------------------ */
+/* gobject glue */
+
+#define SPICE_SESSION_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SPICE_TYPE_SESSION, SpiceSessionPrivate))
+
+G_DEFINE_TYPE (SpiceSession, spice_session, G_TYPE_OBJECT);
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_HOST,
+ PROP_PORT,
+ PROP_TLS_PORT,
+ PROP_PASSWORD,
+ PROP_CA_FILE,
+ PROP_CIPHERS,
+ PROP_IPV4,
+ PROP_IPV6,
+ PROP_PROTOCOL,
+ PROP_URI,
+ PROP_CLIENT_SOCKETS,
+ PROP_PUBKEY,
+ PROP_CERT_SUBJECT,
+ PROP_VERIFY,
+ PROP_MIGRATION_STATE,
+ PROP_AUDIO,
+ PROP_SMARTCARD,
+ PROP_SMARTCARD_CERTIFICATES,
+ PROP_SMARTCARD_DB,
+ PROP_USBREDIR,
+ PROP_INHIBIT_KEYBOARD_GRAB,
+ PROP_DISABLE_EFFECTS,
+ PROP_COLOR_DEPTH,
+ PROP_READ_ONLY,
+ PROP_CACHE_SIZE,
+ PROP_GLZ_WINDOW_SIZE,
+ PROP_UUID,
+ PROP_NAME,
+ PROP_CA,
+ PROP_PROXY,
+ PROP_SECURE_CHANNELS,
+ PROP_SHARED_DIR,
+ PROP_SHARE_DIR_RO,
+ PROP_USERNAME,
+ PROP_UNIX_PATH,
+ PROP_PREF_COMPRESSION,
+};
+
+/* signals */
+enum {
+ SPICE_SESSION_CHANNEL_NEW,
+ SPICE_SESSION_CHANNEL_DESTROY,
+ SPICE_SESSION_MM_TIME_RESET,
+ SPICE_SESSION_LAST_SIGNAL,
+};
+
+/* Register SpiceImageCompress */
+#define SPICE_TYPE_IMAGE_COMPRESSION spice_image_compress_get_type()
+GType spice_image_compress_get_type (void);
+
+static const GEnumValue _spice_image_compress_values[] = {
+ { SPICE_IMAGE_COMPRESSION_INVALID, "SPICE_IMAGE_COMPRESSION_INVALID", "invalid" },
+ { SPICE_IMAGE_COMPRESSION_OFF, "SPICE_IMAGE_COMPRESSION_OFF", "off" },
+ { SPICE_IMAGE_COMPRESSION_AUTO_GLZ, "SPICE_IMAGE_COMPRESSION_AUTO_GLZ", "auto-glz" },
+ { SPICE_IMAGE_COMPRESSION_AUTO_LZ, "SPICE_IMAGE_COMPRESSION_AUTO_LZ", "auto-lz" },
+ { SPICE_IMAGE_COMPRESSION_QUIC, "SPICE_IMAGE_COMPRESSION_QUIC", "quic" },
+ { SPICE_IMAGE_COMPRESSION_GLZ, "SPICE_IMAGE_COMPRESSION_GLZ", "glz" },
+ { SPICE_IMAGE_COMPRESSION_LZ, "SPICE_IMAGE_COMPRESSION_LZ", "lz" },
+ { SPICE_IMAGE_COMPRESSION_LZ4, "SPICE_IMAGE_COMPRESSION_LZ4", "lz4" },
+ { 0, NULL, NULL }
+};
+
+G_STATIC_ASSERT(G_N_ELEMENTS(_spice_image_compress_values) == SPICE_IMAGE_COMPRESSION_ENUM_END + 1);
+
+GType
+spice_image_compress_get_type (void)
+{
+ static GType type = 0;
+ static volatile gsize type_volatile = 0;
+
+ if (g_once_init_enter(&type_volatile)) {
+ type = g_enum_register_static ("SpiceImageCompress", _spice_image_compress_values);
+ g_once_init_leave(&type_volatile, type);
+ }
+
+ return type;
+}
+
+static guint signals[SPICE_SESSION_LAST_SIGNAL];
+
+static void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel);
+
+static void update_proxy(SpiceSession *self, const gchar *str)
+{
+ SpiceSessionPrivate *s = self->priv;
+ SpiceURI *proxy = NULL;
+ GError *error = NULL;
+
+ if (str == NULL)
+ str = g_getenv("SPICE_PROXY");
+ if (str == NULL || *str == 0) {
+ g_clear_object(&s->proxy);
+ return;
+ }
+
+ proxy = spice_uri_new();
+ if (!spice_uri_parse(proxy, str, &error))
+ g_clear_object(&proxy);
+ if (error) {
+ g_warning("%s", error->message);
+ g_clear_error(&error);
+ }
+
+ if (proxy != NULL) {
+ g_clear_object(&s->proxy);
+ s->proxy = proxy;
+ }
+}
+
+static void spice_session_init(SpiceSession *session)
+{
+ SpiceSessionPrivate *s;
+ gchar *channels;
+
+ SPICE_DEBUG("New session (compiled from package " PACKAGE_STRING ")");
+ s = session->priv = SPICE_SESSION_GET_PRIVATE(session);
+
+ channels = spice_channel_supported_string();
+ SPICE_DEBUG("Supported channels: %s", channels);
+ g_free(channels);
+
+ ring_init(&s->channels);
+ s->images = cache_image_new((GDestroyNotify)pixman_image_unref);
+ s->glz_window = glz_decoder_window_new();
+ update_proxy(session, NULL);
+}
+
+static void
+session_disconnect(SpiceSession *self, gboolean keep_main)
+{
+ SpiceSessionPrivate *s;
+ struct channel *item;
+ RingItem *ring, *next;
+
+ s = self->priv;
+
+ for (ring = ring_get_head(&s->channels); ring != NULL; ring = next) {
+ next = ring_next(&s->channels, ring);
+ item = SPICE_CONTAINEROF(ring, struct channel, link);
+
+ if (keep_main && item->channel == s->cmain) {
+ spice_channel_disconnect(item->channel, SPICE_CHANNEL_NONE);
+ } else {
+ spice_session_channel_destroy(self, item->channel);
+ }
+ }
+
+ s->connection_id = 0;
+
+ g_clear_pointer(&s->name, g_free);
+ memset(s->uuid, 0, sizeof(s->uuid));
+
+ spice_session_abort_migration(self);
+}
+
+static void
+spice_session_dispose(GObject *gobject)
+{
+ SpiceSession *session = SPICE_SESSION(gobject);
+ SpiceSessionPrivate *s = session->priv;
+
+ SPICE_DEBUG("session dispose");
+
+ session_disconnect(session, FALSE);
+
+ g_warn_if_fail(s->migration == NULL);
+ g_warn_if_fail(s->migration_left == NULL);
+ g_warn_if_fail(s->after_main_init == 0);
+ g_warn_if_fail(s->disconnecting == 0);
+
+ g_clear_object(&s->audio_manager);
+ g_clear_object(&s->usb_manager);
+ g_clear_object(&s->proxy);
+ g_clear_object(&s->webdav);
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_session_parent_class)->dispose)
+ G_OBJECT_CLASS(spice_session_parent_class)->dispose(gobject);
+}
+
+static void
+spice_session_finalize(GObject *gobject)
+{
+ SpiceSession *session = SPICE_SESSION(gobject);
+ SpiceSessionPrivate *s = session->priv;
+
+ /* release stuff */
+ g_free(s->unix_path);
+ g_free(s->host);
+ g_free(s->port);
+ g_free(s->tls_port);
+ g_free(s->username);
+ g_free(s->password);
+ g_free(s->ca_file);
+ g_free(s->ciphers);
+ g_free(s->cert_subject);
+ g_strfreev(s->smartcard_certificates);
+ g_free(s->smartcard_db);
+ g_strfreev(s->disable_effects);
+ g_strfreev(s->secure_channels);
+ g_free(s->shared_dir);
+
+ g_clear_pointer(&s->images, cache_free);
+ glz_decoder_window_destroy(s->glz_window);
+
+ g_clear_pointer(&s->pubkey, g_byte_array_unref);
+ g_clear_pointer(&s->ca, g_byte_array_unref);
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_session_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_session_parent_class)->finalize(gobject);
+}
+
+#define URI_SCHEME_SPICE "spice://"
+#define URI_SCHEME_SPICE_UNIX "spice+unix://"
+#define URI_QUERY_START ";?"
+#define URI_QUERY_SEP ";&"
+
+static gchar* spice_uri_create(SpiceSession *session)
+{
+ SpiceSessionPrivate *s = session->priv;
+
+ if (s->unix_path != NULL) {
+ return g_strdup_printf(URI_SCHEME_SPICE_UNIX "%s", s->unix_path);
+ } else if (s->host != NULL) {
+ g_return_val_if_fail(s->port != NULL || s->tls_port != NULL, NULL);
+
+ GString *str = g_string_new(URI_SCHEME_SPICE);
+
+ g_string_append(str, s->host);
+ g_string_append(str, "?");
+ if (s->port != NULL) {
+ g_string_append_printf(str, "port=%s&", s->port);
+ }
+ if (s->tls_port != NULL) {
+ g_string_append_printf(str, "tls-port=%s", s->tls_port);
+ }
+ return g_string_free(str, FALSE);
+ }
+
+ g_return_val_if_reached(NULL);
+}
+
+static int spice_parse_uri(SpiceSession *session, const char *original_uri)
+{
+ SpiceSessionPrivate *s = session->priv;
+ gchar *host = NULL, *port = NULL, *tls_port = NULL, *uri = NULL, *username = NULL, *password = NULL;
+ gchar *path = NULL;
+ gchar *authority = NULL;
+ gchar *query = NULL;
+ gchar *tmp = NULL;
+
+ g_return_val_if_fail(original_uri != NULL, -1);
+
+ uri = g_strdup(original_uri);
+
+ if (g_str_has_prefix(uri, URI_SCHEME_SPICE_UNIX)) {
+ path = uri + strlen(URI_SCHEME_SPICE_UNIX);
+ goto end;
+ }
+
+ /* Break up the URI into its various parts, scheme, authority,
+ * path (ignored) and query
+ */
+ if (!g_str_has_prefix(uri, URI_SCHEME_SPICE)) {
+ g_warning("Expected a URI scheme of '%s' in URI '%s'",
+ URI_SCHEME_SPICE, uri);
+ goto fail;
+ }
+ authority = uri + strlen(URI_SCHEME_SPICE);
+
+ tmp = strchr(authority, '@');
+ if (tmp) {
+ tmp[0] = '\0';
+ username = g_uri_unescape_string(authority, NULL);
+ authority = ++tmp;
+ tmp = NULL;
+ }
+
+ path = strchr(authority, '/');
+ if (path) {
+ path[0] = '\0';
+ path++;
+ }
+
+ if (path) {
+ size_t prefix = strcspn(path, URI_QUERY_START);
+ query = path + prefix;
+ } else {
+ size_t prefix = strcspn(authority, URI_QUERY_START);
+ query = authority + prefix;
+ }
+
+ if (query && query[0]) {
+ query[0] = '\0';
+ query++;
+ }
+
+ /* Now process the individual parts */
+
+ if (authority[0] == '[') {
+ tmp = strchr(authority, ']');
+ if (!tmp) {
+ g_warning("Missing closing ']' in authority for URI '%s'", uri);
+ goto fail;
+ }
+ tmp[0] = '\0';
+ tmp++;
+ host = g_strdup_printf("[%s]", authority + 1);
+ if (tmp[0] == ':')
+ port = g_strdup(tmp + 1);
+ } else {
+ tmp = strchr(authority, ':');
+ if (tmp) {
+ *tmp = '\0';
+ tmp++;
+ port = g_strdup(tmp);
+ }
+ host = g_uri_unescape_string(authority, NULL);
+ }
+
+ if (path && !(g_str_equal(path, "") ||
+ g_str_equal(path, "/"))) {
+ g_warning("Unexpected path data '%s' for URI '%s'", path, uri);
+ /* don't fail, just ignore */
+ }
+ path = NULL;
+
+ while (query && query[0] != '\0') {
+ gchar key[32], value[128];
+ gchar **target_key;
+
+ int len;
+ if (sscanf(query, "%31[-a-zA-Z0-9]=%n", key, &len) != 1) {
+ g_warning("Failed to parse key in URI '%s'", query);
+ goto fail;
+ }
+
+ query += len;
+ if (*query == '\0') {
+ SPICE_DEBUG("key '%s' without value", key);
+ break;
+ } else if (*query == ';' || *query == '&') {
+ /* another argument */
+ query++;
+ continue;
+ }
+
+ if (sscanf(query, "%127[^;&]%n", value, &len) != 1) {
+ g_warning("Failed to parse value of key '%s' in URI '%s'", key, query);
+ goto fail;
+ }
+
+ query += len;
+ if (*query)
+ query++;
+
+ target_key = NULL;
+ if (g_str_equal(key, "port")) {
+ target_key = &port;
+ } else if (g_str_equal(key, "tls-port")) {
+ target_key = &tls_port;
+ } else if (g_str_equal(key, "password")) {
+ target_key = &password;
+ g_warning("password may be visible in process listings");
+ } else {
+ g_warning("unknown key in spice URI parsing: '%s'", key);
+ goto fail;
+ }
+ if (target_key) {
+ if (*target_key) {
+ g_warning("Double set of '%s' in URI '%s'", key, uri);
+ goto fail;
+ }
+ *target_key = g_uri_unescape_string(value, NULL);
+ }
+ }
+
+ if (port == NULL && tls_port == NULL) {
+ g_warning("Missing port or tls-port in spice URI '%s'", uri);
+ goto fail;
+ }
+
+end:
+ /* parsed ok -> apply */
+ g_free(s->unix_path);
+ g_free(s->host);
+ g_free(s->port);
+ g_free(s->tls_port);
+ g_free(s->username);
+ g_free(s->password);
+ s->unix_path = g_strdup(path);
+ g_free(uri);
+ s->host = host;
+ s->port = port;
+ s->tls_port = tls_port;
+ s->username = username;
+ s->password = password;
+ return 0;
+
+fail:
+ g_free(uri);
+ g_free(host);
+ g_free(port);
+ g_free(tls_port);
+ g_free(username);
+ g_free(password);
+ return -1;
+}
+
+static void spice_session_get_property(GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceSession *session = SPICE_SESSION(gobject);
+ SpiceSessionPrivate *s = session->priv;
+
+ switch (prop_id) {
+ case PROP_HOST:
+ g_value_set_string(value, s->host);
+ break;
+ case PROP_UNIX_PATH:
+ g_value_set_string(value, s->unix_path);
+ break;
+ case PROP_PORT:
+ g_value_set_string(value, s->port);
+ break;
+ case PROP_TLS_PORT:
+ g_value_set_string(value, s->tls_port);
+ break;
+ case PROP_USERNAME:
+ g_value_set_string(value, s->username);
+ break;
+ case PROP_PASSWORD:
+ g_value_set_string(value, s->password);
+ break;
+ case PROP_CA_FILE:
+ g_value_set_string(value, s->ca_file);
+ break;
+ case PROP_CIPHERS:
+ g_value_set_string(value, s->ciphers);
+ break;
+ case PROP_PROTOCOL:
+ g_value_set_int(value, s->protocol);
+ break;
+ case PROP_URI:
+ g_value_take_string(value, spice_uri_create(session));
+ break;
+ case PROP_CLIENT_SOCKETS:
+ g_value_set_boolean(value, s->client_provided_sockets);
+ break;
+ case PROP_PUBKEY:
+ g_value_set_boxed(value, s->pubkey);
+ break;
+ case PROP_CA:
+ g_value_set_boxed(value, s->ca);
+ break;
+ case PROP_CERT_SUBJECT:
+ g_value_set_string(value, s->cert_subject);
+ break;
+ case PROP_VERIFY:
+ g_value_set_flags(value, s->verify);
+ break;
+ case PROP_MIGRATION_STATE:
+ g_value_set_enum(value, s->migration_state);
+ break;
+ case PROP_SMARTCARD:
+ g_value_set_boolean(value, s->smartcard);
+ break;
+ case PROP_SMARTCARD_CERTIFICATES:
+ g_value_set_boxed(value, s->smartcard_certificates);
+ break;
+ case PROP_SMARTCARD_DB:
+ g_value_set_string(value, s->smartcard_db);
+ break;
+ case PROP_USBREDIR:
+ g_value_set_boolean(value, s->usbredir);
+ break;
+ case PROP_INHIBIT_KEYBOARD_GRAB:
+ g_value_set_boolean(value, s->inhibit_keyboard_grab);
+ break;
+ case PROP_DISABLE_EFFECTS:
+ g_value_set_boxed(value, s->disable_effects);
+ break;
+ case PROP_SECURE_CHANNELS:
+ g_value_set_boxed(value, s->secure_channels);
+ break;
+ case PROP_COLOR_DEPTH:
+ g_value_set_int(value, s->color_depth);
+ break;
+ case PROP_AUDIO:
+ g_value_set_boolean(value, s->audio);
+ break;
+ case PROP_READ_ONLY:
+ g_value_set_boolean(value, s->read_only);
+ break;
+ case PROP_CACHE_SIZE:
+ g_value_set_int(value, s->images_cache_size);
+ break;
+ case PROP_GLZ_WINDOW_SIZE:
+ g_value_set_int(value, s->glz_window_size);
+ break;
+ case PROP_NAME:
+ g_value_set_string(value, s->name);
+ break;
+ case PROP_UUID:
+ g_value_set_pointer(value, s->uuid);
+ break;
+ case PROP_PROXY:
+ g_value_take_string(value, spice_uri_to_string(s->proxy));
+ break;
+ case PROP_SHARED_DIR:
+ g_value_set_string(value, spice_session_get_shared_dir(session));
+ break;
+ case PROP_SHARE_DIR_RO:
+ g_value_set_boolean(value, s->share_dir_ro);
+ break;
+ case PROP_PREF_COMPRESSION:
+ g_value_set_enum(value, s->preferred_compression);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_session_set_property(GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceSession *session = SPICE_SESSION(gobject);
+ SpiceSessionPrivate *s = session->priv;
+ const char *str;
+
+ switch (prop_id) {
+ case PROP_HOST:
+ g_free(s->host);
+ s->host = g_value_dup_string(value);
+ break;
+ case PROP_UNIX_PATH:
+ g_free(s->unix_path);
+ s->unix_path = g_value_dup_string(value);
+ break;
+ case PROP_PORT:
+ g_free(s->port);
+ s->port = g_value_dup_string(value);
+ break;
+ case PROP_TLS_PORT:
+ g_free(s->tls_port);
+ s->tls_port = g_value_dup_string(value);
+ break;
+ case PROP_USERNAME:
+ g_free(s->username);
+ s->username = g_value_dup_string(value);
+ break;
+ case PROP_PASSWORD:
+ g_free(s->password);
+ s->password = g_value_dup_string(value);
+ break;
+ case PROP_CA_FILE:
+ g_free(s->ca_file);
+ s->ca_file = g_value_dup_string(value);
+ break;
+ case PROP_CIPHERS:
+ g_free(s->ciphers);
+ s->ciphers = g_value_dup_string(value);
+ break;
+ case PROP_PROTOCOL:
+ s->protocol = g_value_get_int(value);
+ break;
+ case PROP_URI:
+ str = g_value_get_string(value);
+ if (str != NULL)
+ spice_parse_uri(session, str);
+ break;
+ case PROP_CLIENT_SOCKETS:
+ s->client_provided_sockets = g_value_get_boolean(value);
+ break;
+ case PROP_PUBKEY:
+ if (s->pubkey)
+ g_byte_array_unref(s->pubkey);
+ s->pubkey = g_value_dup_boxed(value);
+ if (s->pubkey)
+ s->verify |= SPICE_SESSION_VERIFY_PUBKEY;
+ else
+ s->verify &= ~SPICE_SESSION_VERIFY_PUBKEY;
+ break;
+ case PROP_CERT_SUBJECT:
+ g_free(s->cert_subject);
+ s->cert_subject = g_value_dup_string(value);
+ if (s->cert_subject)
+ s->verify |= SPICE_SESSION_VERIFY_SUBJECT;
+ else
+ s->verify &= ~SPICE_SESSION_VERIFY_SUBJECT;
+ break;
+ case PROP_VERIFY:
+ s->verify = g_value_get_flags(value);
+ break;
+ case PROP_MIGRATION_STATE:
+ s->migration_state = g_value_get_enum(value);
+ break;
+ case PROP_SMARTCARD:
+ s->smartcard = g_value_get_boolean(value);
+ break;
+ case PROP_SMARTCARD_CERTIFICATES:
+ g_strfreev(s->smartcard_certificates);
+ s->smartcard_certificates = g_value_dup_boxed(value);
+ break;
+ case PROP_SMARTCARD_DB:
+ g_free(s->smartcard_db);
+ s->smartcard_db = g_value_dup_string(value);
+ break;
+ case PROP_USBREDIR:
+ s->usbredir = g_value_get_boolean(value);
+ break;
+ case PROP_INHIBIT_KEYBOARD_GRAB:
+ s->inhibit_keyboard_grab = g_value_get_boolean(value);
+ break;
+ case PROP_DISABLE_EFFECTS:
+ g_strfreev(s->disable_effects);
+ s->disable_effects = g_value_dup_boxed(value);
+ break;
+ case PROP_SECURE_CHANNELS:
+ g_strfreev(s->secure_channels);
+ s->secure_channels = g_value_dup_boxed(value);
+ break;
+ case PROP_COLOR_DEPTH:
+ s->color_depth = g_value_get_int(value);
+ break;
+ case PROP_AUDIO:
+ s->audio = g_value_get_boolean(value);
+ break;
+ case PROP_READ_ONLY:
+ s->read_only = g_value_get_boolean(value);
+ g_coroutine_object_notify(gobject, "read-only");
+ break;
+ case PROP_CACHE_SIZE:
+ s->images_cache_size = g_value_get_int(value);
+ break;
+ case PROP_GLZ_WINDOW_SIZE:
+ s->glz_window_size = g_value_get_int(value);
+ break;
+ case PROP_CA:
+ g_clear_pointer(&s->ca, g_byte_array_unref);
+ s->ca = g_value_dup_boxed(value);
+ break;
+ case PROP_PROXY:
+ update_proxy(session, g_value_get_string(value));
+ break;
+ case PROP_SHARED_DIR:
+ spice_session_set_shared_dir(session, g_value_get_string(value));
+ break;
+ case PROP_SHARE_DIR_RO:
+ s->share_dir_ro = g_value_get_boolean(value);
+ break;
+ case PROP_PREF_COMPRESSION:
+ s->preferred_compression = g_value_get_enum(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_session_class_init(SpiceSessionClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+ _wocky_http_proxy_get_type();
+ _wocky_https_proxy_get_type();
+
+ gobject_class->dispose = spice_session_dispose;
+ gobject_class->finalize = spice_session_finalize;
+ gobject_class->get_property = spice_session_get_property;
+ gobject_class->set_property = spice_session_set_property;
+
+ /**
+ * SpiceSession:host:
+ *
+ * URL of the SPICE host to connect to
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_HOST,
+ g_param_spec_string("host",
+ "Host",
+ "Remote host",
+ "localhost",
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:unix-path:
+ *
+ * Path of the Unix socket to connect to
+ *
+ * Since: 0.28
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_UNIX_PATH,
+ g_param_spec_string("unix-path",
+ "Unix path",
+ "Unix path",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:port:
+ *
+ * Port to connect to for unencrypted sessions
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_PORT,
+ g_param_spec_string("port",
+ "Port",
+ "Remote port (plaintext)",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:tls-port:
+ *
+ * Port to connect to for TLS sessions
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_TLS_PORT,
+ g_param_spec_string("tls-port",
+ "TLS port",
+ "Remote port (encrypted)",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:username:
+ *
+ * Username to use
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_USERNAME,
+ g_param_spec_string("username",
+ "Username",
+ "Username used for SASL connections",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:password:
+ *
+ * TLS password to use
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_PASSWORD,
+ g_param_spec_string("password",
+ "Password",
+ "",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:ca-file:
+ *
+ * File holding the CA certificates for the host the client is
+ * connecting to
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_CA_FILE,
+ g_param_spec_string("ca-file",
+ "CA file",
+ "File holding the CA certificates",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:ciphers:
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_CIPHERS,
+ g_param_spec_string("ciphers",
+ "Ciphers",
+ "SSL cipher list",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:protocol:
+ *
+ * Version of the SPICE protocol to use
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_PROTOCOL,
+ g_param_spec_int("protocol",
+ "Protocol",
+ "Spice protocol major version",
+ 1, 2, 2,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:uri:
+ *
+ * URI of the SPICE host to connect to. The URI is of the form
+ * spice://hostname?port=XXX or spice://hostname?tls_port=XXX
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_URI,
+ g_param_spec_string("uri",
+ "URI",
+ "Spice connection URI",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:client-sockets:
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_CLIENT_SOCKETS,
+ g_param_spec_boolean("client-sockets",
+ "Client sockets",
+ "Sockets are provided by the client",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:pubkey:
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_PUBKEY,
+ g_param_spec_boxed("pubkey",
+ "Pub Key",
+ "Public key to check",
+ G_TYPE_BYTE_ARRAY,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:cert-subject:
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_CERT_SUBJECT,
+ g_param_spec_string("cert-subject",
+ "Cert Subject",
+ "Certificate subject to check",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:verify:
+ *
+ * #SpiceSessionVerify bit field indicating which parts of the peer
+ * certificate should be checked
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_VERIFY,
+ g_param_spec_flags("verify",
+ "Verify",
+ "Certificate verification parameters",
+ SPICE_TYPE_SESSION_VERIFY,
+ SPICE_SESSION_VERIFY_HOSTNAME,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:migration-state:
+ *
+ * #SpiceSessionMigration bit field indicating if a migration is in
+ * progress
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_MIGRATION_STATE,
+ g_param_spec_enum("migration-state",
+ "Migration state",
+ "Migration state",
+ SPICE_TYPE_SESSION_MIGRATION,
+ SPICE_SESSION_MIGRATION_NONE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:disable-effects:
+ *
+ * A string array of effects to disable. The settings will
+ * be applied on new display channels. The following effets can be
+ * disabled "wallpaper", "font-smooth", "animation", and "all",
+ * which will disable all the effects. If NULL, don't apply changes.
+ *
+ * Since: 0.7
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_DISABLE_EFFECTS,
+ g_param_spec_boxed ("disable-effects",
+ "Disable effects",
+ "Comma-separated effects to disable",
+ G_TYPE_STRV,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:color-depth:
+ *
+ * Display color depth to set on new display channels. If 0, don't set.
+ *
+ * Since: 0.7
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_COLOR_DEPTH,
+ g_param_spec_int("color-depth",
+ "Color depth",
+ "Display channel color depth",
+ 0, 32, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:enable-smartcard:
+ *
+ * If set to TRUE, the smartcard channel will be enabled and smartcard
+ * events will be forwarded to the guest
+ *
+ * Since: 0.7
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_SMARTCARD,
+ g_param_spec_boolean("enable-smartcard",
+ "Enable smartcard event forwarding",
+ "Forward smartcard events to the SPICE server",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:enable-audio:
+ *
+ * If set to TRUE, the audio channels will be enabled for
+ * playback and recording.
+ *
+ * Since: 0.8
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_AUDIO,
+ g_param_spec_boolean("enable-audio",
+ "Enable audio channels",
+ "Enable audio channels",
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:smartcard-certificates:
+ *
+ * This property is used when one wants to simulate a smartcard with no
+ * hardware smartcard reader. If it's set to a NULL-terminated string
+ * array containing the names of 3 valid certificates, these will be
+ * used to simulate a smartcard in the guest
+ * See also spice_smartcard_manager_insert_card()
+ *
+ * Since: 0.7
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_SMARTCARD_CERTIFICATES,
+ g_param_spec_boxed("smartcard-certificates",
+ "Smartcard certificates",
+ "Smartcard certificates for software-based smartcards",
+ G_TYPE_STRV,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:smartcard-db:
+ *
+ * Path to the NSS certificate database containing the certificates to
+ * use to simulate a software smartcard
+ *
+ * Since: 0.7
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_SMARTCARD_DB,
+ g_param_spec_string("smartcard-db",
+ "Smartcard certificate database",
+ "Path to the database for smartcard certificates",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:enable-usbredir:
+ *
+ * If set to TRUE, the usbredir channel will be enabled and USB devices
+ * can be redirected to the guest
+ *
+ * Since: 0.8
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_USBREDIR,
+ g_param_spec_boolean("enable-usbredir",
+ "Enable USB device redirection",
+ "Forward USB devices to the SPICE server",
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession::inhibit-keyboard-grab:
+ *
+ * This boolean is set by the usbredir channel to indicate to #SpiceDisplay
+ * that the keyboard grab should be temporarily released, because it is
+ * going to invoke policykit. It will get reset when the usbredir channel
+ * is done with polickit.
+ *
+ * Since: 0.8
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_INHIBIT_KEYBOARD_GRAB,
+ g_param_spec_boolean("inhibit-keyboard-grab",
+ "Inhibit Keyboard Grab",
+ "Request that SpiceDisplays don't grab the keyboard",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:ca:
+ *
+ * CA certificates in PEM format. The text data can contain
+ * several CA certificates identified by:
+ *
+ * -----BEGIN CERTIFICATE-----
+ * ... (CA certificate in base64 encoding) ...
+ * -----END CERTIFICATE-----
+ *
+ * Since: 0.15
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_CA,
+ g_param_spec_boxed("ca",
+ "CA",
+ "The CA certificates data",
+ G_TYPE_BYTE_ARRAY,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:secure-channels:
+ *
+ * A string array of channel types to be secured.
+ *
+ * Since: 0.20
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_SECURE_CHANNELS,
+ g_param_spec_boxed ("secure-channels",
+ "Secure channels",
+ "Array of channel type to secure",
+ G_TYPE_STRV,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+
+ /**
+ * SpiceSession::channel-new:
+ * @session: the session that emitted the signal
+ * @channel: the new #SpiceChannel
+ *
+ * The #SpiceSession::channel-new signal is emitted each time a #SpiceChannel is created.
+ **/
+ signals[SPICE_SESSION_CHANNEL_NEW] =
+ g_signal_new("channel-new",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceSessionClass, channel_new),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ SPICE_TYPE_CHANNEL);
+
+ /**
+ * SpiceSession::channel-destroy:
+ * @session: the session that emitted the signal
+ * @channel: the destroyed #SpiceChannel
+ *
+ * The #SpiceSession::channel-destroy signal is emitted each time a #SpiceChannel is destroyed.
+ **/
+ signals[SPICE_SESSION_CHANNEL_DESTROY] =
+ g_signal_new("channel-destroy",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceSessionClass, channel_destroy),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ SPICE_TYPE_CHANNEL);
+
+ /**
+ * SpiceSession::mm-time-reset:
+ * @session: the session that emitted the signal
+ *
+ * The #SpiceSession::mm-time-reset is emitted when we identify discontinuity in mm-time
+ *
+ * Since 0.20
+ **/
+ signals[SPICE_SESSION_MM_TIME_RESET] =
+ g_signal_new("mm-time-reset",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ /**
+ * SpiceSession:read-only:
+ *
+ * Whether this connection is read-only mode.
+ *
+ * Since: 0.8
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_READ_ONLY,
+ g_param_spec_boolean("read-only", "Read-only",
+ "Whether this connection is read-only mode",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:cache-size:
+ *
+ * Images cache size. If 0, don't set.
+ *
+ * Since: 0.9
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_CACHE_SIZE,
+ g_param_spec_int("cache-size",
+ "Cache size",
+ "Images cache size (bytes)",
+ 0, G_MAXINT, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:glz-window-size:
+ *
+ * Glz window size. If 0, don't set.
+ *
+ * Since: 0.9
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_GLZ_WINDOW_SIZE,
+ g_param_spec_int("glz-window-size",
+ "Glz window size",
+ "Glz window size (bytes)",
+ 0, LZ_MAX_WINDOW_SIZE * 4, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:name:
+ *
+ * Spice server name.
+ *
+ * Since: 0.11
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_NAME,
+ g_param_spec_string("name",
+ "Name",
+ "Spice server name",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:uuid:
+ *
+ * Spice server uuid.
+ *
+ * Since: 0.11
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_UUID,
+ g_param_spec_pointer("uuid",
+ "UUID",
+ "Spice server uuid",
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:proxy:
+ *
+ * URI to the proxy server to use when doing network connection.
+ * of the form <![CDATA[ [protocol://]<host>[:port] ]]>
+ *
+ * Since: 0.17
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_PROXY,
+ g_param_spec_string("proxy",
+ "Proxy",
+ "The proxy server",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:shared-dir:
+ *
+ * Location of the shared directory
+ *
+ * Since: 0.24
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_SHARED_DIR,
+ g_param_spec_string("shared-dir",
+ "Shared directory",
+ "Shared directory",
+ g_get_user_special_dir(G_USER_DIRECTORY_PUBLIC_SHARE),
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:share-dir-ro:
+ *
+ * Whether to share the directory read-only.
+ *
+ * Since: 0.28
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_SHARE_DIR_RO,
+ g_param_spec_boolean("share-dir-ro",
+ "Share directory read-only",
+ "Share directory read-only",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceSession:preferred-compression:
+ *
+ * The image compression algorithm the client prefers to use. It is
+ * reported to the server.
+ *
+ * Since: 0.29
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_PREF_COMPRESSION,
+ g_param_spec_enum("preferred-compression",
+ "Preferred image compression algorithm",
+ "Preferred image compression algorithm",
+ SPICE_TYPE_IMAGE_COMPRESSION,
+ SPICE_IMAGE_COMPRESSION_INVALID,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_type_class_add_private(klass, sizeof(SpiceSessionPrivate));
+}
+
+/* ------------------------------------------------------------------ */
+/* public functions */
+
+/**
+ * spice_session_new:
+ *
+ * Creates a new Spice session.
+ *
+ * Returns: a new #SpiceSession
+ **/
+SpiceSession *spice_session_new(void)
+{
+ return SPICE_SESSION(g_object_new(SPICE_TYPE_SESSION, NULL));
+}
+
+G_GNUC_INTERNAL
+SpiceSession *spice_session_new_from_session(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ SpiceSessionPrivate *s = session->priv;
+ SpiceSession *copy;
+ SpiceSessionPrivate *c;
+
+ if (s->client_provided_sockets) {
+ g_warning("migration with client provided fd is not supported yet");
+ return NULL;
+ }
+
+ copy = SPICE_SESSION(g_object_new(SPICE_TYPE_SESSION,
+ "host", NULL,
+ "ca-file", NULL,
+ NULL));
+ c = copy->priv;
+ g_clear_object(&c->proxy);
+
+ g_warn_if_fail(c->host == NULL);
+ g_warn_if_fail(c->unix_path == NULL);
+ g_warn_if_fail(c->tls_port == NULL);
+ g_warn_if_fail(c->username == NULL);
+ g_warn_if_fail(c->password == NULL);
+ g_warn_if_fail(c->ca_file == NULL);
+ g_warn_if_fail(c->ciphers == NULL);
+ g_warn_if_fail(c->cert_subject == NULL);
+ g_warn_if_fail(c->pubkey == NULL);
+ g_warn_if_fail(c->pubkey == NULL);
+ g_warn_if_fail(c->proxy == NULL);
+
+ g_object_get(session,
+ "host", &c->host,
+ "unix-path", &c->unix_path,
+ "tls-port", &c->tls_port,
+ "username", &c->username,
+ "password", &c->password,
+ "ca-file", &c->ca_file,
+ "ciphers", &c->ciphers,
+ "cert-subject", &c->cert_subject,
+ "pubkey", &c->pubkey,
+ "verify", &c->verify,
+ "smartcard-certificates", &c->smartcard_certificates,
+ "smartcard-db", &c->smartcard_db,
+ "enable-smartcard", &c->smartcard,
+ "enable-audio", &c->audio,
+ "enable-usbredir", &c->usbredir,
+ "ca", &c->ca,
+ NULL);
+
+ c->client_provided_sockets = s->client_provided_sockets;
+ c->protocol = s->protocol;
+ c->connection_id = s->connection_id;
+ if (s->proxy)
+ c->proxy = g_object_ref(s->proxy);
+
+ return copy;
+}
+
+/**
+ * spice_session_connect:
+ * @session: a #SpiceSession
+ *
+ * Open the session using the #SpiceSession:host and
+ * #SpiceSession:port.
+ *
+ * Returns: %FALSE if the session state is invalid for connection
+ * request. %TRUE if the connection is initiated. To know whether the
+ * connection is established, you must watch for channels creation
+ * (#SpiceSession::channel-new) and the channels state
+ * (#SpiceChannel::channel-event).
+ **/
+gboolean spice_session_connect(SpiceSession *session)
+{
+ SpiceSessionPrivate *s;
+
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
+ s = session->priv;
+ g_return_val_if_fail(!s->disconnecting, FALSE);
+
+ session_disconnect(session, TRUE);
+
+ s->client_provided_sockets = FALSE;
+
+ if (s->cmain == NULL)
+ s->cmain = spice_channel_new(session, SPICE_CHANNEL_MAIN, 0);
+
+ glz_decoder_window_clear(s->glz_window);
+ return spice_channel_connect(s->cmain);
+}
+
+/**
+ * spice_session_open_fd:
+ * @session: a #SpiceSession
+ * @fd: a file descriptor (socket) or -1
+ *
+ * Open the session using the provided @fd socket file
+ * descriptor. This is useful if you create the fd yourself, for
+ * example to setup a SSH tunnel.
+ *
+ * Note however that additional sockets will be needed by all the channels
+ * created for @session so users of this API should hook into
+ * SpiceChannel::open-fd signal for each channel they are interested in, and
+ * create and pass a new socket to the channel using #spice_channel_open_fd, in
+ * the signal callback.
+ *
+ * If @fd is -1, a valid fd will be requested later via the
+ * SpiceChannel::open-fd signal. Typically, you would want to just pass -1 as
+ * @fd this call since you will have to hook to SpiceChannel::open-fd signal
+ * anyway.
+ *
+ * Returns: %TRUE on success.
+ **/
+gboolean spice_session_open_fd(SpiceSession *session, int fd)
+{
+ SpiceSessionPrivate *s;
+
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+ g_return_val_if_fail(fd >= -1, FALSE);
+
+ s = session->priv;
+ g_return_val_if_fail(!s->disconnecting, FALSE);
+
+ session_disconnect(session, TRUE);
+
+ s->client_provided_sockets = TRUE;
+
+ if (s->cmain == NULL)
+ s->cmain = spice_channel_new(session, SPICE_CHANNEL_MAIN, 0);
+
+ glz_decoder_window_clear(s->glz_window);
+ return spice_channel_open_fd(s->cmain, fd);
+}
+
+G_GNUC_INTERNAL
+gboolean spice_session_get_client_provided_socket(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ return s->client_provided_sockets;
+}
+
+static void cache_clear_all(SpiceSession *self)
+{
+ SpiceSessionPrivate *s = self->priv;
+
+ cache_clear(s->images);
+ glz_decoder_window_clear(s->glz_window);
+}
+
+G_GNUC_INTERNAL
+void spice_session_switching_disconnect(SpiceSession *self)
+{
+ g_return_if_fail(SPICE_IS_SESSION(self));
+
+ SpiceSessionPrivate *s = self->priv;
+ struct channel *item;
+ RingItem *ring, *next;
+
+ g_return_if_fail(s->cmain != NULL);
+
+ /* disconnect/destroy all but main channel */
+
+ for (ring = ring_get_head(&s->channels); ring != NULL; ring = next) {
+ next = ring_next(&s->channels, ring);
+ item = SPICE_CONTAINEROF(ring, struct channel, link);
+
+ if (item->channel == s->cmain)
+ continue;
+ spice_session_channel_destroy(self, item->channel);
+ }
+
+ g_warn_if_fail(!ring_is_empty(&s->channels)); /* ring_get_length() == 1 */
+
+ cache_clear_all(self);
+ s->connection_id = 0;
+}
+
+#define SWAP_STR(x, y) G_STMT_START { \
+ const gchar *tmp; \
+ const gchar *a = x; \
+ const gchar *b = y; \
+ tmp = a; \
+ a = b; \
+ b = tmp; \
+} G_STMT_END
+
+G_GNUC_INTERNAL
+void spice_session_start_migrating(SpiceSession *session,
+ gboolean full_migration)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ SpiceSessionPrivate *s = session->priv;
+ SpiceSessionPrivate *m;
+
+ g_return_if_fail(s->migration != NULL);
+ m = s->migration->priv;
+ g_return_if_fail(m->migration_state == SPICE_SESSION_MIGRATION_CONNECTING);
+
+
+ s->full_migration = full_migration;
+ spice_session_set_migration_state(session, SPICE_SESSION_MIGRATION_MIGRATING);
+
+ /* swapping connection details happens after MIGRATION_CONNECTING state */
+ SWAP_STR(s->host, m->host);
+ SWAP_STR(s->port, m->port);
+ SWAP_STR(s->tls_port, m->tls_port);
+ SWAP_STR(s->unix_path, m->unix_path);
+
+ g_warn_if_fail(ring_get_length(&s->channels) == ring_get_length(&m->channels));
+
+ SPICE_DEBUG("migration channels left:%u (in migration:%u)",
+ ring_get_length(&s->channels), ring_get_length(&m->channels));
+ s->migration_left = spice_session_get_channels(session);
+}
+#undef SWAP_STR
+
+G_GNUC_INTERNAL
+SpiceChannel* spice_session_lookup_channel(SpiceSession *session, gint id, gint type)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ RingItem *ring, *next;
+ SpiceSessionPrivate *s = session->priv;
+ struct channel *c;
+
+ for (ring = ring_get_head(&s->channels);
+ ring != NULL; ring = next) {
+ next = ring_next(&s->channels, ring);
+ c = SPICE_CONTAINEROF(ring, struct channel, link);
+ if (c == NULL || c->channel == NULL) {
+ g_warn_if_reached();
+ continue;
+ }
+
+ if (id == spice_channel_get_channel_id(c->channel) &&
+ type == spice_channel_get_channel_type(c->channel))
+ break;
+ }
+ g_return_val_if_fail(ring != NULL, NULL);
+
+ return c->channel;
+}
+
+G_GNUC_INTERNAL
+void spice_session_abort_migration(SpiceSession *session)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ SpiceSessionPrivate *s = session->priv;
+ RingItem *ring, *next;
+ struct channel *c;
+
+ if (s->migration == NULL) {
+ SPICE_DEBUG("no migration in progress");
+ return;
+ }
+
+ SPICE_DEBUG("migration: abort");
+ if (s->migration_state != SPICE_SESSION_MIGRATION_MIGRATING)
+ goto end;
+
+ for (ring = ring_get_head(&s->channels);
+ ring != NULL; ring = next) {
+ next = ring_next(&s->channels, ring);
+ c = SPICE_CONTAINEROF(ring, struct channel, link);
+
+ if (g_list_find(s->migration_left, c->channel))
+ continue;
+
+ spice_channel_swap(c->channel,
+ spice_session_lookup_channel(s->migration,
+ spice_channel_get_channel_id(c->channel),
+ spice_channel_get_channel_type(c->channel)),
+ !s->full_migration);
+ }
+
+end:
+ g_clear_pointer(&s->migration_left, g_list_free);
+ session_disconnect(s->migration, FALSE);
+ g_clear_pointer(&s->migration, g_object_unref);
+
+ s->migrate_wait_init = FALSE;
+ if (s->after_main_init) {
+ g_source_remove(s->after_main_init);
+ s->after_main_init = 0;
+ }
+
+ spice_session_set_migration_state(session, SPICE_SESSION_MIGRATION_NONE);
+}
+
+G_GNUC_INTERNAL
+void spice_session_channel_migrate(SpiceSession *session, SpiceChannel *channel)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ SpiceSessionPrivate *s = session->priv;
+ SpiceChannel *c;
+ gint id, type;
+
+ g_return_if_fail(s->migration != NULL);
+ g_return_if_fail(SPICE_IS_CHANNEL(channel));
+
+ id = spice_channel_get_channel_id(channel);
+ type = spice_channel_get_channel_type(channel);
+ CHANNEL_DEBUG(channel, "migrating channel id:%d type:%d", id, type);
+
+ c = spice_session_lookup_channel(s->migration, id, type);
+ g_return_if_fail(c != NULL);
+
+ if (!g_queue_is_empty(&c->priv->xmit_queue) && s->full_migration) {
+ CHANNEL_DEBUG(channel, "mig channel xmit queue is not empty. type %s", c->priv->name);
+ }
+ spice_channel_swap(channel, c, !s->full_migration);
+ s->migration_left = g_list_remove(s->migration_left, channel);
+
+ if (g_list_length(s->migration_left) == 0) {
+ CHANNEL_DEBUG(channel, "migration: all channel migrated, success");
+ session_disconnect(s->migration, FALSE);
+ g_clear_pointer(&s->migration, g_object_unref);
+ spice_session_set_migration_state(session, SPICE_SESSION_MIGRATION_NONE);
+ }
+}
+
+/* main context */
+static gboolean after_main_init(gpointer data)
+{
+ SpiceSession *self = data;
+ SpiceSessionPrivate *s = self->priv;
+ GList *l;
+
+ for (l = s->migration_left; l != NULL; ) {
+ SpiceChannel *channel = l->data;
+ l = l->next;
+
+ spice_session_channel_migrate(self, channel);
+ channel->priv->state = SPICE_CHANNEL_STATE_READY;
+ spice_channel_up(channel);
+ }
+
+ s->after_main_init = 0;
+ return FALSE;
+}
+
+/* coroutine context */
+G_GNUC_INTERNAL
+gboolean spice_session_migrate_after_main_init(SpiceSession *self)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(self), FALSE);
+
+ SpiceSessionPrivate *s = self->priv;
+
+ if (!s->migrate_wait_init)
+ return FALSE;
+
+ g_return_val_if_fail(g_list_length(s->migration_left) != 0, FALSE);
+ g_return_val_if_fail(s->after_main_init == 0, FALSE);
+
+ s->migrate_wait_init = FALSE;
+ s->after_main_init = g_idle_add(after_main_init, self);
+
+ return TRUE;
+}
+
+/* main context */
+G_GNUC_INTERNAL
+void spice_session_migrate_end(SpiceSession *self)
+{
+ g_return_if_fail(SPICE_IS_SESSION(self));
+
+ SpiceSessionPrivate *s = self->priv;
+ SpiceMsgOut *out;
+ GList *l;
+
+ g_return_if_fail(s->migration);
+ g_return_if_fail(s->migration->priv->cmain);
+ g_return_if_fail(g_list_length(s->migration_left) != 0);
+
+ /* disconnect and reset all channels */
+ for (l = s->migration_left; l != NULL; ) {
+ SpiceChannel *channel = l->data;
+ l = l->next;
+
+ if (!SPICE_IS_MAIN_CHANNEL(channel)) {
+ /* freeze other channels */
+ channel->priv->state = SPICE_CHANNEL_STATE_MIGRATING;
+ }
+
+ /* reset for migration, disconnect */
+ spice_channel_reset(channel, TRUE);
+
+ if (SPICE_IS_MAIN_CHANNEL(channel)) {
+ /* migrate main to target, so we can start talking */
+ spice_session_channel_migrate(self, channel);
+ }
+ }
+
+ cache_clear_all(self);
+
+ /* send MIGRATE_END to target */
+ out = spice_msg_out_new(s->cmain, SPICE_MSGC_MAIN_MIGRATE_END);
+ spice_msg_out_send(out);
+
+ /* now wait after main init for the rest of channels migration */
+ s->migrate_wait_init = TRUE;
+}
+
+/**
+ * spice_session_get_read_only:
+ * @session: a #SpiceSession
+ *
+ * Checks whether the @session is read-only.
+ *
+ * Returns: whether the @session is in read-only mode.
+ **/
+gboolean spice_session_get_read_only(SpiceSession *self)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(self), FALSE);
+
+ return self->priv->read_only;
+}
+
+static gboolean session_disconnect_idle(SpiceSession *self)
+{
+ SpiceSessionPrivate *s = self->priv;
+
+ session_disconnect(self, FALSE);
+ s->disconnecting = 0;
+
+ g_object_unref(self);
+
+ return FALSE;
+}
+
+/**
+ * spice_session_disconnect:
+ * @session: a #SpiceSession
+ *
+ * Disconnect the @session, and destroy all channels.
+ **/
+void spice_session_disconnect(SpiceSession *session)
+{
+ SpiceSessionPrivate *s;
+
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ s = session->priv;
+
+ SPICE_DEBUG("session: disconnecting %u", s->disconnecting);
+ if (s->disconnecting != 0)
+ return;
+
+ g_object_ref(session);
+ s->disconnecting = g_idle_add((GSourceFunc)session_disconnect_idle, session);
+}
+
+/**
+ * spice_session_get_channels:
+ * @session: a #SpiceSession
+ *
+ * Get the list of current channels associated with this @session.
+ *
+ * Returns: (element-type SpiceChannel) (transfer container): a #GList
+ * of unowned #SpiceChannel channels.
+ **/
+GList *spice_session_get_channels(SpiceSession *session)
+{
+ SpiceSessionPrivate *s;
+ struct channel *item;
+ GList *list = NULL;
+ RingItem *ring;
+
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+ g_return_val_if_fail(session->priv != NULL, NULL);
+
+ s = session->priv;
+
+ for (ring = ring_get_head(&s->channels);
+ ring != NULL;
+ ring = ring_next(&s->channels, ring)) {
+ item = SPICE_CONTAINEROF(ring, struct channel, link);
+ list = g_list_append(list, item->channel);
+ }
+ return list;
+}
+
+/**
+ * spice_session_has_channel_type:
+ * @session: a #SpiceSession
+ * @type: a #SpiceChannel:channel-type
+ *
+ * See if there is a @type channel in the channels associated with this
+ * @session.
+ *
+ * Returns: TRUE if a @type channel is available otherwise FALSE.
+ **/
+gboolean spice_session_has_channel_type(SpiceSession *session, gint type)
+{
+ SpiceSessionPrivate *s;
+ struct channel *item;
+ RingItem *ring;
+
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+ g_return_val_if_fail(session->priv != NULL, FALSE);
+
+ s = session->priv;
+
+ for (ring = ring_get_head(&s->channels);
+ ring != NULL;
+ ring = ring_next(&s->channels, ring)) {
+ item = SPICE_CONTAINEROF(ring, struct channel, link);
+ if (spice_channel_get_channel_type(item->channel) == type) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* ------------------------------------------------------------------ */
+/* private functions */
+
+typedef struct spice_open_host spice_open_host;
+
+struct spice_open_host {
+ struct coroutine *from;
+ SpiceSession *session;
+ SpiceChannel *channel;
+ SpiceURI *proxy;
+ int port;
+ GCancellable *cancellable;
+ GError *error;
+ GSocketConnection *connection;
+ GSocketClient *client;
+};
+
+static void socket_client_connect_ready(GObject *source_object, GAsyncResult *result,
+ gpointer data)
+{
+ GSocketClient *client = G_SOCKET_CLIENT(source_object);
+ spice_open_host *open_host = data;
+ GSocketConnection *connection = NULL;
+
+ CHANNEL_DEBUG(open_host->channel, "connect ready");
+ connection = g_socket_client_connect_finish(client, result, &open_host->error);
+ if (connection == NULL) {
+ g_warn_if_fail(open_host->error != NULL);
+ goto end;
+ }
+
+ open_host->connection = connection;
+
+end:
+ coroutine_yieldto(open_host->from, NULL);
+}
+
+/* main context */
+static void open_host_connectable_connect(spice_open_host *open_host, GSocketConnectable *connectable)
+{
+ CHANNEL_DEBUG(open_host->channel, "connecting %p...", open_host);
+
+ g_socket_client_connect_async(open_host->client, connectable,
+ open_host->cancellable,
+ socket_client_connect_ready, open_host);
+}
+
+/* main context */
+static void proxy_lookup_ready(GObject *source_object, GAsyncResult *result,
+ gpointer data)
+{
+ spice_open_host *open_host = data;
+ SpiceSession *session = open_host->session;
+ SpiceSessionPrivate *s = session->priv;
+ GList *addresses = NULL, *it;
+ GSocketAddress *address;
+
+ SPICE_DEBUG("proxy lookup ready");
+ addresses = g_resolver_lookup_by_name_finish(G_RESOLVER(source_object),
+ result, &open_host->error);
+ if (addresses == NULL || open_host->error) {
+ g_prefix_error(&open_host->error, "SPICE proxy: ");
+ coroutine_yieldto(open_host->from, NULL);
+ return;
+ }
+
+ for (it = addresses; it != NULL; it = it->next) {
+ address = g_proxy_address_new(G_INET_ADDRESS(it->data),
+ spice_uri_get_port(open_host->proxy),
+ spice_uri_get_scheme(open_host->proxy),
+ s->host, open_host->port,
+ spice_uri_get_user(open_host->proxy),
+ spice_uri_get_password(open_host->proxy));
+ if (address != NULL)
+ break;
+ }
+
+ open_host_connectable_connect(open_host, G_SOCKET_CONNECTABLE(address));
+ g_resolver_free_addresses(addresses);
+ g_object_unref(address);
+}
+
+/* main context */
+static gboolean open_host_idle_cb(gpointer data)
+{
+ spice_open_host *open_host = data;
+ SpiceSessionPrivate *s;
+
+ g_return_val_if_fail(open_host != NULL, FALSE);
+ g_return_val_if_fail(open_host->connection == NULL, FALSE);
+
+ if (spice_channel_get_session(open_host->channel) != open_host->session)
+ return FALSE;
+
+ s = open_host->session->priv;
+ open_host->proxy = s->proxy;
+ if (open_host->error != NULL) {
+ coroutine_yieldto(open_host->from, NULL);
+ return FALSE;
+ }
+
+ if (open_host->proxy) {
+ g_resolver_lookup_by_name_async(g_resolver_get_default(),
+ spice_uri_get_hostname(open_host->proxy),
+ open_host->cancellable,
+ proxy_lookup_ready, open_host);
+ } else {
+ GSocketConnectable *address = NULL;
+
+ if (s->unix_path) {
+ SPICE_DEBUG("open unix path %s", s->unix_path);
+#ifdef G_OS_UNIX
+ address = G_SOCKET_CONNECTABLE(g_unix_socket_address_new(s->unix_path));
+#else
+ g_set_error_literal(&open_host->error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Unix path unsupported on this platform");
+#endif
+ } else {
+ SPICE_DEBUG("open host %s:%d", s->host, open_host->port);
+ address = g_network_address_parse(s->host, open_host->port, &open_host->error);
+ }
+
+ if (address == NULL || open_host->error != NULL) {
+ coroutine_yieldto(open_host->from, NULL);
+ return FALSE;
+ }
+
+ open_host_connectable_connect(open_host, address);
+ g_object_unref(address);
+ }
+
+ if (open_host->proxy != NULL) {
+ gchar *str = spice_uri_to_string(open_host->proxy);
+ SPICE_DEBUG("(with proxy %s)", str);
+ g_free(str);
+ }
+
+ return FALSE;
+}
+
+#define SOCKET_TIMEOUT 10
+
+/* coroutine context */
+G_GNUC_INTERNAL
+GSocketConnection* spice_session_channel_open_host(SpiceSession *session, SpiceChannel *channel,
+ gboolean *use_tls, GError **error)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ SpiceSessionPrivate *s = session->priv;
+ SpiceChannelPrivate *c = channel->priv;
+ spice_open_host open_host = { 0, };
+ gchar *port, *endptr;
+
+ // FIXME: make open_host() cancellable
+ open_host.from = coroutine_self();
+ open_host.session = session;
+ open_host.channel = channel;
+
+ const char *name = spice_channel_type_to_string(c->channel_type);
+ if (spice_strv_contains(s->secure_channels, "all") ||
+ spice_strv_contains(s->secure_channels, name))
+ *use_tls = TRUE;
+
+ if (s->unix_path) {
+ if (*use_tls) {
+ CHANNEL_DEBUG(channel, "No TLS for Unix sockets");
+ return NULL;
+ }
+ } else {
+ port = *use_tls ? s->tls_port : s->port;
+ if (port == NULL) {
+ SPICE_DEBUG("Missing port value, not attempting %s connection.",
+ *use_tls?"TLS":"unencrypted");
+ return NULL;
+ }
+
+ open_host.port = strtol(port, &endptr, 10);
+ if (*port == '\0' || *endptr != '\0' ||
+ open_host.port <= 0 || open_host.port > G_MAXUINT16) {
+ g_warning("Invalid port value %s", port);
+ return NULL;
+ }
+ }
+ if (*use_tls) {
+ CHANNEL_DEBUG(channel, "Using TLS, port %d", open_host.port);
+ } else {
+ CHANNEL_DEBUG(channel, "Using plain text, port %d", open_host.port);
+ }
+
+ open_host.client = g_socket_client_new();
+ g_socket_client_set_enable_proxy(open_host.client, s->proxy != NULL);
+ g_socket_client_set_timeout(open_host.client, SOCKET_TIMEOUT);
+
+ g_idle_add(open_host_idle_cb, &open_host);
+ /* switch to main loop and wait for connection */
+ coroutine_yield(NULL);
+
+ if (open_host.error != NULL) {
+ CHANNEL_DEBUG(channel, "open host: %s", open_host.error->message);
+ g_propagate_error(error, open_host.error);
+ } else if (open_host.connection != NULL) {
+ GSocket *socket;
+ socket = g_socket_connection_get_socket(open_host.connection);
+ g_socket_set_timeout(socket, 0);
+ g_socket_set_blocking(socket, FALSE);
+ g_socket_set_keepalive(socket, TRUE);
+ }
+
+ g_clear_object(&open_host.client);
+ return open_host.connection;
+}
+
+
+G_GNUC_INTERNAL
+void spice_session_channel_new(SpiceSession *session, SpiceChannel *channel)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+ g_return_if_fail(SPICE_IS_CHANNEL(channel));
+
+ SpiceSessionPrivate *s = session->priv;
+ struct channel *item;
+
+
+ item = g_new0(struct channel, 1);
+ item->channel = channel;
+ ring_add(&s->channels, &item->link);
+
+ if (SPICE_IS_MAIN_CHANNEL(channel)) {
+ gboolean all = spice_strv_contains(s->disable_effects, "all");
+
+ g_object_set(channel,
+ "disable-wallpaper", all || spice_strv_contains(s->disable_effects, "wallpaper"),
+ "disable-font-smooth", all || spice_strv_contains(s->disable_effects, "font-smooth"),
+ "disable-animation", all || spice_strv_contains(s->disable_effects, "animation"),
+ NULL);
+ if (s->color_depth != 0)
+ g_object_set(channel, "color-depth", s->color_depth, NULL);
+
+ CHANNEL_DEBUG(channel, "new main channel, switching");
+ s->cmain = channel;
+ } else if (SPICE_IS_PLAYBACK_CHANNEL(channel)) {
+ g_warn_if_fail(s->playback_channel == NULL);
+ s->playback_channel = SPICE_PLAYBACK_CHANNEL(channel);
+ }
+
+ g_signal_emit(session, signals[SPICE_SESSION_CHANNEL_NEW], 0, channel);
+}
+
+static void spice_session_channel_destroy(SpiceSession *session, SpiceChannel *channel)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+ g_return_if_fail(SPICE_IS_CHANNEL(channel));
+
+ SpiceSessionPrivate *s = session->priv;
+ struct channel *item = NULL;
+ RingItem *ring;
+
+ if (s->migration_left)
+ s->migration_left = g_list_remove(s->migration_left, channel);
+
+ for (ring = ring_get_head(&s->channels); ring != NULL;
+ ring = ring_next(&s->channels, ring)) {
+ item = SPICE_CONTAINEROF(ring, struct channel, link);
+ if (item->channel == channel)
+ break;
+ }
+
+ g_return_if_fail(ring != NULL);
+
+ if (channel == s->cmain) {
+ CHANNEL_DEBUG(channel, "the session lost the main channel");
+ s->cmain = NULL;
+ }
+
+ ring_remove(&item->link);
+ free(item);
+
+ g_signal_emit(session, signals[SPICE_SESSION_CHANNEL_DESTROY], 0, channel);
+
+ g_clear_object(&channel->priv->session);
+ spice_channel_disconnect(channel, SPICE_CHANNEL_NONE);
+ g_object_unref(channel);
+}
+
+G_GNUC_INTERNAL
+void spice_session_set_connection_id(SpiceSession *session, int id)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ SpiceSessionPrivate *s = session->priv;
+
+ s->connection_id = id;
+}
+
+G_GNUC_INTERNAL
+int spice_session_get_connection_id(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), -1);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ return s->connection_id;
+}
+
+G_GNUC_INTERNAL
+guint32 spice_session_get_mm_time(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), 0);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ /* FIXME: we may want to estimate the drift of clocks, and well,
+ do something better than this trivial approach */
+ return s->mm_time + (g_get_monotonic_time() - s->mm_time_at_clock) / 1000;
+}
+
+#define MM_TIME_DIFF_RESET_THRESH 500 // 0.5 sec
+
+G_GNUC_INTERNAL
+void spice_session_set_mm_time(SpiceSession *session, guint32 time)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ SpiceSessionPrivate *s = session->priv;
+ guint32 old_time;
+
+ old_time = spice_session_get_mm_time(session);
+
+ s->mm_time = time;
+ s->mm_time_at_clock = g_get_monotonic_time();
+ SPICE_DEBUG("set mm time: %u", spice_session_get_mm_time(session));
+ if (time > old_time + MM_TIME_DIFF_RESET_THRESH ||
+ time < old_time) {
+ SPICE_DEBUG("%s: mm-time-reset, old %u, new %u", __FUNCTION__, old_time, s->mm_time);
+ g_coroutine_signal_emit(session, signals[SPICE_SESSION_MM_TIME_RESET], 0);
+ }
+}
+
+G_GNUC_INTERNAL
+void spice_session_set_port(SpiceSession *session, int port, gboolean tls)
+{
+ const char *prop = tls ? "tls-port" : "port";
+ char *tmp;
+
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ /* old spicec client doesn't accept port == 0, see Migrate::start */
+ tmp = port > 0 ? g_strdup_printf("%d", port) : NULL;
+ g_object_set(session, prop, tmp, NULL);
+ g_free(tmp);
+}
+
+G_GNUC_INTERNAL
+void spice_session_get_pubkey(SpiceSession *session, guint8 **pubkey, guint *size)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+ g_return_if_fail(pubkey != NULL);
+ g_return_if_fail(size != NULL);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ *pubkey = s->pubkey ? s->pubkey->data : NULL;
+ *size = s->pubkey ? s->pubkey->len : 0;
+}
+
+G_GNUC_INTERNAL
+void spice_session_get_ca(SpiceSession *session, guint8 **ca, guint *size)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+ g_return_if_fail(ca != NULL);
+ g_return_if_fail(size != NULL);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ *ca = s->ca ? s->ca->data : NULL;
+ *size = s->ca ? s->ca->len : 0;
+}
+
+G_GNUC_INTERNAL
+guint spice_session_get_verify(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), 0);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ return s->verify;
+}
+
+G_GNUC_INTERNAL
+void spice_session_set_migration_state(SpiceSession *session, SpiceSessionMigration state)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ SpiceSessionPrivate *s = session->priv;
+
+ if (state == SPICE_SESSION_MIGRATION_CONNECTING)
+ s->for_migration = true;
+
+ s->migration_state = state;
+ g_coroutine_object_notify(G_OBJECT(session), "migration-state");
+}
+
+G_GNUC_INTERNAL
+const gchar* spice_session_get_username(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ return s->username;
+}
+
+G_GNUC_INTERNAL
+const gchar* spice_session_get_password(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ return s->password;
+}
+
+G_GNUC_INTERNAL
+const gchar* spice_session_get_host(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ return s->host;
+}
+
+G_GNUC_INTERNAL
+const gchar* spice_session_get_cert_subject(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ return s->cert_subject;
+}
+
+G_GNUC_INTERNAL
+const gchar* spice_session_get_ciphers(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ return s->ciphers;
+}
+
+G_GNUC_INTERNAL
+const gchar* spice_session_get_ca_file(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ return s->ca_file;
+}
+
+G_GNUC_INTERNAL
+void spice_session_get_caches(SpiceSession *session,
+ display_cache **images,
+ SpiceGlzDecoderWindow **glz_window)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ SpiceSessionPrivate *s = session->priv;
+
+ if (images)
+ *images = s->images;
+ if (glz_window)
+ *glz_window = s->glz_window;
+}
+
+G_GNUC_INTERNAL
+void spice_session_set_caches_hints(SpiceSession *session,
+ uint32_t pci_ram_size,
+ uint32_t n_display_channels)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ SpiceSessionPrivate *s = session->priv;
+
+ s->pci_ram_size = pci_ram_size;
+ s->n_display_channels = n_display_channels;
+
+ /* TODO: when setting cache and window size, we should consider the client's
+ * available memory and the number of display channels */
+ if (s->images_cache_size == 0) {
+ s->images_cache_size = IMAGES_CACHE_SIZE_DEFAULT;
+ }
+
+ if (s->glz_window_size == 0) {
+ s->glz_window_size = MIN(MAX_GLZ_WINDOW_SIZE_DEFAULT, pci_ram_size / 2);
+ s->glz_window_size = MAX(MIN_GLZ_WINDOW_SIZE_DEFAULT, s->glz_window_size);
+ }
+}
+
+G_GNUC_INTERNAL
+guint spice_session_get_n_display_channels(SpiceSession *session)
+{
+ g_return_val_if_fail(session != NULL, 0);
+
+ return session->priv->n_display_channels;
+}
+
+G_GNUC_INTERNAL
+void spice_session_set_uuid(SpiceSession *session, guint8 uuid[16])
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ SpiceSessionPrivate *s = session->priv;
+
+ memcpy(s->uuid, uuid, sizeof(s->uuid));
+
+ g_coroutine_object_notify(G_OBJECT(session), "uuid");
+}
+
+G_GNUC_INTERNAL
+void spice_session_set_name(SpiceSession *session, const gchar *name)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ SpiceSessionPrivate *s = session->priv;
+
+ g_free(s->name);
+ s->name = g_strdup(name);
+
+ g_coroutine_object_notify(G_OBJECT(session), "name");
+}
+
+G_GNUC_INTERNAL
+void spice_session_sync_playback_latency(SpiceSession *session)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ SpiceSessionPrivate *s = session->priv;
+
+ if (s->playback_channel &&
+ spice_playback_channel_is_active(s->playback_channel)) {
+ spice_playback_channel_sync_latency(s->playback_channel);
+ } else {
+ SPICE_DEBUG("%s: not implemented when there isn't audio playback", __FUNCTION__);
+ }
+}
+
+G_GNUC_INTERNAL
+gboolean spice_session_is_playback_active(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ return (s->playback_channel &&
+ spice_playback_channel_is_active(s->playback_channel));
+}
+
+G_GNUC_INTERNAL
+guint32 spice_session_get_playback_latency(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), 0);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ if (s->playback_channel &&
+ spice_playback_channel_is_active(s->playback_channel)) {
+ return spice_playback_channel_get_latency(s->playback_channel);
+ } else {
+ SPICE_DEBUG("%s: not implemented when there isn't audio playback", __FUNCTION__);
+ return 0;
+ }
+}
+
+G_GNUC_INTERNAL
+const gchar* spice_session_get_shared_dir(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ SpiceSessionPrivate *s = session->priv;
+
+ return s->shared_dir;
+}
+
+G_GNUC_INTERNAL
+void spice_session_set_shared_dir(SpiceSession *session, const gchar *dir)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+
+ SpiceSessionPrivate *s = session->priv;
+
+ g_free(s->shared_dir);
+ s->shared_dir = g_strdup(dir);
+}
+
+/**
+ * spice_session_get_proxy_uri:
+ * @session: a #SpiceSession
+ *
+ * Gets the @session proxy uri.
+ *
+ * Returns: (transfer none): the session proxy #SpiceURI or %NULL.
+ * Since: 0.24
+ **/
+SpiceURI *spice_session_get_proxy_uri(SpiceSession *session)
+{
+ SpiceSessionPrivate *s;
+
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+ g_return_val_if_fail(session->priv != NULL, NULL);
+
+ s = session->priv;
+
+ return s->proxy;
+}
+
+/**
+ * spice_audio_get:
+ * @session: the #SpiceSession to connect to
+ * @context: (allow-none): a #GMainContext to attach to (or %NULL for default).
+ *
+ * Gets the #SpiceAudio associated with the passed in #SpiceSession.
+ * A new #SpiceAudio instance will be created the first time this
+ * function is called for a certain #SpiceSession.
+ *
+ * Note that this function returns a weak reference, which should not be used
+ * after the #SpiceSession itself has been unref-ed by the caller.
+ *
+ * Returns: (transfer none): a weak reference to a #SpiceAudio
+ * instance or %NULL if failed.
+ **/
+SpiceAudio *spice_audio_get(SpiceSession *session, GMainContext *context)
+{
+ static GMutex mutex;
+ SpiceAudio *self;
+
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+
+ g_mutex_lock(&mutex);
+ self = session->priv->audio_manager;
+ if (self == NULL) {
+ self = spice_audio_new(session, context, NULL);
+ session->priv->audio_manager = self;
+ }
+ g_mutex_unlock(&mutex);
+
+ return self;
+}
+
+/**
+ * spice_usb_device_manager_get:
+ * @session: #SpiceSession for which to get the #SpiceUsbDeviceManager
+ * @err: (allow-none): a return location for #GError, or %NULL.
+ *
+ * Gets the #SpiceUsbDeviceManager associated with the passed in #SpiceSession.
+ * A new #SpiceUsbDeviceManager instance will be created the first time this
+ * function is called for a certain #SpiceSession.
+ *
+ * Note that this function returns a weak reference, which should not be used
+ * after the #SpiceSession itself has been unref-ed by the caller.
+ *
+ * Returns: (transfer none): a weak reference to the #SpiceUsbDeviceManager associated with the passed in #SpiceSession
+ */
+SpiceUsbDeviceManager *spice_usb_device_manager_get(SpiceSession *session,
+ GError **err)
+{
+ SpiceUsbDeviceManager *self;
+ static GMutex mutex;
+
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+ g_return_val_if_fail(err == NULL || *err == NULL, NULL);
+
+ g_mutex_lock(&mutex);
+ self = session->priv->usb_manager;
+ if (self == NULL) {
+ self = g_initable_new(SPICE_TYPE_USB_DEVICE_MANAGER, NULL, err,
+ "session", session, NULL);
+ session->priv->usb_manager = self;
+ }
+ g_mutex_unlock(&mutex);
+
+ return self;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_session_get_audio_enabled(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
+ return session->priv->audio;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_session_get_usbredir_enabled(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
+ return session->priv->usbredir;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_session_get_smartcard_enabled(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
+ return session->priv->smartcard;
+}
+
+G_GNUC_INTERNAL
+PhodavServer* spice_session_get_webdav_server(SpiceSession *session)
+{
+ SpiceSessionPrivate *priv;
+
+ g_return_val_if_fail(SPICE_IS_SESSION(session), NULL);
+ priv = session->priv;
+
+#ifdef USE_PHODAV
+ static GMutex mutex;
+
+ const gchar *shared_dir = spice_session_get_shared_dir(session);
+ if (shared_dir == NULL) {
+ SPICE_DEBUG("No shared dir set, not creating webdav server");
+ return NULL;
+ }
+
+ g_mutex_lock(&mutex);
+
+ if (priv->webdav)
+ goto end;
+
+ priv->webdav = phodav_server_new(shared_dir);
+ g_object_bind_property(session, "share-dir-ro",
+ priv->webdav, "read-only",
+ G_BINDING_SYNC_CREATE|G_BINDING_BIDIRECTIONAL);
+ g_object_bind_property(session, "shared-dir",
+ priv->webdav, "root",
+ G_BINDING_SYNC_CREATE|G_BINDING_BIDIRECTIONAL);
+
+end:
+ g_mutex_unlock(&mutex);
+#endif
+
+ return priv->webdav;
+}
+
+/**
+ * spice_session_is_for_migration:
+ * @session: a Spice session
+ *
+ * During seamless migration, channels may be created to establish a
+ * connection with the target, but they are temporary and should only
+ * handle migration steps. In order to avoid other interactions with
+ * the client, channels should check this value.
+ *
+ * Returns: %TRUE if the session is a copy created during migration
+ * Since: 0.27
+ **/
+gboolean spice_session_is_for_migration(SpiceSession *session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+
+ return session->priv->for_migration;
+}
+
+G_GNUC_INTERNAL
+void spice_session_set_main_channel(SpiceSession *session, SpiceChannel *channel)
+{
+ g_return_if_fail(SPICE_IS_SESSION(session));
+ g_return_if_fail(SPICE_IS_CHANNEL(channel));
+ g_return_if_fail(session->priv->cmain == NULL);
+
+ session->priv->cmain = channel;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_session_set_migration_session(SpiceSession *session, SpiceSession *mig_session)
+{
+ g_return_val_if_fail(SPICE_IS_SESSION(session), FALSE);
+ g_return_val_if_fail(SPICE_IS_SESSION(mig_session), FALSE);
+ g_return_val_if_fail(session->priv->migration == NULL, FALSE);
+
+ session->priv->migration = mig_session;
+
+ return TRUE;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_SESSION_H__
+#define __SPICE_CLIENT_SESSION_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include <glib-object.h>
+#include "spice-types.h"
+#include "spice-uri.h"
+#include "spice-glib-enums.h"
+#include "spice-util.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_SESSION (spice_session_get_type ())
+#define SPICE_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_SESSION, SpiceSession))
+#define SPICE_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_SESSION, SpiceSessionClass))
+#define SPICE_IS_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_SESSION))
+#define SPICE_IS_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_SESSION))
+#define SPICE_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_SESSION, SpiceSessionClass))
+
+/**
+ * SpiceSessionVerify:
+ * @SPICE_SESSION_VERIFY_PUBKEY: verify certificate public key matching
+ * @SPICE_SESSION_VERIFY_HOSTNAME: verify certificate hostname matching
+ * @SPICE_SESSION_VERIFY_SUBJECT: verify certificate subject matching
+ *
+ * Peer certificate verification parameters flags.
+ **/
+typedef enum {
+ SPICE_SESSION_VERIFY_PUBKEY = (1 << 0),
+ SPICE_SESSION_VERIFY_HOSTNAME = (1 << 1),
+ SPICE_SESSION_VERIFY_SUBJECT = (1 << 2),
+} SpiceSessionVerify;
+
+/**
+ * SpiceSessionMigration:
+ * @SPICE_SESSION_MIGRATION_NONE: no migration going on
+ * @SPICE_SESSION_MIGRATION_SWITCHING: the session is switching host (destroy and reconnect)
+ * @SPICE_SESSION_MIGRATION_MIGRATING: the session is migrating seamlessly (reconnect)
+ * @SPICE_SESSION_MIGRATION_CONNECTING: the migration is connecting to destination (Since: 0.27)
+ *
+ * Session migration state.
+ **/
+typedef enum {
+ SPICE_SESSION_MIGRATION_NONE,
+ SPICE_SESSION_MIGRATION_SWITCHING,
+ SPICE_SESSION_MIGRATION_MIGRATING,
+ SPICE_SESSION_MIGRATION_CONNECTING,
+} SpiceSessionMigration;
+
+/**
+ * SpiceSession:
+ *
+ * The #SpiceSession struct is opaque and should not be accessed directly.
+ */
+struct _SpiceSession
+{
+ GObject parent;
+ SpiceSessionPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpiceSessionClass:
+ * @parent_class: Parent class.
+ * @channel_new: Signal class handler for the #SpiceSession::channel_new signal.
+ * @channel_destroy: Signal class handler for the #SpiceSession::channel_destroy signal.
+ *
+ * Class structure for #SpiceSession.
+ */
+struct _SpiceSessionClass
+{
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*channel_new)(SpiceSession *session, SpiceChannel *channel);
+ void (*channel_destroy)(SpiceSession *session, SpiceChannel *channel);
+
+ /*< private >*/
+ /*
+ * If adding fields to this struct, remove corresponding
+ * amount of padding to avoid changing overall struct size
+ */
+ gchar _spice_reserved[SPICE_RESERVED_PADDING];
+};
+
+GType spice_session_get_type(void);
+
+SpiceSession *spice_session_new(void);
+gboolean spice_session_connect(SpiceSession *session);
+gboolean spice_session_open_fd(SpiceSession *session, int fd);
+void spice_session_disconnect(SpiceSession *session);
+GList *spice_session_get_channels(SpiceSession *session);
+gboolean spice_session_has_channel_type(SpiceSession *session, gint type);
+gboolean spice_session_get_read_only(SpiceSession *session);
+SpiceURI *spice_session_get_proxy_uri(SpiceSession *session);
+gboolean spice_session_is_for_migration(SpiceSession *session);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_SESSION_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_TYPES_H__
+#define __SPICE_CLIENT_TYPES_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+G_BEGIN_DECLS
+
+/* SpiceSession */
+typedef struct _SpiceSession SpiceSession;
+typedef struct _SpiceSessionClass SpiceSessionClass;
+typedef struct _SpiceSessionPrivate SpiceSessionPrivate;
+
+/* SpiceChannel */
+typedef struct _SpiceChannel SpiceChannel;
+typedef struct _SpiceChannelClass SpiceChannelClass;
+typedef struct _SpiceChannelPrivate SpiceChannelPrivate;
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_TYPES_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_URI_PRIV_H__
+#define __SPICE_URI_PRIV_H__
+
+#include "spice-uri.h"
+
+G_BEGIN_DECLS
+
+SpiceURI* spice_uri_new(void);
+gboolean spice_uri_parse(SpiceURI* self, const gchar* uri, GError** error);
+
+G_END_DECLS
+
+#endif /* __SPICE_URI_PRIV_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "spice-client.h"
+#include "spice-uri.h"
+#include "spice-uri-priv.h"
+
+/**
+ * SECTION:spice-uri
+ * @short_description: URIs handling
+ * @title: SpiceURI
+ * @section_id:
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * A SpiceURI represents a (parsed) URI.
+ * Since: 0.24
+ */
+
+struct _SpiceURI {
+ GObject parent_instance;
+ gchar *scheme;
+ gchar *hostname;
+ guint port;
+ gchar *user;
+ gchar *password;
+};
+
+struct _SpiceURIClass {
+ GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE(SpiceURI, spice_uri, G_TYPE_OBJECT);
+
+enum {
+ SPICE_URI_DUMMY_PROPERTY,
+ SPICE_URI_SCHEME,
+ SPICE_URI_USER,
+ SPICE_URI_PASSWORD,
+ SPICE_URI_HOSTNAME,
+ SPICE_URI_PORT
+};
+
+#ifndef HAVE_STRTOK_R
+static char *strtok_r(char *s, const char *delim, char **save_ptr)
+{
+ char *token;
+
+ if (s == NULL)
+ s = *save_ptr;
+
+ /* Scan leading delimiters. */
+ s += strspn (s, delim);
+ if (*s == '\0')
+ return NULL;
+
+ /* Find the end of the token. */
+ token = s;
+ s = strpbrk (token, delim);
+ if (s == NULL)
+ /* This token finishes the string. */
+ *save_ptr = strchr (token, '\0');
+ else
+ {
+ /* Terminate the token and make *SAVE_PTR point past it. */
+ *s = '\0';
+ *save_ptr = s + 1;
+ }
+ return token;
+}
+#endif
+
+G_GNUC_INTERNAL
+SpiceURI* spice_uri_new(void)
+{
+ SpiceURI * self = NULL;
+ self = (SpiceURI*)g_object_new(SPICE_TYPE_URI, NULL);
+ return self;
+}
+
+static void spice_uri_reset(SpiceURI *self)
+{
+ g_clear_pointer(&self->scheme, g_free);
+ g_clear_pointer(&self->hostname, g_free);
+ g_clear_pointer(&self->user, g_free);
+ g_clear_pointer(&self->password, g_free);
+ self->port = 0;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error)
+{
+ gchar *dup, *uri, **uriv = NULL;
+ const gchar *uri_port = NULL;
+ char *uri_scheme = NULL;
+ gboolean success = FALSE;
+ size_t len;
+
+ g_return_val_if_fail(self != NULL, FALSE);
+
+ spice_uri_reset(self);
+
+ g_return_val_if_fail(_uri != NULL, FALSE);
+
+ uri = dup = g_strdup(_uri);
+ /* FIXME: use GUri when it is ready... only support http atm */
+ /* the code is voluntarily not parsing thoroughly the uri */
+ uri_scheme = g_uri_parse_scheme(uri);
+ if (uri_scheme == NULL) {
+ spice_uri_set_scheme(self, "http");
+ } else {
+ spice_uri_set_scheme(self, uri_scheme);
+ uri += strlen(uri_scheme) + 3; /* scheme + "://" */
+ }
+ if (g_ascii_strcasecmp(spice_uri_get_scheme(self), "http") == 0) {
+ spice_uri_set_port(self, 3128);
+ } else if (g_ascii_strcasecmp(spice_uri_get_scheme(self), "https") == 0) {
+ spice_uri_set_port(self, 3129);
+ } else {
+ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Invalid uri scheme for proxy: %s", spice_uri_get_scheme(self));
+ goto end;
+ }
+ /* remove trailing slash */
+ len = strlen(uri);
+ for (; len > 0; len--)
+ if (uri[len-1] == '/')
+ uri[len-1] = '\0';
+ else
+ break;
+
+
+ /* yes, that parser is bad, we need GUri... */
+ if (strstr(uri, "@")) {
+ gchar *saveptr = NULL, *saveptr2 = NULL;
+ gchar *next = strstr(uri, "@") + 1;
+ gchar *auth = strtok_r(uri, "@", &saveptr);
+ const gchar *user = strtok_r(auth, ":", &saveptr2);
+ const gchar *pass = strtok_r(NULL, ":", &saveptr2);
+ spice_uri_set_user(self, user);
+ spice_uri_set_password(self, pass);
+ uri = next;
+ }
+
+ if (*uri == '[') { /* ipv6 address */
+ uriv = g_strsplit(uri + 1, "]", 2);
+ if (uriv[1] == NULL) {
+ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Missing ']' in ipv6 uri");
+ goto end;
+ }
+ if (*uriv[1] == ':') {
+ uri_port = uriv[1] + 1;
+ } else if (strlen(uriv[1]) > 0) { /* invalid string after the hostname */
+ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Invalid uri address");
+ goto end;
+ }
+ } else {
+ /* max 2 parts, host:port */
+ uriv = g_strsplit(uri, ":", 2);
+ if (uriv[0] != NULL)
+ uri_port = uriv[1];
+ }
+
+ if (uriv[0] == NULL || strlen(uriv[0]) == 0) {
+ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Invalid hostname in uri address");
+ goto end;
+ }
+
+ spice_uri_set_hostname(self, uriv[0]);
+
+ if (uri_port != NULL) {
+ gchar *endptr;
+ gint64 port = g_ascii_strtoll(uri_port, &endptr, 10);
+ if (*endptr != '\0') {
+ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Invalid uri port: %s", uri_port);
+ goto end;
+ } else if (endptr == uri_port) {
+ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, "Missing uri port");
+ goto end;
+ }
+ if (port <= 0 || port > 65535) {
+ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED, "Port out of range");
+ goto end;
+ }
+ spice_uri_set_port(self, port);
+ }
+
+ success = TRUE;
+
+end:
+ free(uri_scheme);
+ g_free(dup);
+ g_strfreev(uriv);
+ return success;
+}
+
+/**
+ * spice_uri_get_scheme:
+ * @uri: a #SpiceURI
+ *
+ * Gets @uri's scheme.
+ *
+ * Returns: @uri's scheme.
+ * Since: 0.24
+ **/
+const gchar* spice_uri_get_scheme(SpiceURI *self)
+{
+ g_return_val_if_fail(SPICE_IS_URI(self), NULL);
+ return self->scheme;
+}
+
+/**
+ * spice_uri_set_scheme:
+ * @uri: a #SpiceURI
+ * @scheme: the scheme
+ *
+ * Sets @uri's scheme to @scheme.
+ * Since: 0.24
+ **/
+void spice_uri_set_scheme(SpiceURI *self, const gchar *scheme)
+{
+ g_return_if_fail(SPICE_IS_URI(self));
+
+ g_free(self->scheme);
+ self->scheme = g_strdup(scheme);
+ g_object_notify((GObject *)self, "scheme");
+}
+
+/**
+ * spice_uri_get_hostname:
+ * @uri: a #SpiceURI
+ *
+ * Gets @uri's hostname.
+ *
+ * Returns: @uri's hostname.
+ * Since: 0.24
+ **/
+const gchar* spice_uri_get_hostname(SpiceURI *self)
+{
+ g_return_val_if_fail(SPICE_IS_URI(self), NULL);
+ return self->hostname;
+}
+
+
+/**
+ * spice_uri_set_hostname:
+ * @uri: a #SpiceURI
+ * @hostname: the hostname
+ *
+ * Sets @uri's hostname to @hostname.
+ * Since: 0.24
+ **/
+void spice_uri_set_hostname(SpiceURI *self, const gchar *hostname)
+{
+ g_return_if_fail(SPICE_IS_URI(self));
+
+ g_free(self->hostname);
+ self->hostname = g_strdup(hostname);
+ g_object_notify((GObject *)self, "hostname");
+}
+
+/**
+ * spice_uri_get_port:
+ * @uri: a #SpiceURI
+ *
+ * Gets @uri's port.
+ *
+ * Returns: @uri's port.
+ * Since: 0.24
+ **/
+guint spice_uri_get_port(SpiceURI *self)
+{
+ g_return_val_if_fail(SPICE_IS_URI(self), 0);
+ return self->port;
+}
+
+/**
+ * spice_uri_set_port:
+ * @uri: a #SpiceURI
+ * @port: the port
+ *
+ * Sets @uri's port to @port.
+ * Since: 0.24
+ **/
+void spice_uri_set_port(SpiceURI *self, guint port)
+{
+ g_return_if_fail(SPICE_IS_URI(self));
+ self->port = port;
+ g_object_notify((GObject *)self, "port");
+}
+
+static void spice_uri_get_property(GObject *object, guint property_id,
+ GValue *value, GParamSpec *pspec)
+{
+ SpiceURI *self;
+ self = G_TYPE_CHECK_INSTANCE_CAST(object, SPICE_TYPE_URI, SpiceURI);
+
+ switch (property_id) {
+ case SPICE_URI_SCHEME:
+ g_value_set_string(value, spice_uri_get_scheme(self));
+ break;
+ case SPICE_URI_HOSTNAME:
+ g_value_set_string(value, spice_uri_get_hostname(self));
+ break;
+ case SPICE_URI_PORT:
+ g_value_set_uint(value, spice_uri_get_port(self));
+ break;
+ case SPICE_URI_USER:
+ g_value_set_string(value, spice_uri_get_user(self));
+ break;
+ case SPICE_URI_PASSWORD:
+ g_value_set_string(value, spice_uri_get_password(self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void spice_uri_set_property(GObject *object, guint property_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ SpiceURI * self;
+ self = G_TYPE_CHECK_INSTANCE_CAST(object, SPICE_TYPE_URI, SpiceURI);
+
+ switch (property_id) {
+ case SPICE_URI_SCHEME:
+ spice_uri_set_scheme(self, g_value_get_string(value));
+ break;
+ case SPICE_URI_HOSTNAME:
+ spice_uri_set_hostname(self, g_value_get_string(value));
+ break;
+ case SPICE_URI_USER:
+ spice_uri_set_user(self, g_value_get_string(value));
+ break;
+ case SPICE_URI_PASSWORD:
+ spice_uri_set_password(self, g_value_get_string(value));
+ break;
+ case SPICE_URI_PORT:
+ spice_uri_set_port(self, g_value_get_uint(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void spice_uri_finalize(GObject* obj)
+{
+ SpiceURI *self;
+
+ self = G_TYPE_CHECK_INSTANCE_CAST(obj, SPICE_TYPE_URI, SpiceURI);
+ spice_uri_reset(self);
+
+ G_OBJECT_CLASS (spice_uri_parent_class)->finalize (obj);
+}
+
+static void spice_uri_init (SpiceURI *self G_GNUC_UNUSED)
+{
+}
+
+
+static void spice_uri_class_init(SpiceURIClass *klass)
+{
+ spice_uri_parent_class = g_type_class_peek_parent (klass);
+
+ G_OBJECT_CLASS (klass)->get_property = spice_uri_get_property;
+ G_OBJECT_CLASS (klass)->set_property = spice_uri_set_property;
+ G_OBJECT_CLASS (klass)->finalize = spice_uri_finalize;
+
+ g_object_class_install_property(G_OBJECT_CLASS (klass),
+ SPICE_URI_SCHEME,
+ g_param_spec_string ("scheme",
+ "scheme",
+ "scheme",
+ NULL,
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(G_OBJECT_CLASS (klass),
+ SPICE_URI_HOSTNAME,
+ g_param_spec_string ("hostname",
+ "hostname",
+ "hostname",
+ NULL,
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(G_OBJECT_CLASS (klass),
+ SPICE_URI_PORT,
+ g_param_spec_uint ("port",
+ "port",
+ "port",
+ 0, G_MAXUINT, 0,
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(G_OBJECT_CLASS (klass),
+ SPICE_URI_USER,
+ g_param_spec_string ("user",
+ "user",
+ "user",
+ NULL,
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(G_OBJECT_CLASS (klass),
+ SPICE_URI_PASSWORD,
+ g_param_spec_string ("password",
+ "password",
+ "password",
+ NULL,
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_READWRITE));
+}
+
+/**
+ * spice_uri_to_string:
+ * @uri: a #SpiceURI
+ *
+ * Returns a string representing @uri.
+ *
+ * Returns: a string representing @uri, which the caller must free.
+ * Since: 0.24
+ **/
+gchar* spice_uri_to_string(SpiceURI* self)
+{
+ g_return_val_if_fail(SPICE_IS_URI(self), NULL);
+
+ if (self->scheme == NULL || self->hostname == NULL)
+ return NULL;
+
+ if (self->user || self->password)
+ return g_strdup_printf("%s://%s:%s@%s:%u",
+ self->scheme,
+ self->user, self->password,
+ self->hostname, self->port);
+ else
+ return g_strdup_printf("%s://%s:%u",
+ self->scheme, self->hostname, self->port);
+}
+
+/**
+ * spice_uri_get_user:
+ * @uri: a #SpiceURI
+ *
+ * Gets @uri's user.
+ *
+ * Returns: @uri's user.
+ * Since: 0.24
+ **/
+const gchar* spice_uri_get_user(SpiceURI *self)
+{
+ g_return_val_if_fail(SPICE_IS_URI(self), NULL);
+ return self->user;
+}
+
+/**
+ * spice_uri_set_user:
+ * @uri: a #SpiceURI
+ * @user: the user, or %NULL.
+ *
+ * Sets @uri's user to @user.
+ * Since: 0.24
+ **/
+void spice_uri_set_user(SpiceURI *self, const gchar *user)
+{
+ g_return_if_fail(SPICE_IS_URI(self));
+
+ g_free(self->user);
+ self->user = g_strdup(user);
+ g_object_notify((GObject *)self, "user");
+}
+
+/**
+ * spice_uri_get_password:
+ * @uri: a #SpiceURI
+ *
+ * Gets @uri's password.
+ *
+ * Returns: @uri's password.
+ * Since: 0.24
+ **/
+const gchar* spice_uri_get_password(SpiceURI *self)
+{
+ g_return_val_if_fail(SPICE_IS_URI(self), NULL);
+ return self->password;
+}
+
+/**
+ * spice_uri_set_password:
+ * @uri: a #SpiceURI
+ * @password: the password, or %NULL.
+ *
+ * Sets @uri's password to @password.
+ * Since: 0.24
+ **/
+void spice_uri_set_password(SpiceURI *self, const gchar *password)
+{
+ g_return_if_fail(SPICE_IS_URI(self));
+
+ g_free(self->password);
+ self->password = g_strdup(password);
+ g_object_notify((GObject *)self, "password");
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_URI_H__
+#define __SPICE_URI_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_URI (spice_uri_get_type ())
+#define SPICE_URI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_URI, SpiceURI))
+#define SPICE_URI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_URI, SpiceURIClass))
+#define SPICE_IS_URI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_URI))
+#define SPICE_IS_URI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_URI))
+#define SPICE_URI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_URI, SpiceURIClass))
+
+/**
+ * SpiceURI:
+ *
+ * The #SpiceURI struct is opaque and cannot be accessed directly.
+ */
+typedef struct _SpiceURI SpiceURI;
+
+/**
+ * SpiceURIClass:
+ *
+ * The #SpiceURIClass struct is opaque and cannot be accessed directly.
+ * It is class structure for #SpiceURI.
+ */
+typedef struct _SpiceURIClass SpiceURIClass;
+typedef struct _SpiceURIPrivate SpiceURIPrivate;
+
+GType spice_uri_get_type(void) G_GNUC_CONST;
+
+const gchar* spice_uri_get_scheme(SpiceURI* uri);
+void spice_uri_set_scheme(SpiceURI* uri, const gchar* scheme);
+const gchar* spice_uri_get_hostname(SpiceURI* uri);
+void spice_uri_set_hostname(SpiceURI* uri, const gchar* hostname);
+guint spice_uri_get_port(SpiceURI* uri);
+void spice_uri_set_port(SpiceURI* uri, guint port);
+gchar *spice_uri_to_string(SpiceURI* uri);
+const gchar* spice_uri_get_user(SpiceURI* uri);
+void spice_uri_set_user(SpiceURI* uri, const gchar* user);
+const gchar* spice_uri_get_password(SpiceURI* uri);
+void spice_uri_set_password(SpiceURI* uri, const gchar* password);
+
+G_END_DECLS
+
+#endif /* __SPICE_URI_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef SPICE_UTIL_PRIV_H
+#define SPICE_UTIL_PRIV_H
+
+#include <glib.h>
+#include "spice-util.h"
+
+G_BEGIN_DECLS
+
+#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
+
+gboolean spice_strv_contains(const GStrv strv, const gchar *str);
+const gchar* spice_yes_no(gboolean value);
+guint16 spice_make_scancode(guint scancode, gboolean release);
+gchar* spice_unix2dos(const gchar *str, gssize len);
+gchar* spice_dos2unix(const gchar *str, gssize len);
+void spice_mono_edge_highlight(unsigned width, unsigned hight,
+ const guint8 *and, const guint8 *xor, guint8 *dest);
+
+G_END_DECLS
+
+#endif /* SPICE_UTIL_PRIV_H */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+ Copyright © 2006-2010 Collabora Ltd. <http://www.collabora.co.uk/>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <spice/macros.h>
+#include "spice-util-priv.h"
+#include "spice-util.h"
+#include "spice-util-priv.h"
+
+/**
+ * SECTION:spice-util
+ * @short_description: version and debugging functions
+ * @title: Utilities
+ * @section_id:
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * Various functions for debugging and informational purposes.
+ */
+
+static GOnce debug_once = G_ONCE_INIT;
+
+static void spice_util_enable_debug_messages(void)
+{
+ const gchar *doms = g_getenv("G_MESSAGES_DEBUG");
+ if (!doms) {
+ g_setenv("G_MESSAGES_DEBUG", G_LOG_DOMAIN, 1);
+ } else if (g_str_equal(doms, "all")) {
+ return;
+ } else if (!strstr(doms, G_LOG_DOMAIN)) {
+ gchar *newdoms = g_strdup_printf("%s %s", doms, G_LOG_DOMAIN);
+ g_setenv("G_MESSAGES_DEBUG", newdoms, 1);
+ g_free(newdoms);
+ }
+}
+
+/**
+ * spice_util_set_debug:
+ * @enabled: %TRUE or %FALSE
+ *
+ * Enable or disable Spice-GTK debugging messages.
+ **/
+void spice_util_set_debug(gboolean enabled)
+{
+ /* Make sure debug_once has been initialised
+ * with the value of SPICE_DEBUG already, otherwise
+ * spice_util_get_debug() may overwrite the value
+ * that was just set using spice_util_set_debug()
+ */
+ spice_util_get_debug();
+
+ if (enabled) {
+ spice_util_enable_debug_messages();
+ }
+
+ debug_once.retval = GINT_TO_POINTER(enabled);
+}
+
+static gpointer getenv_debug(gpointer data)
+{
+ gboolean debug;
+
+ debug = (g_getenv("SPICE_DEBUG") != NULL);
+ if (debug)
+ spice_util_enable_debug_messages();
+
+ return GINT_TO_POINTER(debug);
+}
+
+gboolean spice_util_get_debug(void)
+{
+ g_once(&debug_once, getenv_debug, NULL);
+
+ return GPOINTER_TO_INT(debug_once.retval);
+}
+
+/**
+ * spice_util_get_version_string:
+ *
+ * Gets the version string
+ *
+ * Returns: Spice-GTK version as a const string.
+ **/
+const gchar *spice_util_get_version_string(void)
+{
+ return VERSION;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_strv_contains(const GStrv strv, const gchar *str)
+{
+ int i;
+
+ if (strv == NULL)
+ return FALSE;
+
+ for (i = 0; strv[i] != NULL; i++)
+ if (g_str_equal(strv[i], str))
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
+ * spice_uuid_to_string:
+ * @uuid: UUID byte array
+ *
+ * Creates a string representation of @uuid, of the form
+ * "06e023d5-86d8-420e-8103-383e4566087a"
+ *
+ * Returns: A string that should be freed with g_free().
+ * Since: 0.22
+ **/
+gchar* spice_uuid_to_string(const guint8 uuid[16])
+{
+ return g_strdup_printf(UUID_FMT, uuid[0], uuid[1],
+ uuid[2], uuid[3], uuid[4], uuid[5],
+ uuid[6], uuid[7], uuid[8], uuid[9],
+ uuid[10], uuid[11], uuid[12], uuid[13],
+ uuid[14], uuid[15]);
+}
+
+typedef struct {
+ GObject *instance;
+ GObject *observer;
+ GClosure *closure;
+ gulong handler_id;
+} WeakHandlerCtx;
+
+static WeakHandlerCtx *
+whc_new (GObject *instance,
+ GObject *observer)
+{
+ WeakHandlerCtx *ctx = g_new0 (WeakHandlerCtx, 1);
+
+ ctx->instance = instance;
+ ctx->observer = observer;
+
+ return ctx;
+}
+
+static void
+whc_free (WeakHandlerCtx *ctx)
+{
+ g_free (ctx);
+}
+
+static void observer_destroyed_cb (gpointer, GObject *);
+static void closure_invalidated_cb (gpointer, GClosure *);
+
+/*
+ * If signal handlers are removed before the object is destroyed, this
+ * callback will never get triggered.
+ */
+static void
+instance_destroyed_cb (gpointer ctx_,
+ GObject *where_the_instance_was)
+{
+ WeakHandlerCtx *ctx = ctx_;
+
+ /* No need to disconnect the signal here, the instance has gone away. */
+ g_object_weak_unref (ctx->observer, observer_destroyed_cb, ctx);
+ g_closure_remove_invalidate_notifier (ctx->closure, ctx,
+ closure_invalidated_cb);
+ whc_free (ctx);
+}
+
+/* Triggered when the observer is destroyed. */
+static void
+observer_destroyed_cb (gpointer ctx_,
+ GObject *where_the_observer_was)
+{
+ WeakHandlerCtx *ctx = ctx_;
+
+ g_closure_remove_invalidate_notifier (ctx->closure, ctx,
+ closure_invalidated_cb);
+ g_signal_handler_disconnect (ctx->instance, ctx->handler_id);
+ g_object_weak_unref (ctx->instance, instance_destroyed_cb, ctx);
+ whc_free (ctx);
+}
+
+/* Triggered when either object is destroyed or the handler is disconnected. */
+static void
+closure_invalidated_cb (gpointer ctx_,
+ GClosure *where_the_closure_was)
+{
+ WeakHandlerCtx *ctx = ctx_;
+
+ g_object_weak_unref (ctx->instance, instance_destroyed_cb, ctx);
+ g_object_weak_unref (ctx->observer, observer_destroyed_cb, ctx);
+ whc_free (ctx);
+}
+
+/* Copied from tp_g_signal_connect_object. See documentation. */
+/**
+ * spice_g_signal_connect_object: (skip)
+ * @instance: the instance to connect to.
+ * @detailed_signal: a string of the form "signal-name::detail".
+ * @c_handler: the #GCallback to connect.
+ * @gobject: the object to pass as data to @c_handler.
+ * @connect_flags: a combination of #GConnectFlags.
+ *
+ * Similar to g_signal_connect_object() but will delete connection
+ * when any of the objects is destroyed.
+ *
+ * Returns: the handler id.
+ */
+gulong spice_g_signal_connect_object (gpointer instance,
+ const gchar *detailed_signal,
+ GCallback c_handler,
+ gpointer gobject,
+ GConnectFlags connect_flags)
+{
+ GObject *instance_obj = G_OBJECT (instance);
+ WeakHandlerCtx *ctx = whc_new (instance_obj, gobject);
+
+ g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
+ g_return_val_if_fail (detailed_signal != NULL, 0);
+ g_return_val_if_fail (c_handler != NULL, 0);
+ g_return_val_if_fail (G_IS_OBJECT (gobject), 0);
+ g_return_val_if_fail (
+ (connect_flags & ~(G_CONNECT_AFTER|G_CONNECT_SWAPPED)) == 0, 0);
+
+ if (connect_flags & G_CONNECT_SWAPPED)
+ ctx->closure = g_cclosure_new_object_swap (c_handler, gobject);
+ else
+ ctx->closure = g_cclosure_new_object (c_handler, gobject);
+
+ ctx->handler_id = g_signal_connect_closure (instance, detailed_signal,
+ ctx->closure, (connect_flags & G_CONNECT_AFTER) ? TRUE : FALSE);
+
+ g_object_weak_ref (instance_obj, instance_destroyed_cb, ctx);
+ g_object_weak_ref (gobject, observer_destroyed_cb, ctx);
+ g_closure_add_invalidate_notifier (ctx->closure, ctx,
+ closure_invalidated_cb);
+
+ return ctx->handler_id;
+}
+
+G_GNUC_INTERNAL
+const gchar* spice_yes_no(gboolean value)
+{
+ return value ? "yes" : "no";
+}
+
+G_GNUC_INTERNAL
+guint16 spice_make_scancode(guint scancode, gboolean release)
+{
+ SPICE_DEBUG("%s: %s scancode %u",
+ __FUNCTION__, release ? "release" : "", scancode);
+
+ scancode &= 0x37f;
+ if (release)
+ scancode |= 0x80;
+ if (scancode < 0x100)
+ return scancode;
+ return SPICE_BYTESWAP16(0xe000 | (scancode - 0x100));
+}
+
+typedef enum {
+ NEWLINE_TYPE_LF,
+ NEWLINE_TYPE_CR_LF
+} NewlineType;
+
+static gssize get_line(const gchar *str, gsize len,
+ NewlineType type, gsize *nl_len)
+{
+ const gchar *p, *endl;
+ gsize nl = 0;
+
+ endl = (type == NEWLINE_TYPE_CR_LF) ? "\r\n" : "\n";
+ p = g_strstr_len(str, len, endl);
+ if (p) {
+ len = p - str;
+ nl = strlen(endl);
+ }
+
+ *nl_len = nl;
+ return len;
+}
+
+
+static gchar* spice_convert_newlines(const gchar *str, gssize len,
+ NewlineType from,
+ NewlineType to)
+{
+ gssize length;
+ gsize nl;
+ GString *output;
+ gint i;
+
+ g_return_val_if_fail(str != NULL, NULL);
+ g_return_val_if_fail(len >= -1, NULL);
+ /* only 2 supported combinations */
+ g_return_val_if_fail((from == NEWLINE_TYPE_LF &&
+ to == NEWLINE_TYPE_CR_LF) ||
+ (from == NEWLINE_TYPE_CR_LF &&
+ to == NEWLINE_TYPE_LF), NULL);
+
+ if (len == -1)
+ len = strlen(str);
+ /* sometime we get \0 terminated strings, skip that, or it fails
+ to utf8 validate line with \0 end */
+ else if (len > 0 && str[len-1] == 0)
+ len -= 1;
+
+ /* allocate worst case, if it's small enough, we don't care much,
+ * if it's big, malloc will put us in mmap'd region, and we can
+ * over allocate.
+ */
+ output = g_string_sized_new(len * 2 + 1);
+
+ for (i = 0; i < len; i += length + nl) {
+ length = get_line(str + i, len - i, from, &nl);
+ if (length < 0)
+ break;
+
+ g_string_append_len(output, str + i, length);
+
+ if (nl) {
+ /* let's not double \r if it's already in the line */
+ if (to == NEWLINE_TYPE_CR_LF &&
+ (output->len == 0 || output->str[output->len - 1] != '\r'))
+ g_string_append_c(output, '\r');
+
+ g_string_append_c(output, '\n');
+ }
+ }
+
+ return g_string_free(output, FALSE);
+}
+
+G_GNUC_INTERNAL
+gchar* spice_dos2unix(const gchar *str, gssize len)
+{
+ return spice_convert_newlines(str, len,
+ NEWLINE_TYPE_CR_LF,
+ NEWLINE_TYPE_LF);
+}
+
+G_GNUC_INTERNAL
+gchar* spice_unix2dos(const gchar *str, gssize len)
+{
+ return spice_convert_newlines(str, len,
+ NEWLINE_TYPE_LF,
+ NEWLINE_TYPE_CR_LF);
+}
+
+static bool buf_is_ones(unsigned size, const guint8 *data)
+{
+ int i;
+
+ for (i = 0 ; i < size; ++i) {
+ if (data[i] != 0xff) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool is_edge_helper(const guint8 *xor, int bpl, int x, int y)
+{
+ return (xor[bpl * y + (x / 8)] & (0x80 >> (x % 8))) > 0;
+}
+
+static bool is_edge(unsigned width, unsigned height, const guint8 *xor, int bpl, int x, int y)
+{
+ if (x == 0 || x == width -1 || y == 0 || y == height - 1) {
+ return 0;
+ }
+#define P(x, y) is_edge_helper(xor, bpl, x, y)
+ return !P(x, y) && (P(x - 1, y + 1) || P(x, y + 1) || P(x + 1, y + 1) ||
+ P(x - 1, y) || P(x + 1, y) ||
+ P(x - 1, y - 1) || P(x, y - 1) || P(x + 1, y - 1));
+#undef P
+}
+
+/* Mono cursors have two places, "and" and "xor". If a bit is 1 in both, it
+ * means invertion of the corresponding pixel in the display. Since X11 (and
+ * gdk) doesn't do invertion, instead we do edge detection and turn the
+ * sorrounding edge pixels black, and the invert-me pixels white. To
+ * illustrate:
+ *
+ * and xor dest RGB (1=0xffffff, 0=0x000000)
+ *
+ * dest alpha (1=0xff, 0=0x00)
+ *
+ * 11111 00000 00000 00000
+ * 11111 00000 00000 01110
+ * 11111 00100 => 00100 01110
+ * 11111 00100 00100 01110
+ * 11111 00000 00000 01110
+ * 11111 00000 00000 00000
+ *
+ * See tests/util.c for more tests
+ *
+ * Notes:
+ * Assumes width >= 8 (i.e. bytes per line is at least 1)
+ * Assumes edges are not on the boundary (first/last line/column) for simplicity
+ *
+ */
+G_GNUC_INTERNAL
+void spice_mono_edge_highlight(unsigned width, unsigned height,
+ const guint8 *and, const guint8 *xor, guint8 *dest)
+{
+ int bpl = (width + 7) / 8;
+ bool and_ones = buf_is_ones(height * bpl, and);
+ int x, y, bit;
+ const guint8 *xor_base = xor;
+
+ for (y = 0; y < height; y++) {
+ bit = 0x80;
+ for (x = 0; x < width; x++, dest += 4) {
+ if (is_edge(width, height, xor_base, bpl, x, y) && and_ones) {
+ dest[0] = 0x00;
+ dest[1] = 0x00;
+ dest[2] = 0x00;
+ dest[3] = 0xff;
+ goto next_bit;
+ }
+ if (and[x/8] & bit) {
+ if (xor[x/8] & bit) {
+ dest[0] = 0xff;
+ dest[1] = 0xff;
+ dest[2] = 0xff;
+ dest[3] = 0xff;
+ } else {
+ /* unchanged -> transparent */
+ dest[0] = 0x00;
+ dest[1] = 0x00;
+ dest[2] = 0x00;
+ dest[3] = 0x00;
+ }
+ } else {
+ if (xor[x/8] & bit) {
+ /* set -> white */
+ dest[0] = 0xff;
+ dest[1] = 0xff;
+ dest[2] = 0xff;
+ dest[3] = 0xff;
+ } else {
+ /* clear -> black */
+ dest[0] = 0x00;
+ dest[1] = 0x00;
+ dest[2] = 0x00;
+ dest[3] = 0xff;
+ }
+ }
+ next_bit:
+ bit >>= 1;
+ if (bit == 0) {
+ bit = 0x80;
+ }
+ }
+ and += bpl;
+ xor += bpl;
+ }
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef SPICE_UTIL_H
+#define SPICE_UTIL_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void spice_util_set_debug(gboolean enabled);
+gboolean spice_util_get_debug(void);
+const gchar *spice_util_get_version_string(void);
+gulong spice_g_signal_connect_object(gpointer instance,
+ const gchar *detailed_signal,
+ GCallback c_handler,
+ gpointer gobject,
+ GConnectFlags connect_flags);
+gchar* spice_uuid_to_string(const guint8 uuid[16]);
+
+#define SPICE_DEBUG(fmt, ...) \
+ do { \
+ if (G_UNLIKELY(spice_util_get_debug())) \
+ g_debug(G_STRLOC " " fmt, ## __VA_ARGS__); \
+ } while (0)
+
+#define SPICE_RESERVED_PADDING (10 * sizeof(void*))
+
+/* need to be in a public header */
+#ifndef SPICE_GNUC_DEPRECATED_FOR
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#define SPICE_GNUC_DEPRECATED_FOR(f) \
+ __attribute__((deprecated("Use " #f " instead")))
+#else
+#define SPICE_GNUC_DEPRECATED_FOR(f) G_GNUC_DEPRECATED
+#endif /* __GNUC__ */
+#endif
+
+#ifndef SPICE_NO_DEPRECATED
+#define SPICE_DEPRECATED_FOR(f) SPICE_GNUC_DEPRECATED_FOR(f)
+#define SPICE_DEPRECATED G_GNUC_DEPRECATED
+#else
+#define SPICE_DEPRECATED_FOR(f)
+#define SPICE_DEPRECATED
+#endif
+
+G_END_DECLS
+
+#endif /* SPICE_UTIL_H */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2014 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_VERSION_H__
+#define __SPICE_VERSION_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+/**
+ * SECTION:spice-version
+ * @short_description: Spice-Gtk version checking
+ * @title: Version Information
+ * @include: spice-version.h
+ *
+ * Spice-Gtk provides macros to check the version of the library
+ * at compile-time
+ */
+
+/**
+ * SPICE_GTK_MAJOR_VERSION:
+ *
+ * Spice-Gtk major version component (e.g. 1 if version is 1.2.3)
+ * Since: 0.24
+ */
+#define SPICE_GTK_MAJOR_VERSION (0)
+
+/**
+ * SPICE_GTK_MINOR_VERSION:
+ *
+ * Spice-Gtk minor version component (e.g. 2 if version is 1.2.3)
+ * Since: 0.24
+ */
+#define SPICE_GTK_MINOR_VERSION (33)
+
+/**
+ * SPICE_GTK_MICRO_VERSION:
+ *
+ * Spice-Gtk micro version component (e.g. 3 if version is 1.2.3)
+ * Since: 0.24
+ */
+#define SPICE_GTK_MICRO_VERSION (0)
+
+/**
+ * SPICE_GTK_CHECK_VERSION:
+ * @major: required major version
+ * @minor: required minor version
+ * @micro: required micro version
+ *
+ * Compile-time version checking. Evaluates to %TRUE if the version
+ * of Spice-Gtk is greater than the required one.
+ * Since: 0.24
+ */
+#define SPICE_GTK_CHECK_VERSION(major, minor, micro) \
+ (SPICE_GTK_MAJOR_VERSION > (major) || \
+ (SPICE_GTK_MAJOR_VERSION == (major) && SPICE_GTK_MINOR_VERSION > (minor)) || \
+ (SPICE_GTK_MAJOR_VERSION == (major) && SPICE_GTK_MINOR_VERSION == (minor) && \
+ SPICE_GTK_MICRO_VERSION >= (micro)))
+
+
+#endif /* __SPICE_VERSION_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2014 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_VERSION_H__
+#define __SPICE_VERSION_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+/**
+ * SECTION:spice-version
+ * @short_description: Spice-Gtk version checking
+ * @title: Version Information
+ * @include: spice-version.h
+ *
+ * Spice-Gtk provides macros to check the version of the library
+ * at compile-time
+ */
+
+/**
+ * SPICE_GTK_MAJOR_VERSION:
+ *
+ * Spice-Gtk major version component (e.g. 1 if version is 1.2.3)
+ * Since: 0.24
+ */
+#define SPICE_GTK_MAJOR_VERSION (@SPICE_GTK_MAJOR_VERSION@)
+
+/**
+ * SPICE_GTK_MINOR_VERSION:
+ *
+ * Spice-Gtk minor version component (e.g. 2 if version is 1.2.3)
+ * Since: 0.24
+ */
+#define SPICE_GTK_MINOR_VERSION (@SPICE_GTK_MINOR_VERSION@)
+
+/**
+ * SPICE_GTK_MICRO_VERSION:
+ *
+ * Spice-Gtk micro version component (e.g. 3 if version is 1.2.3)
+ * Since: 0.24
+ */
+#define SPICE_GTK_MICRO_VERSION (@SPICE_GTK_MICRO_VERSION@)
+
+/**
+ * SPICE_GTK_CHECK_VERSION:
+ * @major: required major version
+ * @minor: required minor version
+ * @micro: required micro version
+ *
+ * Compile-time version checking. Evaluates to %TRUE if the version
+ * of Spice-Gtk is greater than the required one.
+ * Since: 0.24
+ */
+#define SPICE_GTK_CHECK_VERSION(major, minor, micro) \
+ (SPICE_GTK_MAJOR_VERSION > (major) || \
+ (SPICE_GTK_MAJOR_VERSION == (major) && SPICE_GTK_MINOR_VERSION > (minor)) || \
+ (SPICE_GTK_MAJOR_VERSION == (major) && SPICE_GTK_MINOR_VERSION == (minor) && \
+ SPICE_GTK_MICRO_VERSION >= (micro)))
+
+
+#endif /* __SPICE_VERSION_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-widget.h"
+#include "spice-widget-priv.h"
+#include "spice-gtk-session-priv.h"
+
+
+G_GNUC_INTERNAL
+int spice_cairo_image_create(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+
+ if (d->canvas.surface != NULL)
+ return 0;
+
+ if (d->canvas.format == SPICE_SURFACE_FMT_16_555 ||
+ d->canvas.format == SPICE_SURFACE_FMT_16_565) {
+ d->canvas.convert = TRUE;
+ d->canvas.data = g_malloc0(d->area.width * d->area.height * 4);
+
+ d->canvas.surface = cairo_image_surface_create_for_data
+ (d->canvas.data, CAIRO_FORMAT_RGB24,
+ d->area.width, d->area.height, d->area.width * 4);
+
+ } else {
+ d->canvas.convert = FALSE;
+
+ d->canvas.surface = cairo_image_surface_create_for_data
+ (d->canvas.data, CAIRO_FORMAT_RGB24,
+ d->canvas.width, d->canvas.height, d->canvas.stride);
+ }
+
+ return 0;
+}
+
+G_GNUC_INTERNAL
+void spice_cairo_image_destroy(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+
+ g_clear_pointer(&d->canvas.surface, cairo_surface_destroy);
+ if (d->canvas.convert)
+ g_clear_pointer(&d->canvas.data, g_free);
+ d->canvas.convert = FALSE;
+}
+
+G_GNUC_INTERNAL
+void spice_cairo_draw_event(SpiceDisplay *display, cairo_t *cr)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ cairo_rectangle_int_t rect;
+ cairo_region_t *region;
+ double s;
+ int x, y;
+ int ww, wh;
+ int w, h;
+
+ spice_display_get_scaling(display, &s, &x, &y, &w, &h);
+
+ ww = gtk_widget_get_allocated_width(GTK_WIDGET(display));
+ wh = gtk_widget_get_allocated_height(GTK_WIDGET(display));
+
+ /* We need to paint the bg color around the image */
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = ww;
+ rect.height = wh;
+ region = cairo_region_create_rectangle(&rect);
+
+ /* Optionally cut out the inner area where the pixmap
+ will be drawn. This avoids 'flashing' since we're
+ not double-buffering. */
+ if (d->canvas.surface) {
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ cairo_region_subtract_rectangle(region, &rect);
+ }
+
+ gdk_cairo_region (cr, region);
+ cairo_region_destroy (region);
+
+ /* Need to set a real solid color, because the default is usually
+ transparent these days, and non-double buffered windows can't
+ render transparently */
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ cairo_fill(cr);
+
+ /* Draw the display */
+ if (d->canvas.surface) {
+ cairo_translate(cr, x, y);
+ cairo_rectangle(cr, 0, 0, w, h);
+ cairo_scale(cr, s, s);
+ if (!d->canvas.convert)
+ cairo_translate(cr, -d->area.x, -d->area.y);
+ cairo_set_source_surface(cr, d->canvas.surface, 0, 0);
+ cairo_fill(cr);
+
+ if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER &&
+ d->mouse_guest_x != -1 && d->mouse_guest_y != -1 &&
+ !d->show_cursor &&
+ spice_gtk_session_get_pointer_grabbed(d->gtk_session)) {
+ GdkPixbuf *image = d->mouse_pixbuf;
+ if (image != NULL) {
+ gdk_cairo_set_source_pixbuf(cr, image,
+ d->mouse_guest_x - d->mouse_hotspot.x,
+ d->mouse_guest_y - d->mouse_hotspot.y);
+ cairo_paint(cr);
+ }
+ }
+ }
+}
+
+G_GNUC_INTERNAL
+gboolean spice_cairo_is_scaled(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ return d->allow_scaling;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2014-2016 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <math.h>
+
+#define EGL_EGLEXT_PROTOTYPES
+#define GL_GLEXT_PROTOTYPES
+
+#include "spice-widget.h"
+#include "spice-widget-priv.h"
+#include "spice-gtk-session-priv.h"
+#include <libdrm/drm_fourcc.h>
+
+#include <gdk/gdkx.h>
+#ifdef GDK_WINDOWING_WAYLAND
+#include <gdk/gdkwayland.h>
+#endif
+
+#define VERTS_ARRAY_SIZE (sizeof(GLfloat) * 4 * 4)
+#define TEX_ARRAY_SIZE (sizeof(GLfloat) * 4 * 2)
+
+static const char *spice_egl_vertex_src = \
+" \
+ #version 130\n \
+ \
+ in vec4 position; \
+ in vec2 texcoords; \
+ out vec2 tcoords; \
+ uniform mat4 mproj; \
+ \
+ void main() \
+ { \
+ tcoords = texcoords; \
+ gl_Position = mproj * position; \
+ } \
+";
+
+static const char *spice_egl_fragment_src = \
+" \
+ #version 130\n \
+ \
+ in vec2 tcoords; \
+ out vec4 fragmentColor; \
+ uniform sampler2D samp; \
+ \
+ void main() \
+ { \
+ fragmentColor = texture2D(samp, tcoords); \
+ } \
+";
+
+static void apply_ortho(guint mproj, float left, float right,
+ float bottom, float top, float near, float far)
+
+{
+ float a = 2.0f / (right - left);
+ float b = 2.0f / (top - bottom);
+ float c = -2.0f / (far - near);
+
+ float tx = - (right + left) / (right - left);
+ float ty = - (top + bottom) / (top - bottom);
+ float tz = - (far + near) / (far - near);
+
+ float ortho[16] = {
+ a, 0, 0, 0,
+ 0, b, 0, 0,
+ 0, 0, c, 0,
+ tx, ty, tz, 1
+ };
+
+ glUniformMatrix4fv(mproj, 1, GL_FALSE, &ortho[0]);
+}
+
+static gboolean spice_egl_init_shaders(SpiceDisplay *display, GError **err)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+ GLuint fs = 0, vs = 0, buf;
+ GLint status, tex_loc, prog;
+ gboolean success = FALSE;
+ gchar log[1000] = { 0, };
+ GLsizei len;
+
+ glGetIntegerv(GL_CURRENT_PROGRAM, &prog);
+
+ fs = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fs, 1, (const char **)&spice_egl_fragment_src, NULL);
+ glCompileShader(fs);
+ glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
+ if (!status) {
+ glGetShaderInfoLog(fs, sizeof(log), &len, log);
+ g_set_error(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "failed to compile fragment shader: %s", log);
+ goto end;
+ }
+
+ vs = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vs, 1, (const char **)&spice_egl_vertex_src, NULL);
+ glCompileShader(vs);
+ glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
+ if (!status) {
+ glGetShaderInfoLog(vs, sizeof(log), &len, log);
+ g_set_error(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "failed to compile vertex shader: %s", log);
+ goto end;
+ }
+
+ d->egl.prog = glCreateProgram();
+ glAttachShader(d->egl.prog, fs);
+ glAttachShader(d->egl.prog, vs);
+ glLinkProgram(d->egl.prog);
+ glGetProgramiv(d->egl.prog, GL_LINK_STATUS, &status);
+ if (!status) {
+ glGetProgramInfoLog(d->egl.prog, 1000, &len, log);
+ g_set_error(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "error linking shaders: %s", log);
+ goto end;
+ }
+
+ glUseProgram(d->egl.prog);
+ glDetachShader(d->egl.prog, fs);
+ glDetachShader(d->egl.prog, vs);
+
+ d->egl.attr_pos = glGetAttribLocation(d->egl.prog, "position");
+ g_assert(d->egl.attr_pos != -1);
+ d->egl.attr_tex = glGetAttribLocation(d->egl.prog, "texcoords");
+ g_assert(d->egl.attr_tex != -1);
+ tex_loc = glGetUniformLocation(d->egl.prog, "samp");
+ g_assert(tex_loc != -1);
+ d->egl.mproj = glGetUniformLocation(d->egl.prog, "mproj");
+ g_assert(d->egl.mproj != -1);
+
+ glUniform1i(tex_loc, 0);
+
+ /* we only use one VAO, so we always keep it bound */
+ glGenVertexArrays(1, &buf);
+ glBindVertexArray(buf);
+
+ glGenBuffers(1, &buf);
+ glBindBuffer(GL_ARRAY_BUFFER, buf);
+ glBufferData(GL_ARRAY_BUFFER,
+ VERTS_ARRAY_SIZE + TEX_ARRAY_SIZE,
+ NULL,
+ GL_STATIC_DRAW);
+ d->egl.vbuf_id = buf;
+
+ glGenTextures(1, &d->egl.tex_id);
+ glGenTextures(1, &d->egl.tex_pointer_id);
+
+ success = TRUE;
+
+end:
+ if (fs) {
+ glDeleteShader(fs);
+ }
+ if (vs) {
+ glDeleteShader(vs);
+ }
+
+ glUseProgram(prog);
+ return success;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_egl_init(SpiceDisplay *display, GError **err)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+ static const EGLint conf_att[] = {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 0,
+ EGL_NONE,
+ };
+ static const EGLint ctx_att[] = {
+#ifdef EGL_CONTEXT_MAJOR_VERSION
+ EGL_CONTEXT_MAJOR_VERSION, 3,
+#else
+ EGL_CONTEXT_CLIENT_VERSION, 3,
+#endif
+ EGL_NONE
+ };
+ EGLBoolean b;
+ EGLint major, minor, n;
+ EGLNativeDisplayType dpy = 0;
+ GdkDisplay *gdk_dpy = gdk_display_get_default();
+
+#ifdef GDK_WINDOWING_WAYLAND
+ if (GDK_IS_WAYLAND_DISPLAY(gdk_dpy)) {
+ d->egl.ctx = eglGetCurrentContext();
+ dpy = (EGLNativeDisplayType)gdk_wayland_display_get_wl_display(gdk_dpy);
+ d->egl.display = eglGetDisplay(dpy);
+ goto end;
+ }
+#endif
+#ifdef GDK_WINDOWING_X11
+ if (GDK_IS_X11_DISPLAY(gdk_dpy)) {
+ dpy = (EGLNativeDisplayType)gdk_x11_display_get_xdisplay(gdk_dpy);
+ }
+#endif
+
+ d->egl.display = eglGetDisplay(dpy);
+ if (d->egl.display == EGL_NO_DISPLAY) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "failed to get EGL display");
+ return FALSE;
+ }
+
+ if (!eglInitialize(d->egl.display, &major, &minor)) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "failed to init EGL display");
+ return FALSE;
+ }
+
+ SPICE_DEBUG("EGL major/minor: %d.%d\n", major, minor);
+ SPICE_DEBUG("EGL version: %s\n",
+ eglQueryString(d->egl.display, EGL_VERSION));
+ SPICE_DEBUG("EGL vendor: %s\n",
+ eglQueryString(d->egl.display, EGL_VENDOR));
+ SPICE_DEBUG("EGL extensions: %s\n",
+ eglQueryString(d->egl.display, EGL_EXTENSIONS));
+
+ b = eglBindAPI(EGL_OPENGL_API);
+ if (!b) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "cannot bind OpenGL API");
+ return FALSE;
+ }
+
+ b = eglChooseConfig(d->egl.display, conf_att, &d->egl.conf,
+ 1, &n);
+
+ if (!b || n != 1) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "cannot find suitable EGL config");
+ return FALSE;
+ }
+
+ d->egl.ctx = eglCreateContext(d->egl.display,
+ d->egl.conf,
+ EGL_NO_CONTEXT,
+ ctx_att);
+ if (!d->egl.ctx) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "cannot create EGL context");
+ return FALSE;
+ }
+
+ eglMakeCurrent(d->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ d->egl.ctx);
+
+#ifdef GDK_WINDOWING_WAYLAND
+end:
+#endif
+
+ if (!spice_egl_init_shaders(display, err))
+ return FALSE;
+
+ d->egl.context_ready = TRUE;
+
+ if (spice_display_get_gl_scanout(SPICE_DISPLAY_CHANNEL(d->display)) != NULL) {
+ SPICE_DEBUG("scanout present during egl init, updating widget");
+ spice_display_widget_gl_scanout(display);
+ spice_display_widget_update_monitor_area(display);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+gl_make_current(SpiceDisplay *display, GError **err)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+
+ if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
+ EGLBoolean success = eglMakeCurrent(d->egl.display,
+ d->egl.surface,
+ d->egl.surface,
+ d->egl.ctx);
+ if (success != EGL_TRUE) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED,
+ "failed to activate context");
+ return FALSE;
+ }
+ }
+#if GTK_CHECK_VERSION(3,16,0)
+ else {
+ GtkWidget *area = gtk_stack_get_child_by_name(d->stack, "gl-area");
+
+ gtk_gl_area_make_current(GTK_GL_AREA(area));
+ }
+#endif
+
+ return TRUE;
+}
+
+static gboolean spice_widget_init_egl_win(SpiceDisplay *display, GdkWindow *win,
+ GError **err)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+ EGLNativeWindowType native = 0;
+
+ if (d->egl.surface)
+ return TRUE;
+
+#ifdef GDK_WINDOWING_X11
+ if (GDK_IS_X11_WINDOW(win)) {
+ native = (EGLNativeWindowType)GDK_WINDOW_XID(win);
+ }
+#endif
+
+ if (!native) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "this platform isn't supported");
+ return FALSE;
+ }
+
+ d->egl.surface = eglCreateWindowSurface(d->egl.display,
+ d->egl.conf,
+ native, NULL);
+
+ if (!d->egl.surface) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "failed to init egl surface");
+ return FALSE;
+ }
+
+ if (!gl_make_current(display, err))
+ return FALSE;
+
+ return TRUE;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_egl_realize_display(SpiceDisplay *display, GdkWindow *win, GError **err)
+{
+ SPICE_DEBUG("egl realize");
+ if (!spice_widget_init_egl_win(display, win, err))
+ return FALSE;
+
+ spice_egl_resize_display(display, gdk_window_get_width(win),
+ gdk_window_get_height(win));
+
+ return TRUE;
+}
+
+G_GNUC_INTERNAL
+void spice_egl_unrealize_display(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+
+ SPICE_DEBUG("egl unrealize %p", d->egl.surface);
+
+ if (!gl_make_current(display, NULL))
+ return;
+
+ if (d->egl.image != NULL) {
+ eglDestroyImageKHR(d->egl.display, d->egl.image);
+ d->egl.image = NULL;
+ }
+
+ if (d->egl.tex_id) {
+ glDeleteTextures(1, &d->egl.tex_id);
+ d->egl.tex_id = 0;
+ }
+
+ if (d->egl.tex_pointer_id) {
+ glDeleteTextures(1, &d->egl.tex_pointer_id);
+ d->egl.tex_pointer_id = 0;
+ }
+
+ if (d->egl.vbuf_id) {
+ glDeleteBuffers(1, &d->egl.vbuf_id);
+ d->egl.vbuf_id = 0;
+ }
+
+ if (d->egl.prog) {
+ glDeleteProgram(d->egl.prog);
+ d->egl.prog = 0;
+ }
+
+ if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
+ /* egl.surface && egl.ctx are only created on x11, see
+ spice_egl_init() */
+
+ if (d->egl.surface != EGL_NO_SURFACE) {
+ eglDestroySurface(d->egl.display, d->egl.surface);
+ d->egl.surface = EGL_NO_SURFACE;
+ }
+
+ if (d->egl.ctx) {
+ eglDestroyContext(d->egl.display, d->egl.ctx);
+ d->egl.ctx = 0;
+ }
+
+ eglMakeCurrent(d->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+
+ /* do not call eglterminate() since egl may be used by
+ * somebody else code */
+ }
+}
+
+G_GNUC_INTERNAL
+void spice_egl_resize_display(SpiceDisplay *display, int w, int h)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+ int prog;
+
+ if (!gl_make_current(display, NULL))
+ return;
+
+ glGetIntegerv(GL_CURRENT_PROGRAM, &prog);
+
+ glUseProgram(d->egl.prog);
+ apply_ortho(d->egl.mproj, 0, w, 0, h, -1, 1);
+ glViewport(0, 0, w, h);
+
+ if (d->ready)
+ spice_egl_update_display(display);
+
+ glUseProgram(prog);
+}
+
+static void
+draw_rect_from_arrays(SpiceDisplay *display, const void *verts, const void *tex)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+
+ glBindBuffer(GL_ARRAY_BUFFER, d->egl.vbuf_id);
+
+ if (verts) {
+ glEnableVertexAttribArray(d->egl.attr_pos);
+ glBufferSubData(GL_ARRAY_BUFFER,
+ 0,
+ VERTS_ARRAY_SIZE,
+ verts);
+ glVertexAttribPointer(d->egl.attr_pos, 4, GL_FLOAT,
+ GL_FALSE, 0, 0);
+ }
+ if (tex) {
+ glEnableVertexAttribArray(d->egl.attr_tex);
+ glBufferSubData(GL_ARRAY_BUFFER,
+ VERTS_ARRAY_SIZE,
+ TEX_ARRAY_SIZE,
+ tex);
+ glVertexAttribPointer(d->egl.attr_tex, 2, GL_FLOAT,
+ GL_FALSE, 0,
+ (void *)VERTS_ARRAY_SIZE);
+ }
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ if (verts)
+ glDisableVertexAttribArray(d->egl.attr_pos);
+ if (tex)
+ glDisableVertexAttribArray(d->egl.attr_tex);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+static GLvoid
+client_draw_rect_tex(SpiceDisplay *display,
+ float x, float y, float w, float h,
+ float tx, float ty, float tw, float th)
+{
+ float verts[4][4];
+ float tex[4][2];
+
+ verts[0][0] = x;
+ verts[0][1] = y;
+ verts[0][2] = 0.0;
+ verts[0][3] = 1.0;
+ tex[0][0] = tx;
+ tex[0][1] = ty;
+ verts[1][0] = x + w;
+ verts[1][1] = y;
+ verts[1][2] = 0.0;
+ verts[1][3] = 1.0;
+ tex[1][0] = tx + tw;
+ tex[1][1] = ty;
+ verts[2][0] = x;
+ verts[2][1] = y + h;
+ verts[2][2] = 0.0;
+ verts[2][3] = 1.0;
+ tex[2][0] = tx;
+ tex[2][1] = ty + th;
+ verts[3][0] = x + w;
+ verts[3][1] = y + h;
+ verts[3][2] = 0.0;
+ verts[3][3] = 1.0;
+ tex[3][0] = tx + tw;
+ tex[3][1] = ty + th;
+
+ draw_rect_from_arrays(display, verts, tex);
+}
+
+G_GNUC_INTERNAL
+void spice_egl_cursor_set(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+ GdkPixbuf *image = d->mouse_pixbuf;
+
+ g_return_if_fail(d->egl.enabled);
+
+ if (image == NULL)
+ return;
+
+ int width = gdk_pixbuf_get_width(image);
+ int height = gdk_pixbuf_get_height(image);
+
+ glBindTexture(GL_TEXTURE_2D, d->egl.tex_pointer_id);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ width, height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE,
+ gdk_pixbuf_read_pixels(image));
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+G_GNUC_INTERNAL
+void spice_egl_update_display(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+ double s;
+ int x, y, w, h;
+ gdouble tx, ty, tw, th;
+ int prog;
+
+ g_return_if_fail(d->ready);
+ if (!gl_make_current(display, NULL))
+ return;
+
+ spice_display_get_scaling(display, &s, &x, &y, &w, &h);
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ tx = ((float)d->area.x / (float)d->egl.scanout.width);
+ ty = ((float)d->area.y / (float)d->egl.scanout.height);
+ tw = ((float)d->area.width / (float)d->egl.scanout.width);
+ th = ((float)d->area.height / (float)d->egl.scanout.height);
+
+ /* convert to opengl coordinates, 0 is bottom, 1 is top. ty should
+ * be the bottom of the area, since th is upward */
+ /* 1+---------------+ */
+ /* | | */
+ /* | ty to |th | */
+ /* | | -> | | */
+ /* | |th ty | */
+ /* | | */
+ /* | | */
+ /* +---------------+ */
+ /* 0 */
+ ty = 1 - (ty + th);
+
+
+ /* if the scanout is inverted, then invert coordinates and direction too */
+ if (!d->egl.scanout.y0top) {
+ ty = 1 - ty;
+ th = -1 * th;
+ }
+ SPICE_DEBUG("update %f +%d+%d %dx%d +%f+%f %fx%f", s, x, y, w, h,
+ tx, ty, tw, th);
+ glBindTexture(GL_TEXTURE_2D, d->egl.tex_id);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+#if !GTK_CHECK_VERSION(3,16,0)
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)d->egl.image);
+#endif
+
+ glDisable(GL_BLEND);
+ glGetIntegerv(GL_CURRENT_PROGRAM, &prog);
+ glUseProgram(d->egl.prog);
+ client_draw_rect_tex(display, x, y, w, h,
+ tx, ty, tw, th);
+
+ if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER &&
+ d->mouse_guest_x != -1 && d->mouse_guest_y != -1 &&
+ !d->show_cursor &&
+ spice_gtk_session_get_pointer_grabbed(d->gtk_session) &&
+ d->mouse_pixbuf != NULL) {
+ GdkPixbuf *image = d->mouse_pixbuf;
+ int width = gdk_pixbuf_get_width(image);
+ int height = gdk_pixbuf_get_height(image);
+
+ glBindTexture(GL_TEXTURE_2D, d->egl.tex_pointer_id);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ client_draw_rect_tex(display,
+ x + (d->mouse_guest_x - d->mouse_hotspot.x) * s,
+ y + h - (d->mouse_guest_y - d->mouse_hotspot.y) * s,
+ width, -height,
+ 0, 0, 1, 1);
+ }
+
+ if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
+ /* gtk+ does the swap with gtkglarea */
+ eglSwapBuffers(d->egl.display, d->egl.surface);
+ }
+
+ glUseProgram(prog);
+}
+
+G_GNUC_INTERNAL
+gboolean spice_egl_update_scanout(SpiceDisplay *display,
+ const SpiceGlScanout *scanout,
+ GError **err)
+{
+ SpiceDisplayPrivate *d = SPICE_DISPLAY_GET_PRIVATE(display);
+ EGLint attrs[13];
+ guint32 format;
+
+ g_return_val_if_fail(scanout != NULL, FALSE);
+ format = scanout->format;
+
+ if (d->egl.image != NULL) {
+ eglDestroyImageKHR(d->egl.display, d->egl.image);
+ d->egl.image = NULL;
+ }
+
+ if (scanout->fd == -1)
+ return TRUE;
+
+ attrs[0] = EGL_DMA_BUF_PLANE0_FD_EXT;
+ attrs[1] = scanout->fd;
+ attrs[2] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
+ attrs[3] = scanout->stride;
+ attrs[4] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
+ attrs[5] = 0;
+ attrs[6] = EGL_WIDTH;
+ attrs[7] = scanout->width;
+ attrs[8] = EGL_HEIGHT;
+ attrs[9] = scanout->height;
+ attrs[10] = EGL_LINUX_DRM_FOURCC_EXT;
+ attrs[11] = format;
+ attrs[12] = EGL_NONE;
+ SPICE_DEBUG("fd:%d stride:%u y0:%d %ux%u format:0x%x (%c%c%c%c)",
+ scanout->fd, scanout->stride, scanout->y0top,
+ scanout->width, scanout->height, format,
+ (int)format & 0xff, (int)(format >> 8) & 0xff,
+ (int)(format >> 16) & 0xff, (int)format >> 24);
+
+ d->egl.image = eglCreateImageKHR(d->egl.display,
+ EGL_NO_CONTEXT,
+ EGL_LINUX_DMA_BUF_EXT,
+ (EGLClientBuffer)NULL,
+ attrs);
+
+ d->egl.scanout = *scanout;
+
+#if GTK_CHECK_VERSION(3,16,0)
+ if (!gl_make_current(display, NULL))
+ return FALSE;
+
+ glBindTexture(GL_TEXTURE_2D, d->egl.tex_id);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)d->egl.image);
+#endif
+
+ return TRUE;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_WIDGET_PRIV_H__
+#define __SPICE_WIDGET_PRIV_H__
+
+#include "config.h"
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#ifndef G_OS_WIN32
+#include <epoxy/egl.h>
+#endif
+
+#include "spice-widget.h"
+#include "spice-common.h"
+#include "spice-gtk-session.h"
+
+G_BEGIN_DECLS
+
+typedef struct _SpiceDisplayPrivate SpiceDisplayPrivate;
+
+struct _SpiceDisplay {
+ GtkEventBox parent;
+ SpiceDisplayPrivate *priv;
+};
+
+struct _SpiceDisplayClass {
+ GtkEventBoxClass parent_class;
+
+ /* signals */
+ void (*mouse_grab)(SpiceChannel *channel, gint grabbed);
+ void (*keyboard_grab)(SpiceChannel *channel, gint grabbed);
+};
+
+#define SPICE_DISPLAY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_DISPLAY, SpiceDisplayPrivate))
+
+struct _SpiceDisplayPrivate {
+ GtkStack *stack;
+ gint channel_id;
+ gint monitor_id;
+
+ /* options */
+ bool keyboard_grab_enable;
+ gboolean keyboard_grab_inhibit;
+ bool mouse_grab_enable;
+ bool resize_guest_enable;
+
+ /* state */
+ gboolean ready;
+ gboolean monitor_ready;
+ struct {
+ enum SpiceSurfaceFmt format;
+ gint width, height, stride;
+ gpointer data_origin; /* the original display image data */
+ gpointer data; /* converted if necessary to 32 bits */
+ bool convert;
+ cairo_surface_t *surface;
+ } canvas;
+ GdkRectangle area;
+ /* window border */
+ gint ww, wh, mx, my;
+
+ gboolean allow_scaling;
+ gboolean only_downscale;
+ gboolean disable_inputs;
+
+ SpiceSession *session;
+ SpiceGtkSession *gtk_session;
+ SpiceMainChannel *main;
+ SpiceChannel *display;
+ SpiceCursorChannel *cursor;
+ SpiceInputsChannel *inputs;
+ SpiceSmartcardChannel *smartcard;
+
+ enum SpiceMouseMode mouse_mode;
+ int mouse_grab_active;
+ bool mouse_have_pointer;
+ GdkCursor *mouse_cursor;
+ GdkPixbuf *mouse_pixbuf;
+ GdkPoint mouse_hotspot;
+ GdkCursor *show_cursor;
+ int mouse_last_x;
+ int mouse_last_y;
+ int mouse_guest_x;
+ int mouse_guest_y;
+
+ bool keyboard_grab_active;
+ bool keyboard_have_focus;
+
+ const guint16 *keycode_map;
+ size_t keycode_maplen;
+ uint32_t key_state[512 / 32];
+ int key_delayed_scancode;
+ guint key_delayed_id;
+ SpiceGrabSequence *grabseq; /* the configured key sequence */
+ gboolean *activeseq; /* the currently pressed keys */
+ gboolean seq_pressed;
+ gboolean keyboard_grab_released;
+ gint mark;
+#ifdef WIN32
+ HHOOK keyboard_hook;
+ int win_mouse[3];
+ int win_mouse_speed;
+#endif
+ guint keypress_delay;
+ gint zoom_level;
+#ifdef GDK_WINDOWING_X11
+ int x11_accel_numerator;
+ int x11_accel_denominator;
+ int x11_threshold;
+#endif
+#ifndef G_OS_WIN32
+ struct {
+ gboolean context_ready;
+ gboolean enabled;
+ EGLSurface surface;
+ EGLDisplay display;
+ EGLConfig conf;
+ EGLContext ctx;
+ gint mproj, attr_pos, attr_tex;
+ guint vbuf_id;
+ guint tex_id;
+ guint tex_pointer_id;
+ guint prog;
+ EGLImageKHR image;
+ gboolean call_draw_done;
+ SpiceGlScanout scanout;
+ } egl;
+#endif
+};
+
+int spice_cairo_image_create (SpiceDisplay *display);
+void spice_cairo_image_destroy (SpiceDisplay *display);
+void spice_cairo_draw_event (SpiceDisplay *display, cairo_t *cr);
+gboolean spice_cairo_is_scaled (SpiceDisplay *display);
+void spice_display_get_scaling (SpiceDisplay *display, double *s, int *x, int *y, int *w, int *h);
+gboolean spice_egl_init (SpiceDisplay *display, GError **err);
+gboolean spice_egl_realize_display (SpiceDisplay *display, GdkWindow *win,
+ GError **err);
+void spice_egl_unrealize_display (SpiceDisplay *display);
+void spice_egl_update_display (SpiceDisplay *display);
+void spice_egl_resize_display (SpiceDisplay *display, int w, int h);
+gboolean spice_egl_update_scanout (SpiceDisplay *display,
+ const SpiceGlScanout *scanout,
+ GError **err);
+void spice_egl_cursor_set (SpiceDisplay *display);
+
+void spice_display_widget_gl_scanout (SpiceDisplay *display);
+void spice_display_widget_update_monitor_area(SpiceDisplay *display);
+
+G_END_DECLS
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <math.h>
+#include <glib.h>
+
+#ifdef HAVE_X11_XKBLIB_H
+#include <X11/XKBlib.h>
+#include <gdk/gdkx.h>
+#endif
+#ifdef GDK_WINDOWING_X11
+#include <X11/Xlib.h>
+#include <gdk/gdkx.h>
+#endif
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include <dinput.h>
+#include <ime.h>
+#include <gdk/gdkwin32.h>
+#ifndef MAPVK_VK_TO_VSC /* may be undefined in older mingw-headers */
+#define MAPVK_VK_TO_VSC 0
+#endif
+#endif
+
+#include "spice-widget.h"
+#include "spice-widget-priv.h"
+#include "spice-gtk-session-priv.h"
+#include "vncdisplaykeymap.h"
+#include "spice-grabsequence-priv.h"
+
+/* Some compatibility defines to let us build on both Gtk2 and Gtk3 */
+
+/**
+ * SECTION:spice-widget
+ * @short_description: a GTK display widget
+ * @title: Spice Display
+ * @section_id:
+ * @stability: Stable
+ * @include: spice-client-gtk.h
+ *
+ * A GTK widget that displays a SPICE server. It sends keyboard/mouse
+ * events and can also share clipboard...
+ *
+ * Arbitrary key events can be sent thanks to spice_display_send_keys().
+ *
+ * The widget will optionally grab the keyboard and the mouse when
+ * focused if the properties #SpiceDisplay:grab-keyboard and
+ * #SpiceDisplay:grab-mouse are #TRUE respectively. It can be
+ * ungrabbed with spice_display_mouse_ungrab(), and by setting a key
+ * combination with spice_display_set_grab_keys().
+ *
+ * Finally, spice_display_get_pixbuf() will take a screenshot of the
+ * current display and return an #GdkPixbuf (that you can then easily
+ * save to disk).
+ */
+
+G_DEFINE_TYPE(SpiceDisplay, spice_display, GTK_TYPE_EVENT_BOX)
+
+/* Properties */
+enum {
+ PROP_0,
+ PROP_SESSION,
+ PROP_CHANNEL_ID,
+ PROP_KEYBOARD_GRAB,
+ PROP_MOUSE_GRAB,
+ PROP_RESIZE_GUEST,
+ PROP_SCALING,
+ PROP_ONLY_DOWNSCALE,
+ PROP_DISABLE_INPUTS,
+ PROP_ZOOM_LEVEL,
+ PROP_MONITOR_ID,
+ PROP_KEYPRESS_DELAY,
+ PROP_READY
+};
+
+/* Signals */
+enum {
+ SPICE_DISPLAY_MOUSE_GRAB,
+ SPICE_DISPLAY_KEYBOARD_GRAB,
+ SPICE_DISPLAY_GRAB_KEY_PRESSED,
+ SPICE_DISPLAY_LAST_SIGNAL,
+};
+
+#define DEFAULT_KEYPRESS_DELAY 100
+
+static guint signals[SPICE_DISPLAY_LAST_SIGNAL];
+
+#ifdef G_OS_WIN32
+static HWND win32_window = NULL;
+#endif
+
+static void update_keyboard_grab(SpiceDisplay *display);
+static void try_keyboard_grab(SpiceDisplay *display);
+static void try_keyboard_ungrab(SpiceDisplay *display);
+static void update_mouse_grab(SpiceDisplay *display);
+static void try_mouse_grab(SpiceDisplay *display);
+static void try_mouse_ungrab(SpiceDisplay *display);
+static void recalc_geometry(GtkWidget *widget);
+static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data);
+static void channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer data);
+static void cursor_invalidate(SpiceDisplay *display);
+static void update_area(SpiceDisplay *display, gint x, gint y, gint width, gint height);
+static void release_keys(SpiceDisplay *display);
+static void size_allocate(GtkWidget *widget, GtkAllocation *conf, gpointer data);
+static gboolean draw_event(GtkWidget *widget, cairo_t *cr, gpointer data);
+static void update_size_request(SpiceDisplay *display);
+
+/* ---------------------------------------------------------------- */
+
+static void spice_display_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(object);
+ SpiceDisplayPrivate *d = display->priv;
+
+ switch (prop_id) {
+ case PROP_SESSION:
+ g_value_set_object(value, d->session);
+ break;
+ case PROP_CHANNEL_ID:
+ g_value_set_int(value, d->channel_id);
+ break;
+ case PROP_MONITOR_ID:
+ g_value_set_int(value, d->monitor_id);
+ break;
+ case PROP_KEYBOARD_GRAB:
+ g_value_set_boolean(value, d->keyboard_grab_enable);
+ break;
+ case PROP_MOUSE_GRAB:
+ g_value_set_boolean(value, d->mouse_grab_enable);
+ break;
+ case PROP_RESIZE_GUEST:
+ g_value_set_boolean(value, d->resize_guest_enable);
+ break;
+ case PROP_SCALING:
+ g_value_set_boolean(value, d->allow_scaling);
+ break;
+ case PROP_ONLY_DOWNSCALE:
+ g_value_set_boolean(value, d->only_downscale);
+ break;
+ case PROP_DISABLE_INPUTS:
+ g_value_set_boolean(value, d->disable_inputs);
+ break;
+ case PROP_ZOOM_LEVEL:
+ g_value_set_int(value, d->zoom_level);
+ break;
+ case PROP_READY:
+ g_value_set_boolean(value, d->ready);
+ break;
+ case PROP_KEYPRESS_DELAY:
+ g_value_set_uint(value, d->keypress_delay);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void scaling_updated(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(display));
+
+ recalc_geometry(GTK_WIDGET(display));
+ if (d->canvas.surface && window) { /* if not yet shown */
+ gtk_widget_queue_draw(GTK_WIDGET(display));
+ }
+ update_size_request(display);
+}
+
+static void update_size_request(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ gint reqwidth, reqheight;
+
+ if (d->resize_guest_enable || d->allow_scaling) {
+ reqwidth = 640;
+ reqheight = 480;
+ } else {
+ reqwidth = d->area.width;
+ reqheight = d->area.height;
+ }
+
+ gtk_widget_set_size_request(GTK_WIDGET(display), reqwidth, reqheight);
+ recalc_geometry(GTK_WIDGET(display));
+}
+
+static void update_keyboard_focus(SpiceDisplay *display, gboolean state)
+{
+ SpiceDisplayPrivate *d = display->priv;
+
+ d->keyboard_have_focus = state;
+ spice_gtk_session_set_keyboard_has_focus(d->gtk_session, state);
+
+ /* keyboard grab gets inhibited by usb-device-manager when it is
+ in the process of redirecting a usb-device (as this may show a
+ policykit dialog). Making autoredir/automount setting changes while
+ this is happening is not a good idea! */
+ if (d->keyboard_grab_inhibit)
+ return;
+
+ spice_gtk_session_request_auto_usbredir(d->gtk_session, state);
+}
+
+static gint get_display_id(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+
+ /* supported monitor_id only with display channel #0 */
+ if (d->channel_id == 0 && d->monitor_id >= 0)
+ return d->monitor_id;
+
+ g_return_val_if_fail(d->monitor_id <= 0, -1);
+
+ return d->channel_id;
+}
+
+static bool egl_enabled(SpiceDisplayPrivate *d)
+{
+#ifndef G_OS_WIN32
+ return d->egl.enabled;
+#else
+ return false;
+#endif
+}
+
+static void update_ready(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ gboolean ready = FALSE;
+
+ if (d->monitor_ready) {
+ ready = egl_enabled(d) || d->mark != 0;
+ }
+ /* If the 'resize-guest' property is set, the application expects spice-gtk
+ * to manage the size and state of the displays, so update the 'enabled'
+ * state here. If 'resize-guest' is false, we can assume that the
+ * application will manage the state of the displays.
+ */
+ if (d->resize_guest_enable) {
+ spice_main_update_display_enabled(d->main, get_display_id(display),
+ ready, TRUE);
+ }
+
+ if (d->ready == ready)
+ return;
+
+ if (ready && gtk_widget_get_window(GTK_WIDGET(display)))
+ gtk_widget_queue_draw(GTK_WIDGET(display));
+
+ d->ready = ready;
+ g_object_notify(G_OBJECT(display), "ready");
+}
+
+static void set_monitor_ready(SpiceDisplay *self, gboolean ready)
+{
+ SpiceDisplayPrivate *d = self->priv;
+
+ d->monitor_ready = ready;
+ update_ready(self);
+}
+
+G_GNUC_INTERNAL
+void spice_display_widget_update_monitor_area(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ SpiceDisplayMonitorConfig *cfg, *c = NULL;
+ GArray *monitors = NULL;
+ int i;
+
+ SPICE_DEBUG("update monitor area %d:%d", d->channel_id, d->monitor_id);
+ if (d->monitor_id < 0)
+ goto whole;
+
+ g_object_get(d->display, "monitors", &monitors, NULL);
+ for (i = 0; monitors != NULL && i < monitors->len; i++) {
+ cfg = &g_array_index(monitors, SpiceDisplayMonitorConfig, i);
+ if (cfg->id == d->monitor_id) {
+ c = cfg;
+ break;
+ }
+ }
+ if (c == NULL) {
+ SPICE_DEBUG("update monitor: no monitor %d", d->monitor_id);
+ set_monitor_ready(display, false);
+ if (spice_channel_test_capability(d->display, SPICE_DISPLAY_CAP_MONITORS_CONFIG)) {
+ SPICE_DEBUG("waiting until MonitorsConfig is received");
+ g_clear_pointer(&monitors, g_array_unref);
+ return;
+ }
+ goto whole;
+ }
+
+ if (c->surface_id != 0) {
+ g_warning("FIXME: only support monitor config with primary surface 0, "
+ "but given config surface %u", c->surface_id);
+ goto whole;
+ }
+
+ /* If only one head on this monitor, update the whole area */
+ if (monitors->len == 1 && !egl_enabled(d)) {
+ update_area(display, 0, 0, c->width, c->height);
+ } else {
+ update_area(display, c->x, c->y, c->width, c->height);
+ }
+ g_clear_pointer(&monitors, g_array_unref);
+ return;
+
+whole:
+ g_clear_pointer(&monitors, g_array_unref);
+ /* by display whole surface */
+ update_area(display, 0, 0, d->canvas.width, d->canvas.height);
+ set_monitor_ready(display, true);
+}
+
+static void
+spice_display_set_keypress_delay(SpiceDisplay *display, guint delay)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ const gchar *env = g_getenv("SPICE_KEYPRESS_DELAY");
+
+ if (env != NULL)
+ delay = strtoul(env, NULL, 10);
+
+ if (d->keypress_delay != delay) {
+ SPICE_DEBUG("keypress-delay is set to %u ms", delay);
+ d->keypress_delay = delay;
+ g_object_notify(G_OBJECT(display), "keypress-delay");
+ }
+}
+
+static void spice_display_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(object);
+ SpiceDisplayPrivate *d = display->priv;
+
+ switch (prop_id) {
+ case PROP_SESSION:
+ g_warn_if_fail(d->session == NULL);
+ d->session = g_value_dup_object(value);
+ d->gtk_session = spice_gtk_session_get(d->session);
+ spice_g_signal_connect_object(d->gtk_session, "notify::pointer-grabbed",
+ G_CALLBACK(cursor_invalidate), object,
+ G_CONNECT_SWAPPED);
+ break;
+ case PROP_CHANNEL_ID:
+ d->channel_id = g_value_get_int(value);
+ break;
+ case PROP_MONITOR_ID:
+ d->monitor_id = g_value_get_int(value);
+ if (d->display) /* if constructed */
+ spice_display_widget_update_monitor_area(display);
+ break;
+ case PROP_KEYBOARD_GRAB:
+ d->keyboard_grab_enable = g_value_get_boolean(value);
+ update_keyboard_grab(display);
+ break;
+ case PROP_MOUSE_GRAB:
+ d->mouse_grab_enable = g_value_get_boolean(value);
+ update_mouse_grab(display);
+ break;
+ case PROP_RESIZE_GUEST:
+ d->resize_guest_enable = g_value_get_boolean(value);
+ update_ready(display);
+ update_size_request(display);
+ break;
+ case PROP_SCALING:
+ d->allow_scaling = g_value_get_boolean(value);
+ scaling_updated(display);
+ break;
+ case PROP_ONLY_DOWNSCALE:
+ d->only_downscale = g_value_get_boolean(value);
+ scaling_updated(display);
+ break;
+ case PROP_DISABLE_INPUTS:
+ d->disable_inputs = g_value_get_boolean(value);
+ gtk_widget_set_can_focus(GTK_WIDGET(display), !d->disable_inputs);
+ update_keyboard_grab(display);
+ update_mouse_grab(display);
+ break;
+ case PROP_ZOOM_LEVEL:
+ d->zoom_level = g_value_get_int(value);
+ scaling_updated(display);
+ break;
+ case PROP_KEYPRESS_DELAY:
+ spice_display_set_keypress_delay(display, g_value_get_uint(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void session_inhibit_keyboard_grab_changed(GObject *gobject,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ SpiceDisplay *display = user_data;
+ SpiceDisplayPrivate *d = display->priv;
+
+ g_object_get(d->session, "inhibit-keyboard-grab",
+ &d->keyboard_grab_inhibit, NULL);
+ update_keyboard_grab(display);
+ update_mouse_grab(display);
+}
+
+static void spice_display_dispose(GObject *obj)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(obj);
+ SpiceDisplayPrivate *d = display->priv;
+
+ SPICE_DEBUG("spice display dispose");
+
+ spice_cairo_image_destroy(display);
+ g_clear_object(&d->session);
+ d->gtk_session = NULL;
+
+ if (d->key_delayed_id) {
+ g_source_remove(d->key_delayed_id);
+ d->key_delayed_id = 0;
+ }
+
+ G_OBJECT_CLASS(spice_display_parent_class)->dispose(obj);
+}
+
+static void spice_display_finalize(GObject *obj)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(obj);
+ SpiceDisplayPrivate *d = display->priv;
+
+ SPICE_DEBUG("Finalize spice display");
+
+ g_clear_pointer(&d->grabseq, spice_grab_sequence_free);
+ g_clear_pointer(&d->activeseq, g_free);
+
+ g_clear_object(&d->show_cursor);
+ g_clear_object(&d->mouse_cursor);
+ g_clear_object(&d->mouse_pixbuf);
+
+ G_OBJECT_CLASS(spice_display_parent_class)->finalize(obj);
+}
+
+static GdkCursor* get_blank_cursor(void)
+{
+ if (g_getenv("SPICE_DEBUG_CURSOR"))
+ return gdk_cursor_new(GDK_DOT);
+
+ return gdk_cursor_new(GDK_BLANK_CURSOR);
+}
+
+static gboolean grab_broken(SpiceDisplay *self, GdkEventGrabBroken *event,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(self));
+ SPICE_DEBUG("%s (implicit: %d, keyboard: %d)", __FUNCTION__,
+ event->implicit, event->keyboard);
+ SPICE_DEBUG("%s (SpiceDisplay::GdkWindow %p, event->grab_window: %p)",
+ __FUNCTION__, window, event->grab_window);
+ if (window == event->grab_window) {
+ /* ignore grab-broken event moving the grab to GtkEventBox::window
+ * (from GtkEventBox::event_window) as we initially called
+ * gdk_pointer_grab() on GtkEventBox::window, see
+ * https://bugzilla.gnome.org/show_bug.cgi?id=769635
+ */
+ return false;
+ }
+
+ if (event->keyboard) {
+ try_keyboard_ungrab(self);
+ release_keys(self);
+ }
+
+ /* always release mouse when grab broken, this could be more
+ generally placed in keyboard_ungrab(), but one might worry of
+ breaking someone else code. */
+ try_mouse_ungrab(self);
+
+ return false;
+}
+
+static void file_transfer_callback(GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ SpiceMainChannel *channel = SPICE_MAIN_CHANNEL(source_object);
+ GError *error = NULL;
+
+ if (spice_main_file_copy_finish(channel, result, &error))
+ return;
+
+ if (error != NULL && error->message != NULL)
+ g_warning("File transfer failed with error: %s", error->message);
+ else
+ g_warning("File transfer failed");
+
+ g_clear_error(&error);
+}
+
+static void drag_data_received_callback(SpiceDisplay *self,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *data,
+ guint info,
+ guint time,
+ gpointer *user_data)
+{
+ const guchar *buf;
+ gchar **file_urls;
+ int n_files;
+ SpiceDisplayPrivate *d = self->priv;
+ int i = 0;
+ GFile **files;
+
+ /* We get a buf like:
+ * file:///root/a.txt\r\nfile:///root/b.txt\r\n
+ */
+ SPICE_DEBUG("%s: drag a file", __FUNCTION__);
+ buf = gtk_selection_data_get_data(data);
+ g_return_if_fail(buf != NULL);
+
+ file_urls = g_uri_list_extract_uris((const gchar*)buf);
+ n_files = g_strv_length(file_urls);
+ files = g_new0(GFile*, n_files + 1);
+ for (i = 0; i < n_files; i++) {
+ files[i] = g_file_new_for_uri(file_urls[i]);
+ }
+ g_strfreev(file_urls);
+
+ spice_main_file_copy_async(d->main, files, 0, NULL, NULL,
+ NULL, file_transfer_callback, NULL);
+ for (i = 0; i < n_files; i++) {
+ g_object_unref(files[i]);
+ }
+ g_free(files);
+
+ gtk_drag_finish(drag_context, TRUE, FALSE, time);
+}
+
+static void grab_notify(SpiceDisplay *display, gboolean was_grabbed)
+{
+ SPICE_DEBUG("grab notify %d", was_grabbed);
+
+ if (was_grabbed == FALSE)
+ release_keys(display);
+}
+
+#if GTK_CHECK_VERSION(3,16,0)
+#ifndef G_OS_WIN32
+static gboolean
+gl_area_render(GtkGLArea *area, GdkGLContext *context, gpointer user_data)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(user_data);
+ SpiceDisplayPrivate *d = display->priv;
+
+ spice_egl_update_display(display);
+ glFlush();
+ if (d->egl.call_draw_done) {
+ spice_display_gl_draw_done(SPICE_DISPLAY_CHANNEL(d->display));
+ d->egl.call_draw_done = FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+gl_area_realize(GtkGLArea *area, gpointer user_data)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(user_data);
+ GError *err = NULL;
+
+ gtk_gl_area_make_current(area);
+ if (gtk_gl_area_get_error(area) != NULL)
+ return;
+
+ if (!spice_egl_init(display, &err)) {
+ g_critical("egl init failed: %s", err->message);
+ g_clear_error(&err);
+ }
+}
+#endif
+#endif
+
+static void
+drawing_area_realize(GtkWidget *area, gpointer user_data)
+{
+#ifdef GDK_WINDOWING_X11
+ SpiceDisplay *display = SPICE_DISPLAY(user_data);
+
+ if (GDK_IS_X11_DISPLAY(gdk_display_get_default()) &&
+ spice_display_get_gl_scanout(SPICE_DISPLAY_CHANNEL(display->priv->display)) != NULL)
+ spice_display_widget_gl_scanout(display);
+
+#endif
+}
+
+static void spice_display_init(SpiceDisplay *display)
+{
+ GtkWidget *widget = GTK_WIDGET(display);
+ GtkWidget *area;
+ SpiceDisplayPrivate *d;
+ GtkTargetEntry targets = { "text/uri-list", 0, 0 };
+
+ d = display->priv = SPICE_DISPLAY_GET_PRIVATE(display);
+ d->stack = GTK_STACK(gtk_stack_new());
+ gtk_container_add(GTK_CONTAINER(display), GTK_WIDGET(d->stack));
+ area = gtk_drawing_area_new();
+
+ g_object_connect(area,
+ "signal::draw", draw_event, display,
+ "signal::realize", drawing_area_realize, display,
+ NULL);
+ gtk_stack_add_named(d->stack, area, "draw-area");
+ gtk_widget_set_double_buffered(area, true);
+ gtk_stack_set_visible_child(d->stack, area);
+
+#if GTK_CHECK_VERSION(3,16,0)
+#ifndef G_OS_WIN32
+ area = gtk_gl_area_new();
+ gtk_gl_area_set_required_version(GTK_GL_AREA(area), 3, 2);
+ gtk_gl_area_set_auto_render(GTK_GL_AREA(area), false);
+ g_object_connect(area,
+ "signal::render", gl_area_render, display,
+ "signal::realize", gl_area_realize, display,
+ NULL);
+ gtk_stack_add_named(d->stack, area, "gl-area");
+ gtk_widget_show_all(widget);
+#endif
+#endif
+
+ g_signal_connect(display, "grab-broken-event", G_CALLBACK(grab_broken), NULL);
+ g_signal_connect(display, "grab-notify", G_CALLBACK(grab_notify), NULL);
+
+ gtk_drag_dest_set(widget, GTK_DEST_DEFAULT_ALL, &targets, 1, GDK_ACTION_COPY);
+ g_signal_connect(display, "drag-data-received",
+ G_CALLBACK(drag_data_received_callback), NULL);
+ g_signal_connect(display, "size-allocate", G_CALLBACK(size_allocate), NULL);
+
+ gtk_widget_add_events(widget,
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_BUTTON_MOTION_MASK |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK |
+ GDK_KEY_PRESS_MASK |
+ GDK_SCROLL_MASK);
+ gtk_widget_set_can_focus(widget, true);
+ gtk_event_box_set_above_child(GTK_EVENT_BOX(widget), true);
+
+ d->grabseq = spice_grab_sequence_new_from_string("Control_L+Alt_L");
+ d->activeseq = g_new0(gboolean, d->grabseq->nkeysyms);
+ d->mouse_cursor = get_blank_cursor();
+}
+
+static GObject *
+spice_display_constructor(GType gtype,
+ guint n_properties,
+ GObjectConstructParam *properties)
+{
+ GObject *obj;
+ SpiceDisplay *display;
+ SpiceDisplayPrivate *d;
+ GList *list;
+ GList *it;
+
+ {
+ /* Always chain up to the parent constructor */
+ GObjectClass *parent_class;
+ parent_class = G_OBJECT_CLASS(spice_display_parent_class);
+ obj = parent_class->constructor(gtype, n_properties, properties);
+ }
+
+ display = SPICE_DISPLAY(obj);
+ d = display->priv;
+
+ if (!d->session)
+ g_error("SpiceDisplay constructed without a session");
+
+ spice_g_signal_connect_object(d->session, "channel-new",
+ G_CALLBACK(channel_new), display, 0);
+ spice_g_signal_connect_object(d->session, "channel-destroy",
+ G_CALLBACK(channel_destroy), display, 0);
+ list = spice_session_get_channels(d->session);
+ for (it = g_list_first(list); it != NULL; it = g_list_next(it)) {
+ if (SPICE_IS_MAIN_CHANNEL(it->data)) {
+ channel_new(d->session, it->data, (gpointer*)display);
+ break;
+ }
+ }
+ for (it = g_list_first(list); it != NULL; it = g_list_next(it)) {
+ if (!SPICE_IS_MAIN_CHANNEL(it->data))
+ channel_new(d->session, it->data, (gpointer*)display);
+ }
+ g_list_free(list);
+
+ spice_g_signal_connect_object(d->session, "notify::inhibit-keyboard-grab",
+ G_CALLBACK(session_inhibit_keyboard_grab_changed),
+ display, 0);
+
+ return obj;
+}
+
+/**
+ * spice_display_set_grab_keys:
+ * @display: the display widget
+ * @seq: (transfer none): key sequence
+ *
+ * Set the key combination to grab/ungrab the keyboard. The default is
+ * "Control L + Alt L".
+ **/
+void spice_display_set_grab_keys(SpiceDisplay *display, SpiceGrabSequence *seq)
+{
+ SpiceDisplayPrivate *d;
+
+ g_return_if_fail(SPICE_IS_DISPLAY(display));
+
+ d = display->priv;
+ g_return_if_fail(d != NULL);
+
+ if (d->grabseq) {
+ spice_grab_sequence_free(d->grabseq);
+ }
+ if (seq)
+ d->grabseq = spice_grab_sequence_copy(seq);
+ else
+ d->grabseq = spice_grab_sequence_new_from_string("Control_L+Alt_L");
+ g_free(d->activeseq);
+ d->activeseq = g_new0(gboolean, d->grabseq->nkeysyms);
+}
+
+#ifdef G_OS_WIN32
+static LRESULT CALLBACK keyboard_hook_cb(int code, WPARAM wparam, LPARAM lparam)
+{
+ if (win32_window && code == HC_ACTION && wparam != WM_KEYUP) {
+ KBDLLHOOKSTRUCT *hooked = (KBDLLHOOKSTRUCT*)lparam;
+ DWORD dwmsg = (hooked->flags << 24) | (hooked->scanCode << 16) | 1;
+
+ if (hooked->vkCode == VK_NUMLOCK || hooked->vkCode == VK_RSHIFT) {
+ dwmsg &= ~(1 << 24);
+ SendMessage(win32_window, wparam, hooked->vkCode, dwmsg);
+ }
+ switch (hooked->vkCode) {
+ case VK_CAPITAL:
+ case VK_SCROLL:
+ case VK_NUMLOCK:
+ case VK_LSHIFT:
+ case VK_RSHIFT:
+ case VK_RCONTROL:
+ case VK_LMENU:
+ case VK_RMENU:
+ break;
+ case VK_LCONTROL:
+ /* When pressing AltGr, an extra VK_LCONTROL with a special
+ * scancode with bit 9 set is sent. Let's ignore the extra
+ * VK_LCONTROL, as that will make AltGr misbehave. */
+ if (hooked->scanCode & 0x200)
+ return 1;
+ break;
+ default:
+ SendMessage(win32_window, wparam, hooked->vkCode, dwmsg);
+ return 1;
+ }
+ }
+ return CallNextHookEx(NULL, code, wparam, lparam);
+}
+#endif
+
+/**
+ * spice_display_get_grab_keys:
+ * @display: the display widget
+ *
+ * Finds the current grab key combination for the @display.
+ *
+ * Returns: (transfer none): the current grab key combination.
+ **/
+SpiceGrabSequence *spice_display_get_grab_keys(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d;
+
+ g_return_val_if_fail(SPICE_IS_DISPLAY(display), NULL);
+
+ d = display->priv;
+ g_return_val_if_fail(d != NULL, NULL);
+
+ return d->grabseq;
+}
+
+static void try_keyboard_grab(SpiceDisplay *display)
+{
+ GtkWidget *widget = GTK_WIDGET(display);
+ SpiceDisplayPrivate *d = display->priv;
+ GdkGrabStatus status;
+
+ if (g_getenv("SPICE_NOGRAB"))
+ return;
+ if (d->disable_inputs)
+ return;
+
+ if (d->keyboard_grab_inhibit)
+ return;
+ if (!d->keyboard_grab_enable)
+ return;
+ if (d->keyboard_grab_active)
+ return;
+ if (!spice_gtk_session_get_keyboard_has_focus(d->gtk_session))
+ return;
+ if (!spice_gtk_session_get_mouse_has_pointer(d->gtk_session))
+ return;
+ if (d->keyboard_grab_released)
+ return;
+
+ g_return_if_fail(gtk_widget_is_focus(widget));
+
+ SPICE_DEBUG("grab keyboard");
+ gtk_widget_grab_focus(widget);
+
+#ifdef G_OS_WIN32
+ if (d->keyboard_hook == NULL)
+ d->keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_hook_cb,
+ GetModuleHandle(NULL), 0);
+ g_warn_if_fail(d->keyboard_hook != NULL);
+#endif
+ status = gdk_keyboard_grab(gtk_widget_get_window(widget), FALSE,
+ GDK_CURRENT_TIME);
+ if (status != GDK_GRAB_SUCCESS) {
+ g_warning("keyboard grab failed %u", status);
+ d->keyboard_grab_active = false;
+ } else {
+ d->keyboard_grab_active = true;
+ g_signal_emit(widget, signals[SPICE_DISPLAY_KEYBOARD_GRAB], 0, true);
+ }
+}
+
+static void try_keyboard_ungrab(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ GtkWidget *widget = GTK_WIDGET(display);
+
+ if (!d->keyboard_grab_active)
+ return;
+
+ SPICE_DEBUG("ungrab keyboard");
+ gdk_keyboard_ungrab(GDK_CURRENT_TIME);
+#ifdef G_OS_WIN32
+ // do not use g_clear_pointer as Windows API have different linkage
+ if (d->keyboard_hook) {
+ UnhookWindowsHookEx(d->keyboard_hook);
+ d->keyboard_hook = NULL;
+ }
+#endif
+ d->keyboard_grab_active = false;
+ g_signal_emit(widget, signals[SPICE_DISPLAY_KEYBOARD_GRAB], 0, false);
+}
+
+static void update_keyboard_grab(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+
+ if (d->keyboard_grab_enable &&
+ !d->keyboard_grab_inhibit &&
+ !d->disable_inputs)
+ try_keyboard_grab(display);
+ else
+ try_keyboard_ungrab(display);
+}
+
+static void set_mouse_accel(SpiceDisplay *display, gboolean enabled)
+{
+ SpiceDisplayPrivate *d = display->priv;
+
+#if defined GDK_WINDOWING_X11
+ GdkWindow *w = GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(display)));
+
+ if (!GDK_IS_X11_DISPLAY(gdk_window_get_display(w))) {
+ SPICE_DEBUG("FIXME: gtk backend is not X11");
+ return;
+ }
+
+ Display *x_display = GDK_WINDOW_XDISPLAY(w);
+ if (enabled) {
+ /* restore mouse acceleration */
+ XChangePointerControl(x_display, True, True,
+ d->x11_accel_numerator, d->x11_accel_denominator, d->x11_threshold);
+ } else {
+ XGetPointerControl(x_display,
+ &d->x11_accel_numerator, &d->x11_accel_denominator, &d->x11_threshold);
+ /* set mouse acceleration to default */
+ XChangePointerControl(x_display, True, True, -1, -1, -1);
+ SPICE_DEBUG("disabled X11 mouse motion %d %d %d",
+ d->x11_accel_numerator, d->x11_accel_denominator, d->x11_threshold);
+ }
+#elif defined GDK_WINDOWING_WIN32
+ if (enabled) {
+ g_return_if_fail(SystemParametersInfo(SPI_SETMOUSE, 0, &d->win_mouse, 0));
+ g_return_if_fail(SystemParametersInfo(SPI_SETMOUSESPEED, 0, (PVOID)(INT_PTR)d->win_mouse_speed, 0));
+ } else {
+ int accel[3] = { 0, 0, 0 }; // disabled
+ g_return_if_fail(SystemParametersInfo(SPI_GETMOUSE, 0, &d->win_mouse, 0));
+ g_return_if_fail(SystemParametersInfo(SPI_GETMOUSESPEED, 0, &d->win_mouse_speed, 0));
+ g_return_if_fail(SystemParametersInfo(SPI_SETMOUSE, 0, &accel, SPIF_SENDCHANGE));
+ g_return_if_fail(SystemParametersInfo(SPI_SETMOUSESPEED, 0, (PVOID)10, SPIF_SENDCHANGE)); // default
+ }
+#else
+ g_warning("Mouse acceleration code missing for your platform");
+#endif
+}
+
+#ifdef G_OS_WIN32
+static gboolean win32_clip_cursor(void)
+{
+ RECT window, workarea, rect;
+ HMONITOR monitor;
+ MONITORINFO mi = { 0, };
+
+ g_return_val_if_fail(win32_window != NULL, FALSE);
+
+ if (!GetWindowRect(win32_window, &window))
+ goto error;
+
+ monitor = MonitorFromRect(&window, MONITOR_DEFAULTTONEAREST);
+ g_return_val_if_fail(monitor != NULL, false);
+
+ mi.cbSize = sizeof(mi);
+ if (!GetMonitorInfo(monitor, &mi))
+ goto error;
+ workarea = mi.rcWork;
+
+ if (!IntersectRect(&rect, &window, &workarea)) {
+ g_critical("error clipping cursor");
+ return false;
+ }
+
+ SPICE_DEBUG("clip rect %ld %ld %ld %ld\n",
+ rect.left, rect.right, rect.top, rect.bottom);
+
+ if (!ClipCursor(&rect))
+ goto error;
+
+ return true;
+
+error:
+ {
+ DWORD errval = GetLastError();
+ gchar *errstr = g_win32_error_message(errval);
+ g_warning("failed to clip cursor (%lu) %s", errval, errstr);
+ }
+
+ return false;
+}
+#endif
+
+static gboolean do_pointer_grab(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ GdkWindow *window = GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(display)));
+ GdkGrabStatus status;
+ GdkCursor *blank = get_blank_cursor();
+ gboolean grab_successful = FALSE;
+
+ if (!gtk_widget_get_realized(GTK_WIDGET(display)))
+ goto end;
+
+#ifdef G_OS_WIN32
+ if (!win32_clip_cursor())
+ goto end;
+#endif
+
+ try_keyboard_grab(display);
+ /*
+ * from gtk-vnc:
+ * For relative mouse to work correctly when grabbed we need to
+ * allow the pointer to move anywhere on the local desktop, so
+ * use NULL for the 'confine_to' argument. Furthermore we need
+ * the coords to be reported to our VNC window, regardless of
+ * what window the pointer is actally over, so use 'FALSE' for
+ * 'owner_events' parameter
+ */
+ status = gdk_pointer_grab(window, FALSE,
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_BUTTON_MOTION_MASK |
+ GDK_SCROLL_MASK,
+ NULL,
+ blank,
+ GDK_CURRENT_TIME);
+ grab_successful = (status == GDK_GRAB_SUCCESS);
+ if (!grab_successful) {
+ d->mouse_grab_active = false;
+ g_warning("pointer grab failed %u", status);
+ } else {
+ d->mouse_grab_active = true;
+ g_signal_emit(display, signals[SPICE_DISPLAY_MOUSE_GRAB], 0, true);
+ spice_gtk_session_set_pointer_grabbed(d->gtk_session, true);
+ set_mouse_accel(display, FALSE);
+ }
+
+end:
+ g_object_unref(blank);
+ return grab_successful;
+}
+
+static void update_mouse_pointer(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ GdkWindow *window = GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(display)));
+
+ if (!window)
+ return;
+
+ switch (d->mouse_mode) {
+ case SPICE_MOUSE_MODE_CLIENT:
+ if (gdk_window_get_cursor(window) != d->mouse_cursor)
+ gdk_window_set_cursor(window, d->mouse_cursor);
+ break;
+ case SPICE_MOUSE_MODE_SERVER:
+ if (gdk_window_get_cursor(window) != NULL)
+ gdk_window_set_cursor(window, NULL);
+ break;
+ default:
+ g_warn_if_reached();
+ break;
+ }
+}
+
+static void try_mouse_grab(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+
+ if (g_getenv("SPICE_NOGRAB"))
+ return;
+ if (d->disable_inputs)
+ return;
+
+ if (!d->mouse_have_pointer)
+ return;
+ if (!d->keyboard_have_focus)
+ return;
+
+ if (!d->mouse_grab_enable)
+ return;
+ if (d->mouse_mode != SPICE_MOUSE_MODE_SERVER)
+ return;
+ if (d->mouse_grab_active)
+ return;
+
+ if (!do_pointer_grab(display))
+ return;
+
+ d->mouse_last_x = -1;
+ d->mouse_last_y = -1;
+}
+
+static void mouse_wrap(SpiceDisplay *display, GdkEventMotion *motion)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ gint xr, yr;
+
+#ifdef G_OS_WIN32
+ RECT clip;
+ g_return_if_fail(GetClipCursor(&clip));
+ xr = clip.left + (clip.right - clip.left) / 2;
+ yr = clip.top + (clip.bottom - clip.top) / 2;
+ /* the clip rectangle has no offset, so we can't use gdk_wrap_pointer */
+ SetCursorPos(xr, yr);
+ d->mouse_last_x = -1;
+ d->mouse_last_y = -1;
+#else
+ GdkScreen *screen = gtk_widget_get_screen(GTK_WIDGET(display));
+ xr = gdk_screen_get_width(screen) / 2;
+ yr = gdk_screen_get_height(screen) / 2;
+
+ if (xr != (gint)motion->x_root || yr != (gint)motion->y_root) {
+ /* FIXME: we try our best to ignore that next pointer move event.. */
+ gdk_display_sync(gdk_screen_get_display(screen));
+
+ gdk_display_warp_pointer(gtk_widget_get_display(GTK_WIDGET(display)),
+ screen, xr, yr);
+ d->mouse_last_x = -1;
+ d->mouse_last_y = -1;
+ }
+#endif
+
+}
+
+static void try_mouse_ungrab(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ double s;
+ int x, y;
+
+ if (!d->mouse_grab_active)
+ return;
+
+ gdk_pointer_ungrab(GDK_CURRENT_TIME);
+ gtk_grab_remove(GTK_WIDGET(display));
+#ifdef G_OS_WIN32
+ ClipCursor(NULL);
+#endif
+ set_mouse_accel(display, TRUE);
+
+ d->mouse_grab_active = false;
+
+ spice_display_get_scaling(display, &s, &x, &y, NULL, NULL);
+
+ gdk_window_get_root_coords(gtk_widget_get_window(GTK_WIDGET(display)),
+ x + d->mouse_guest_x * s,
+ y + d->mouse_guest_y * s,
+ &x, &y);
+
+ gdk_display_warp_pointer(gtk_widget_get_display(GTK_WIDGET(display)),
+ gtk_widget_get_screen(GTK_WIDGET(display)),
+ x, y);
+
+ g_signal_emit(display, signals[SPICE_DISPLAY_MOUSE_GRAB], 0, false);
+ spice_gtk_session_set_pointer_grabbed(d->gtk_session, false);
+}
+
+static void update_mouse_grab(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+
+ if (d->mouse_grab_enable &&
+ !d->keyboard_grab_inhibit &&
+ !d->disable_inputs)
+ try_mouse_grab(display);
+ else
+ try_mouse_ungrab(display);
+}
+
+static void recalc_geometry(GtkWidget *widget)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ SpiceDisplayPrivate *d = display->priv;
+ gdouble zoom = 1.0;
+
+ if (spice_cairo_is_scaled(display))
+ zoom = (gdouble)d->zoom_level / 100;
+
+ SPICE_DEBUG("recalc geom monitor: %d:%d, guest +%d+%d:%dx%d, window %dx%d, zoom %g",
+ d->channel_id, d->monitor_id, d->area.x, d->area.y, d->area.width, d->area.height,
+ d->ww, d->wh, zoom);
+
+ if (d->resize_guest_enable)
+ spice_main_set_display(d->main, get_display_id(display),
+ d->area.x, d->area.y, d->ww / zoom, d->wh / zoom);
+}
+
+/* ---------------------------------------------------------------- */
+
+#define CONVERT_0565_TO_0888(s) \
+ (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
+ ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
+ ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
+
+#define CONVERT_0565_TO_8888(s) (CONVERT_0565_TO_0888(s) | 0xff000000)
+
+#define CONVERT_0555_TO_0888(s) \
+ (((((s) & 0x001f) << 3) | (((s) & 0x001c) >> 2)) | \
+ ((((s) & 0x03e0) << 6) | (((s) & 0x0380) << 1)) | \
+ ((((s) & 0x7c00) << 9) | ((((s) & 0x7000)) << 4)))
+
+#define CONVERT_0555_TO_8888(s) (CONVERT_0555_TO_0888(s) | 0xff000000)
+
+static gboolean do_color_convert(SpiceDisplay *display, GdkRectangle *r)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ guint32 *dest = d->canvas.data;
+ guint16 *src = d->canvas.data_origin;
+ gint x, y;
+
+ g_return_val_if_fail(r != NULL, false);
+ g_return_val_if_fail(d->canvas.format == SPICE_SURFACE_FMT_16_555 ||
+ d->canvas.format == SPICE_SURFACE_FMT_16_565, false);
+
+ src += (d->canvas.stride / 2) * r->y + r->x;
+ dest += d->area.width * (r->y - d->area.y) + (r->x - d->area.x);
+
+ if (d->canvas.format == SPICE_SURFACE_FMT_16_555) {
+ for (y = 0; y < r->height; y++) {
+ for (x = 0; x < r->width; x++) {
+ dest[x] = CONVERT_0555_TO_0888(src[x]);
+ }
+
+ dest += d->area.width;
+ src += d->canvas.stride / 2;
+ }
+ } else if (d->canvas.format == SPICE_SURFACE_FMT_16_565) {
+ for (y = 0; y < r->height; y++) {
+ for (x = 0; x < r->width; x++) {
+ dest[x] = CONVERT_0565_TO_0888(src[x]);
+ }
+
+ dest += d->area.width;
+ src += d->canvas.stride / 2;
+ }
+ }
+
+ return true;
+}
+
+#ifndef G_OS_WIN32
+static void set_egl_enabled(SpiceDisplay *display, bool enabled)
+{
+ SpiceDisplayPrivate *d = display->priv;
+
+ if (egl_enabled(d) == enabled)
+ return;
+
+#ifdef GDK_WINDOWING_X11
+ if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
+ /* even though the function is marked as deprecated, it's the
+ * only way I found to prevent glitches when the window is
+ * resized. */
+ GtkWidget *area = gtk_stack_get_child_by_name(d->stack, "draw-area");
+ gtk_widget_set_double_buffered(GTK_WIDGET(area), !enabled);
+ } else
+#endif
+ {
+ gtk_stack_set_visible_child_name(d->stack,
+ enabled ? "gl-area" : "draw-area");
+ }
+
+ if (enabled) {
+ spice_egl_resize_display(display, d->ww, d->wh);
+ }
+
+ d->egl.enabled = enabled;
+}
+#endif
+
+static gboolean draw_event(GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(data);
+ SpiceDisplayPrivate *d = display->priv;
+ g_return_val_if_fail(d != NULL, false);
+
+#ifndef G_OS_WIN32
+ if (egl_enabled(d) &&
+ g_str_equal(gtk_stack_get_visible_child_name(d->stack), "draw-area")) {
+ spice_egl_update_display(display);
+ return false;
+ }
+#endif
+
+ if (d->mark == 0 || d->canvas.data == NULL ||
+ d->area.width == 0 || d->area.height == 0)
+ return false;
+
+ spice_cairo_draw_event(display, cr);
+ update_mouse_pointer(display);
+
+ return true;
+}
+
+/* ---------------------------------------------------------------- */
+typedef enum {
+ SEND_KEY_PRESS,
+ SEND_KEY_RELEASE,
+} SendKeyType;
+
+static void key_press_and_release(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+
+ if (d->key_delayed_scancode == 0)
+ return;
+
+ spice_inputs_key_press_and_release(d->inputs, d->key_delayed_scancode);
+ d->key_delayed_scancode = 0;
+
+ if (d->key_delayed_id) {
+ g_source_remove(d->key_delayed_id);
+ d->key_delayed_id = 0;
+ }
+}
+
+static gboolean key_press_delayed(gpointer data)
+{
+ SpiceDisplay *display = data;
+ SpiceDisplayPrivate *d = display->priv;
+
+ if (d->key_delayed_scancode == 0)
+ return FALSE;
+
+ spice_inputs_key_press(d->inputs, d->key_delayed_scancode);
+ d->key_delayed_scancode = 0;
+
+ if (d->key_delayed_id) {
+ g_source_remove(d->key_delayed_id);
+ d->key_delayed_id = 0;
+ }
+
+ return FALSE;
+}
+
+static bool send_pause(SpiceDisplay *display, GdkEventType type)
+{
+ SpiceInputsChannel *inputs = display->priv->inputs;
+
+ /* Send proper scancodes. This will send same scancodes
+ * as hardware.
+ * The 0x21d is a sort of Third-Ctrl while
+ * 0x45 is the NumLock.
+ */
+ if (type == GDK_KEY_PRESS) {
+ spice_inputs_key_press(inputs, 0x21d);
+ spice_inputs_key_press(inputs, 0x45);
+ } else {
+ spice_inputs_key_release(inputs, 0x21d);
+ spice_inputs_key_release(inputs, 0x45);
+ }
+ return true;
+}
+
+static void send_key(SpiceDisplay *display, int scancode, SendKeyType type, gboolean press_delayed)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ uint32_t i, b, m;
+
+ g_return_if_fail(scancode != 0);
+
+ if (!d->inputs)
+ return;
+
+ if (d->disable_inputs)
+ return;
+
+ i = scancode / 32;
+ b = scancode % 32;
+ m = (1 << b);
+ g_return_if_fail(i < SPICE_N_ELEMENTS(d->key_state));
+
+ switch (type) {
+ case SEND_KEY_PRESS:
+ /* ensure delayed key is pressed before any new input event */
+ key_press_delayed(display);
+
+ if (press_delayed &&
+ d->keypress_delay != 0 &&
+ !(d->key_state[i] & m)) {
+ g_warn_if_fail(d->key_delayed_id == 0);
+ d->key_delayed_id = g_timeout_add(d->keypress_delay, key_press_delayed, display);
+ d->key_delayed_scancode = scancode;
+ } else
+ spice_inputs_key_press(d->inputs, scancode);
+
+ d->key_state[i] |= m;
+ break;
+
+ case SEND_KEY_RELEASE:
+ if (!(d->key_state[i] & m))
+ break;
+
+ if (d->key_delayed_scancode == scancode)
+ key_press_and_release(display);
+ else {
+ /* ensure delayed key is pressed before other key are released */
+ key_press_delayed(display);
+ spice_inputs_key_release(d->inputs, scancode);
+ }
+
+ d->key_state[i] &= ~m;
+ break;
+
+ default:
+ g_warn_if_reached();
+ }
+}
+
+static void release_keys(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ uint32_t i, b;
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+ for (i = 0; i < SPICE_N_ELEMENTS(d->key_state); i++) {
+ if (!d->key_state[i]) {
+ continue;
+ }
+ for (b = 0; b < 32; b++) {
+ unsigned int scancode = i * 32 + b;
+ if (scancode != 0) {
+ send_key(display, scancode, SEND_KEY_RELEASE, FALSE);
+ }
+ }
+ }
+}
+
+static gboolean check_for_grab_key(SpiceDisplay *display, int type, int keyval,
+ int check_type, int reset_type)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ int i;
+
+ if (!d->grabseq->nkeysyms)
+ return FALSE;
+
+ if (type == check_type) {
+ /* Record the new key */
+ for (i = 0 ; i < d->grabseq->nkeysyms ; i++)
+ if (d->grabseq->keysyms[i] == keyval)
+ d->activeseq[i] = TRUE;
+
+ /* Return if any key is missing */
+ for (i = 0 ; i < d->grabseq->nkeysyms ; i++)
+ if (d->activeseq[i] == FALSE)
+ return FALSE;
+
+ /* resets the whole grab sequence on success */
+ memset(d->activeseq, 0, sizeof(gboolean) * d->grabseq->nkeysyms);
+ return TRUE;
+ } else if (type == reset_type) {
+ /* reset key event type resets the whole grab sequence */
+ memset(d->activeseq, 0, sizeof(gboolean) * d->grabseq->nkeysyms);
+ d->seq_pressed = FALSE;
+ return FALSE;
+ } else
+ g_warn_if_reached();
+
+ return FALSE;
+}
+
+static gboolean check_for_grab_key_pressed(SpiceDisplay *display, int type, int keyval)
+{
+ return check_for_grab_key(display, type, keyval, GDK_KEY_PRESS, GDK_KEY_RELEASE);
+}
+
+static gboolean check_for_grab_key_released(SpiceDisplay *display, int type, int keyval)
+{
+ return check_for_grab_key(display, type, keyval, GDK_KEY_RELEASE, GDK_KEY_PRESS);
+}
+
+static void update_display(SpiceDisplay *display)
+{
+#ifdef G_OS_WIN32
+ win32_window = display ?
+ gdk_win32_window_get_impl_hwnd(gtk_widget_get_window(GTK_WIDGET(display))) :
+ NULL;
+#endif
+}
+
+static gboolean key_event(GtkWidget *widget, GdkEventKey *key)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ SpiceDisplayPrivate *d = display->priv;
+ int scancode = 0;
+#ifdef G_OS_WIN32
+ int native_scancode;
+ WORD langid = LOWORD(GetKeyboardLayout(0));
+ gboolean no_key_release = FALSE;
+#endif
+
+#ifdef G_OS_WIN32
+ /* Try to get scancode with gdk_event_get_scancode.
+ * This API is available from 3.22 or if backported.
+ */
+#if HAVE_GDK_EVENT_GET_SCANCODE
+ native_scancode = gdk_event_get_scancode((GdkEvent *) key);
+ if (native_scancode) {
+ scancode = native_scancode & 0x1ff;
+ /* Windows always set extended attribute for these keys */
+ if (scancode == (0x100|DIK_NUMLOCK) || scancode == (0x100|DIK_RSHIFT))
+ scancode &= 0xff;
+ }
+#else
+ native_scancode = 0;
+#endif
+
+ /* on windows, we ought to ignore the reserved key event? */
+ if (!native_scancode && key->hardware_keycode == 0xff)
+ return false;
+
+ if (!d->keyboard_grab_active) {
+ if (key->hardware_keycode == VK_LWIN ||
+ key->hardware_keycode == VK_RWIN ||
+ key->hardware_keycode == VK_APPS)
+ return false;
+ }
+
+#endif
+ SPICE_DEBUG("%s %s: keycode: %d state: %u group %d modifier %d",
+ __FUNCTION__, key->type == GDK_KEY_PRESS ? "press" : "release",
+ key->hardware_keycode, key->state, key->group, key->is_modifier);
+
+ if (!d->seq_pressed && check_for_grab_key_pressed(display, key->type, key->keyval)) {
+ g_signal_emit(widget, signals[SPICE_DISPLAY_GRAB_KEY_PRESSED], 0);
+
+ if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER) {
+ if (d->mouse_grab_active)
+ try_mouse_ungrab(display);
+ else
+ try_mouse_grab(display);
+ }
+ d->seq_pressed = TRUE;
+ } else if (d->seq_pressed && check_for_grab_key_released(display, key->type, key->keyval)) {
+ release_keys(display);
+ if (!d->keyboard_grab_released) {
+ d->keyboard_grab_released = TRUE;
+ try_keyboard_ungrab(display);
+ } else {
+ d->keyboard_grab_released = FALSE;
+ try_keyboard_grab(display);
+ }
+ d->seq_pressed = FALSE;
+ }
+
+ if (!d->inputs)
+ return true;
+
+ if (key->keyval == GDK_KEY_Pause
+#ifdef G_OS_WIN32
+ /* for some reason GDK does not fill keyval for VK_PAUSE
+ * See https://bugzilla.gnome.org/show_bug.cgi?id=769214
+ */
+ || key->hardware_keycode == VK_PAUSE
+#endif
+ ) {
+ return send_pause(display, key->type);
+ }
+ if (!scancode)
+ scancode = vnc_display_keymap_gdk2xtkbd(d->keycode_map, d->keycode_maplen,
+ key->hardware_keycode);
+#ifdef G_OS_WIN32
+ if (!native_scancode) {
+ native_scancode = MapVirtualKey(key->hardware_keycode, MAPVK_VK_TO_VSC);
+ /* MapVirtualKey doesn't return scancode with needed higher byte */
+ scancode = native_scancode | (scancode & 0xff00);
+ }
+
+ /* Some virtual-key codes are missed in MapVirtualKey(). */
+ switch (langid) {
+ case MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN):
+ if (native_scancode == 0) {
+ switch (key->hardware_keycode) {
+ case VK_DBE_DBCSCHAR: /* from Pressed Zenkaku_Hankaku */
+ case VK_KANJI: /* from Alt + Zenkaku_Hankaku */
+ case VK_DBE_ENTERIMECONFIGMODE:
+ /* from Ctrl+Alt+Zenkaku_Hankaku */
+ scancode = MapVirtualKey(VK_DBE_SBCSCHAR, MAPVK_VK_TO_VSC);
+ /* to Released Zenkaku_Hankaku */
+ break;
+ case VK_CAPITAL: /* from Shift + Eisu_toggle */
+ case VK_DBE_CODEINPUT: /* from Pressed Ctrl+Alt+Eisu_toggle */
+ case VK_DBE_NOCODEINPUT: /* from Released Ctrl+Alt+Eisu_toggle */
+ scancode = MapVirtualKey(VK_DBE_ALPHANUMERIC, MAPVK_VK_TO_VSC);
+ /* to Eisu_toggle */
+ break;
+ case VK_DBE_ROMAN: /* from Pressed Alt+Hiragana_Katakana */
+ case VK_KANA: /* from Ctrl+Shift+Hiragana_Katakana */
+ scancode = MapVirtualKey(VK_DBE_HIRAGANA, MAPVK_VK_TO_VSC);
+ /* to Hiragana_Katakana */
+ break;
+ case VK_DBE_ENTERWORDREGISTERMODE:
+ /* from Ctrl + Alt + Muhenkan */
+ scancode = MapVirtualKey(VK_NONCONVERT, MAPVK_VK_TO_VSC);
+ /* to Muhenkan */
+ break;
+ }
+ }
+ break;
+ case MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN):
+ if (key->hardware_keycode == VK_HANGUL && native_scancode == DIK_LALT) {
+ /* Left Alt (VK_MENU) has the scancode DIK_LALT (0x38) but
+ * Hangul (VK_HANGUL) has the scancode 0x138
+ */
+ scancode = native_scancode | 0x100;
+ }
+ break;
+ }
+
+ /* Emulate KeyRelease events for the following keys.
+ *
+ * Alt+Zenkaku_Hankaku generates WM_KEYDOWN VK_KANJI and no WM_KEYUP
+ * and it caused unlimited VK_KANJI in Linux desktop and the desktop
+ * hung up. We send WM_KEYUP VK_KANJI here to avoid unlimited events.
+ *
+ * Eisu_toggle generates WM_KEYDOWN VK_DBE_ALPHANUMERIC only in
+ * English mode, WM_KEYDOWN VK_DBE_ALPHANUMERIC and WM_KEYUP
+ * VK_DBE_HIRAGANA in Japanese mode, and it caused unlimited
+ * VK_DBE_ALPHANUMERIC in Linux desktop.
+ * Since VK_DBE_HIRAGANA is also assigned in Hiragana key,
+ * we send WM_KEYUP VK_DBE_ALPHANUMERIC here to avoid unlimited events.
+ * No KeyPress VK_DBE_HIRAGANA seems harmless.
+ *
+ * Hiragana_Katakana generates WM_KEYDOWN VK_DBE_HIRAGANA and
+ * WM_KEYUP VK_DBE_ALPHANUMERIC in English mode, WM_KEYDOWN
+ * VK_DBE_HIRAGANA only in Japanese mode, and it caused unlimited
+ * VK_DBE_HIRAGANA in Linux desktop.
+ *
+ * Alt+Hiragana_Katakana generates WM_KEYUP VK_DBE_NOROMAN and
+ * WM_KEYDOWN VK_DBE_ROMAN but the KeyRelease is called before
+ * KeyDown is called and it caused unlimited VK_DBE_ROMAN.
+ * We ignore the scancode of VK_DBE_NOROMAN and emulate WM_KEYUP
+ * VK_DBE_ROMAN.
+ *
+ * Ctrl+Alt+Zenkaku_Hankaku generates WM_KEYDOWN VK_DBE_ENTERIMECONFIGMODE
+ * and no WM_KEYUP and it caused unlimited VK_DBE_ENTERIMECONFIGMODE
+ * in Linux desktop.
+ */
+ switch (langid) {
+ case MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN):
+ switch (key->hardware_keycode) {
+ case VK_KANJI: /* Alt + Zenkaku_Hankaku */
+ case VK_DBE_ALPHANUMERIC: /* Eisu_toggle */
+ case VK_DBE_HIRAGANA: /* Hiragana_Katakana */
+ case VK_DBE_ROMAN: /* Alt+Hiragana_Katakana */
+ case VK_DBE_ENTERIMECONFIGMODE: /* Ctrl + Alt + Zenkaku_Hankaku */
+ no_key_release = TRUE;
+ break;
+ }
+ break;
+ }
+#endif
+
+ switch (key->type) {
+ case GDK_KEY_PRESS:
+ send_key(display, scancode, SEND_KEY_PRESS, !key->is_modifier);
+#ifdef G_OS_WIN32
+ if (no_key_release)
+ send_key(display, scancode, SEND_KEY_RELEASE, !key->is_modifier);
+#endif
+ break;
+ case GDK_KEY_RELEASE:
+ send_key(display, scancode, SEND_KEY_RELEASE, !key->is_modifier);
+ break;
+ default:
+ g_warn_if_reached();
+ break;
+ }
+
+ return true;
+}
+
+static guint get_scancode_from_keyval(SpiceDisplay *display, guint keyval)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ guint keycode = 0;
+ GdkKeymapKey *keys = NULL;
+ gint n_keys = 0;
+
+ if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(),
+ keyval, &keys, &n_keys)) {
+ /* FIXME what about levels? */
+ keycode = keys[0].keycode;
+ g_free(keys);
+ } else {
+ g_warning("could not lookup keyval %u, please report a bug", keyval);
+ return 0;
+ }
+
+ return vnc_display_keymap_gdk2xtkbd(d->keycode_map, d->keycode_maplen, keycode);
+}
+
+
+/**
+ * spice_display_send_keys:
+ * @display: The #SpiceDisplay
+ * @keyvals: (array length=nkeyvals): Keyval array
+ * @nkeyvals: Length of keyvals
+ * @kind: #SpiceDisplayKeyEvent action
+ *
+ * Send keyval press/release events to the display.
+ *
+ **/
+void spice_display_send_keys(SpiceDisplay *display, const guint *keyvals,
+ int nkeyvals, SpiceDisplayKeyEvent kind)
+{
+ int i;
+
+ g_return_if_fail(SPICE_IS_DISPLAY(display));
+ g_return_if_fail(keyvals != NULL);
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+
+ if (kind & SPICE_DISPLAY_KEY_EVENT_PRESS) {
+ for (i = 0 ; i < nkeyvals ; i++)
+ send_key(display, get_scancode_from_keyval(display, keyvals[i]), SEND_KEY_PRESS, FALSE);
+ }
+
+ if (kind & SPICE_DISPLAY_KEY_EVENT_RELEASE) {
+ for (i = (nkeyvals-1) ; i >= 0 ; i--)
+ send_key(display, get_scancode_from_keyval(display, keyvals[i]), SEND_KEY_RELEASE, FALSE);
+ }
+}
+
+static gboolean enter_event(GtkWidget *widget, GdkEventCrossing *crossing G_GNUC_UNUSED)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ SpiceDisplayPrivate *d = display->priv;
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+
+ d->mouse_have_pointer = true;
+ spice_gtk_session_set_mouse_has_pointer(d->gtk_session, true);
+ try_keyboard_grab(display);
+ update_display(display);
+
+ return true;
+}
+
+static gboolean leave_event(GtkWidget *widget, GdkEventCrossing *crossing G_GNUC_UNUSED)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ SpiceDisplayPrivate *d = display->priv;
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+
+ if (d->mouse_grab_active)
+ return true;
+
+ d->mouse_have_pointer = false;
+ spice_gtk_session_set_mouse_has_pointer(d->gtk_session, false);
+ try_keyboard_ungrab(display);
+
+ return true;
+}
+
+static gboolean focus_in_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSED)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ SpiceDisplayPrivate *d = display->priv;
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+
+ /*
+ * Ignore focus in when we already have the focus
+ * (this happens when doing an ungrab from the leave_event callback).
+ */
+ if (d->keyboard_have_focus)
+ return true;
+
+ release_keys(display);
+#ifdef G_OS_WIN32
+ /* Reset the IME context of the focused window.
+ * Note that the focused window can be different from SpiceDisplay
+ * one but the events are received and forwarder by this window. */
+ HWND hwnd_focused = GetFocus();
+ if (hwnd_focused != NULL) {
+ ImmAssociateContext(hwnd_focused, NULL);
+ }
+#endif
+ if (!d->disable_inputs)
+ spice_gtk_session_sync_keyboard_modifiers(d->gtk_session);
+ if (d->keyboard_grab_released)
+ memset(d->activeseq, 0, sizeof(gboolean) * d->grabseq->nkeysyms);
+ update_keyboard_focus(display, true);
+ try_keyboard_grab(display);
+
+ if (gtk_widget_get_realized(widget))
+ update_display(display);
+
+ return true;
+}
+
+static gboolean focus_out_event(GtkWidget *widget, GdkEventFocus *focus G_GNUC_UNUSED)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ SpiceDisplayPrivate *d = display->priv;
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+ update_display(NULL);
+
+ /*
+ * Ignore focus out after a keyboard grab
+ * (this happens when doing the grab from the enter_event callback).
+ */
+ if (d->keyboard_grab_active)
+ return true;
+
+ release_keys(display);
+ update_keyboard_focus(display, false);
+
+ return true;
+}
+
+static int button_gdk_to_spice(guint gdk)
+{
+ static const int map[] = {
+ [ 1 ] = SPICE_MOUSE_BUTTON_LEFT,
+ [ 2 ] = SPICE_MOUSE_BUTTON_MIDDLE,
+ [ 3 ] = SPICE_MOUSE_BUTTON_RIGHT,
+ [ 4 ] = SPICE_MOUSE_BUTTON_UP,
+ [ 5 ] = SPICE_MOUSE_BUTTON_DOWN,
+ };
+
+ if (gdk < SPICE_N_ELEMENTS(map)) {
+ return map [ gdk ];
+ }
+ return 0;
+}
+
+static int button_mask_gdk_to_spice(int gdk)
+{
+ int spice = 0;
+
+ if (gdk & GDK_BUTTON1_MASK)
+ spice |= SPICE_MOUSE_BUTTON_MASK_LEFT;
+ if (gdk & GDK_BUTTON2_MASK)
+ spice |= SPICE_MOUSE_BUTTON_MASK_MIDDLE;
+ if (gdk & GDK_BUTTON3_MASK)
+ spice |= SPICE_MOUSE_BUTTON_MASK_RIGHT;
+ return spice;
+}
+
+static void transform_input(SpiceDisplay *display,
+ double window_x, double window_y,
+ int *input_x, int *input_y)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ int display_x, display_y, display_w, display_h;
+ double is;
+
+ spice_display_get_scaling(display, NULL,
+ &display_x, &display_y,
+ &display_w, &display_h);
+
+ /* For input we need a different scaling factor in order to
+ be able to reach the full width of a display. For instance, consider
+ a display of 100 pixels showing in a window 10 pixels wide. The normal
+ scaling factor here would be 100/10==10, but if you then take the largest
+ possible window coordinate, i.e. 9 and multiply by 10 you get 90, not 99,
+ which is the max display coord.
+
+ If you want to be able to reach the last pixel in the window you need
+ max_window_x * input_scale == max_display_x, which is
+ (window_width - 1) * input_scale == (display_width - 1)
+
+ Note, this is the inverse of s (i.e. s ~= 1/is) as we're converting the
+ coordinates in the inverse direction (window -> display) as the fb size
+ (display -> window).
+ */
+ is = (double)(d->area.width-1) / (double)(display_w-1);
+
+ window_x -= display_x;
+ window_y -= display_y;
+
+ *input_x = floor (window_x * is);
+ *input_y = floor (window_y * is);
+}
+
+static gboolean motion_event(GtkWidget *widget, GdkEventMotion *motion)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ SpiceDisplayPrivate *d = display->priv;
+ int x, y;
+
+ if (!d->inputs)
+ return true;
+ if (d->disable_inputs)
+ return true;
+
+ d->seq_pressed = FALSE;
+
+ if (d->keyboard_grab_released && d->keyboard_have_focus) {
+ d->keyboard_grab_released = FALSE;
+ release_keys(display);
+ try_keyboard_grab(display);
+ }
+
+ transform_input(display, motion->x, motion->y, &x, &y);
+
+ switch (d->mouse_mode) {
+ case SPICE_MOUSE_MODE_CLIENT:
+ if (x >= 0 && x < d->area.width &&
+ y >= 0 && y < d->area.height) {
+ spice_inputs_position(d->inputs, x, y, get_display_id(display),
+ button_mask_gdk_to_spice(motion->state));
+ }
+ break;
+ case SPICE_MOUSE_MODE_SERVER:
+ if (d->mouse_grab_active) {
+ gint dx = d->mouse_last_x != -1 ? x - d->mouse_last_x : 0;
+ gint dy = d->mouse_last_y != -1 ? y - d->mouse_last_y : 0;
+
+ spice_inputs_motion(d->inputs, dx, dy,
+ button_mask_gdk_to_spice(motion->state));
+
+ d->mouse_last_x = x;
+ d->mouse_last_y = y;
+ if (dx != 0 || dy != 0)
+ mouse_wrap(display, motion);
+ }
+ break;
+ default:
+ g_warn_if_reached();
+ break;
+ }
+ return true;
+}
+
+static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *scroll)
+{
+ int button;
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ SpiceDisplayPrivate *d = display->priv;
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+
+ if (!d->inputs)
+ return true;
+ if (d->disable_inputs)
+ return true;
+
+ if (scroll->direction == GDK_SCROLL_UP)
+ button = SPICE_MOUSE_BUTTON_UP;
+ else if (scroll->direction == GDK_SCROLL_DOWN)
+ button = SPICE_MOUSE_BUTTON_DOWN;
+ else {
+ SPICE_DEBUG("unsupported scroll direction");
+ return true;
+ }
+
+ spice_inputs_button_press(d->inputs, button,
+ button_mask_gdk_to_spice(scroll->state));
+ spice_inputs_button_release(d->inputs, button,
+ button_mask_gdk_to_spice(scroll->state));
+ return true;
+}
+
+static gboolean button_event(GtkWidget *widget, GdkEventButton *button)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ SpiceDisplayPrivate *d = display->priv;
+ int x, y;
+
+ SPICE_DEBUG("%s %s: button %u, state 0x%x", __FUNCTION__,
+ button->type == GDK_BUTTON_PRESS ? "press" : "release",
+ button->button, button->state);
+
+ if (d->disable_inputs)
+ return true;
+
+ transform_input(display, button->x, button->y, &x, &y);
+ if ((x < 0 || x >= d->area.width ||
+ y < 0 || y >= d->area.height) &&
+ d->mouse_mode == SPICE_MOUSE_MODE_CLIENT) {
+ /* rule out clicks in outside region */
+ return true;
+ }
+
+ gtk_widget_grab_focus(widget);
+ if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER) {
+ if (!d->mouse_grab_active) {
+ try_mouse_grab(display);
+ return true;
+ }
+ } else
+ /* allow to drag and drop between windows/displays:
+
+ By default, X (and other window system) do a pointer grab
+ when you press a button, so that the release event is
+ received by the same window regardless of where the pointer
+ is. Here, we change that behaviour, so that you can press
+ and release in two differents displays. This is only
+ supported in client mouse mode.
+
+ FIXME: should be multiple widget grab, but how?
+ or should know the position of the other widgets?
+ */
+ gdk_pointer_ungrab(GDK_CURRENT_TIME);
+
+ if (!d->inputs)
+ return true;
+
+ switch (button->type) {
+ case GDK_BUTTON_PRESS:
+ spice_inputs_button_press(d->inputs,
+ button_gdk_to_spice(button->button),
+ button_mask_gdk_to_spice(button->state));
+ break;
+ case GDK_BUTTON_RELEASE:
+ spice_inputs_button_release(d->inputs,
+ button_gdk_to_spice(button->button),
+ button_mask_gdk_to_spice(button->state));
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+static void size_allocate(GtkWidget *widget, GtkAllocation *conf, gpointer data)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ SpiceDisplayPrivate *d = display->priv;
+
+ if (conf->width == d->ww && conf->height == d->wh &&
+ conf->x == d->mx && conf->y == d->my) {
+ return;
+ }
+
+ if (conf->width != d->ww || conf->height != d->wh) {
+ d->ww = conf->width;
+ d->wh = conf->height;
+ recalc_geometry(widget);
+#ifndef G_OS_WIN32
+ if (egl_enabled(d))
+ spice_egl_resize_display(display, conf->width, conf->height);
+#endif
+ }
+
+ d->mx = conf->x;
+ d->my = conf->y;
+
+#ifdef G_OS_WIN32
+ if (d->mouse_grab_active) {
+ try_mouse_ungrab(display);
+ try_mouse_grab(display);
+ }
+#endif
+}
+
+static void update_image(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+
+ spice_cairo_image_create(display);
+ if (d->canvas.convert)
+ do_color_convert(display, &d->area);
+}
+
+static void realize(GtkWidget *widget)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(widget);
+ SpiceDisplayPrivate *d = display->priv;
+
+ GTK_WIDGET_CLASS(spice_display_parent_class)->realize(widget);
+
+ d->keycode_map =
+ vnc_display_keymap_gdk2xtkbd_table(gtk_widget_get_window(widget),
+ &d->keycode_maplen);
+
+ update_image(display);
+}
+
+static void unrealize(GtkWidget *widget)
+{
+ spice_cairo_image_destroy(SPICE_DISPLAY(widget));
+#ifndef G_OS_WIN32
+ spice_egl_unrealize_display(SPICE_DISPLAY(widget));
+#endif
+
+ GTK_WIDGET_CLASS(spice_display_parent_class)->unrealize(widget);
+}
+
+
+/* ---------------------------------------------------------------- */
+
+static void spice_display_class_init(SpiceDisplayClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS(klass);
+
+ gtkwidget_class->key_press_event = key_event;
+ gtkwidget_class->key_release_event = key_event;
+ gtkwidget_class->enter_notify_event = enter_event;
+ gtkwidget_class->leave_notify_event = leave_event;
+ gtkwidget_class->focus_in_event = focus_in_event;
+ gtkwidget_class->focus_out_event = focus_out_event;
+ gtkwidget_class->motion_notify_event = motion_event;
+ gtkwidget_class->button_press_event = button_event;
+ gtkwidget_class->button_release_event = button_event;
+ gtkwidget_class->scroll_event = scroll_event;
+ gtkwidget_class->realize = realize;
+ gtkwidget_class->unrealize = unrealize;
+
+ gobject_class->constructor = spice_display_constructor;
+ gobject_class->dispose = spice_display_dispose;
+ gobject_class->finalize = spice_display_finalize;
+ gobject_class->get_property = spice_display_get_property;
+ gobject_class->set_property = spice_display_set_property;
+
+ /**
+ * SpiceDisplay:session:
+ *
+ * #SpiceSession for this #SpiceDisplay
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_SESSION,
+ g_param_spec_object("session",
+ "Session",
+ "SpiceSession",
+ SPICE_TYPE_SESSION,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceDisplay:channel-id:
+ *
+ * channel-id for this #SpiceDisplay
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_CHANNEL_ID,
+ g_param_spec_int("channel-id",
+ "Channel ID",
+ "Channel ID for this display",
+ 0, 255, 0,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_KEYBOARD_GRAB,
+ g_param_spec_boolean("grab-keyboard",
+ "Grab Keyboard",
+ "Whether we should grab the keyboard.",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_MOUSE_GRAB,
+ g_param_spec_boolean("grab-mouse",
+ "Grab Mouse",
+ "Whether we should grab the mouse.",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_RESIZE_GUEST,
+ g_param_spec_boolean("resize-guest",
+ "Resize guest",
+ "Try to adapt guest display on window resize. "
+ "Requires guest cooperation.",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceDisplay:ready:
+ *
+ * Indicate whether the display is ready to be shown. It takes
+ * into account several conditions, such as the channel display
+ * "mark" state, whether the monitor area is visible..
+ *
+ * Since: 0.13
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_READY,
+ g_param_spec_boolean("ready",
+ "Ready",
+ "Ready to display",
+ FALSE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property
+ (gobject_class, PROP_SCALING,
+ g_param_spec_boolean("scaling", "Scaling",
+ "Whether we should use scaling",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceDisplay:only-downscale:
+ *
+ * If scaling, only scale down, never up.
+ *
+ * Since: 0.14
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_ONLY_DOWNSCALE,
+ g_param_spec_boolean("only-downscale", "Only Downscale",
+ "If scaling, only scale down, never up",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceDisplay:keypress-delay:
+ *
+ * Delay in ms of non-modifiers key press events. If the key is
+ * released before this delay, a single press & release event is
+ * sent to the server. If the key is pressed longer than the
+ * keypress-delay, the server will receive the delayed press
+ * event, and a following release event when the key is released.
+ *
+ * Since: 0.13
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_KEYPRESS_DELAY,
+ g_param_spec_uint("keypress-delay", "Keypress delay",
+ "Keypress delay",
+ 0, G_MAXUINT, DEFAULT_KEYPRESS_DELAY,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceDisplay:disable-inputs:
+ *
+ * Disable all keyboard & mouse inputs.
+ *
+ * Since: 0.8
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_DISABLE_INPUTS,
+ g_param_spec_boolean("disable-inputs", "Disable inputs",
+ "Whether inputs should be disabled",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+
+ /**
+ * SpiceDisplay:zoom-level:
+ *
+ * Zoom level in percentage, from 10 to 400. Default to 100.
+ * (this option is only supported with cairo backend when scaling
+ * is enabled)
+ *
+ * Since: 0.10
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_ZOOM_LEVEL,
+ g_param_spec_int("zoom-level", "Zoom Level",
+ "Zoom Level",
+ 10, 400, 100,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceDisplay:monitor-id:
+ *
+ * Select monitor from #SpiceDisplay to show.
+ * The value -1 means the whole display is shown.
+ * By default, the monitor 0 is selected.
+ *
+ * Since: 0.13
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_MONITOR_ID,
+ g_param_spec_int("monitor-id",
+ "Monitor ID",
+ "Select monitor ID",
+ -1, G_MAXINT, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceDisplay::mouse-grab:
+ * @display: the #SpiceDisplay that emitted the signal
+ * @status: 1 if grabbed, 0 otherwise.
+ *
+ * Notify when the mouse grab is active or not.
+ **/
+ signals[SPICE_DISPLAY_MOUSE_GRAB] =
+ g_signal_new("mouse-grab",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceDisplayClass, mouse_grab),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+
+ /**
+ * SpiceDisplay::keyboard-grab:
+ * @display: the #SpiceDisplay that emitted the signal
+ * @status: 1 if grabbed, 0 otherwise.
+ *
+ * Notify when the keyboard grab is active or not.
+ **/
+ signals[SPICE_DISPLAY_KEYBOARD_GRAB] =
+ g_signal_new("keyboard-grab",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceDisplayClass, keyboard_grab),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
+
+ /**
+ * SpiceDisplay::grab-keys-pressed:
+ * @display: the #SpiceDisplay that emitted the signal
+ *
+ * Notify when the grab keys have been pressed
+ **/
+ signals[SPICE_DISPLAY_GRAB_KEY_PRESSED] =
+ g_signal_new("grab-keys-pressed",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceDisplayClass, keyboard_grab),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ g_type_class_add_private(klass, sizeof(SpiceDisplayPrivate));
+}
+
+/* ---------------------------------------------------------------- */
+
+#define SPICE_GDK_BUTTONS_MASK \
+ (GDK_BUTTON1_MASK|GDK_BUTTON2_MASK|GDK_BUTTON3_MASK|GDK_BUTTON4_MASK|GDK_BUTTON5_MASK)
+
+static void update_mouse_mode(SpiceChannel *channel, gpointer data)
+{
+ SpiceDisplay *display = data;
+ SpiceDisplayPrivate *d = display->priv;
+ GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(display));
+
+ g_object_get(channel, "mouse-mode", &d->mouse_mode, NULL);
+ SPICE_DEBUG("mouse mode %u", d->mouse_mode);
+
+ switch (d->mouse_mode) {
+ case SPICE_MOUSE_MODE_CLIENT:
+ try_mouse_ungrab(display);
+ break;
+ case SPICE_MOUSE_MODE_SERVER:
+ d->mouse_guest_x = -1;
+ d->mouse_guest_y = -1;
+
+ if (window != NULL) {
+ GdkModifierType modifiers;
+ gdk_window_get_pointer(window, NULL, NULL, &modifiers);
+
+ if (modifiers & SPICE_GDK_BUTTONS_MASK)
+ try_mouse_grab(display);
+ }
+ break;
+ default:
+ g_warn_if_reached();
+ }
+
+ update_mouse_pointer(display);
+}
+
+static void update_area(SpiceDisplay *display,
+ gint x, gint y, gint width, gint height)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ GdkRectangle primary;
+
+ SPICE_DEBUG("update area +%d+%d %dx%d", x, y, width, height);
+ d->area = (GdkRectangle) {
+ .x = x,
+ .y = y,
+ .width = width,
+ .height = height
+ };
+
+#ifndef G_OS_WIN32
+ if (egl_enabled(d)) {
+ const SpiceGlScanout *so =
+ spice_display_get_gl_scanout(SPICE_DISPLAY_CHANNEL(d->display));
+ g_return_if_fail(so != NULL);
+ primary = (GdkRectangle) {
+ .width = so->width,
+ .height = so->height
+ };
+ } else
+#endif
+ {
+ primary = (GdkRectangle) {
+ .width = d->canvas.width,
+ .height = d->canvas.height
+ };
+ }
+
+ SPICE_DEBUG("primary: %dx%d", primary.width, primary.height);
+ if (!gdk_rectangle_intersect(&primary, &d->area, &d->area)) {
+ SPICE_DEBUG("The monitor area is not intersecting primary surface");
+ memset(&d->area, '\0', sizeof(d->area));
+ set_monitor_ready(display, false);
+ return;
+ }
+
+ if (!egl_enabled(d)) {
+ spice_cairo_image_destroy(display);
+ if (gtk_widget_get_realized(GTK_WIDGET(display)))
+ update_image(display);
+ }
+
+ update_size_request(display);
+
+ set_monitor_ready(display, true);
+}
+
+static void primary_create(SpiceChannel *channel, gint format,
+ gint width, gint height, gint stride,
+ gint shmid, gpointer imgdata, gpointer data)
+{
+ SpiceDisplay *display = data;
+ SpiceDisplayPrivate *d = display->priv;
+
+ d->canvas.format = format;
+ d->canvas.stride = stride;
+ d->canvas.width = width;
+ d->canvas.height = height;
+ d->canvas.data_origin = d->canvas.data = imgdata;
+
+ spice_display_widget_update_monitor_area(display);
+}
+
+static void primary_destroy(SpiceChannel *channel, gpointer data)
+{
+ SpiceDisplay *display = SPICE_DISPLAY(data);
+ SpiceDisplayPrivate *d = display->priv;
+
+ spice_cairo_image_destroy(display);
+ d->canvas.width = 0;
+ d->canvas.height = 0;
+ d->canvas.stride = 0;
+ d->canvas.data = NULL;
+ d->canvas.data_origin = NULL;
+ set_monitor_ready(display, false);
+}
+
+static void queue_draw_area(SpiceDisplay *display, gint x, gint y,
+ gint width, gint height)
+{
+ if (!gtk_widget_get_has_window(GTK_WIDGET(display))) {
+ GtkAllocation allocation;
+
+ gtk_widget_get_allocation(GTK_WIDGET(display), &allocation);
+ x += allocation.x;
+ y += allocation.y;
+ }
+
+ gtk_widget_queue_draw_area(GTK_WIDGET(display),
+ x, y, width, height);
+}
+
+static void invalidate(SpiceChannel *channel,
+ gint x, gint y, gint w, gint h, gpointer data)
+{
+ SpiceDisplay *display = data;
+ SpiceDisplayPrivate *d = display->priv;
+ int display_x, display_y;
+ int x1, y1, x2, y2;
+ double s;
+ GdkRectangle rect = {
+ .x = x,
+ .y = y,
+ .width = w,
+ .height = h
+ };
+
+#ifndef G_OS_WIN32
+ set_egl_enabled(display, false);
+#endif
+
+ if (!gtk_widget_get_window(GTK_WIDGET(display)))
+ return;
+
+ if (!gdk_rectangle_intersect(&rect, &d->area, &rect))
+ return;
+
+ if (d->canvas.convert)
+ do_color_convert(display, &rect);
+
+ spice_display_get_scaling(display, &s,
+ &display_x, &display_y,
+ NULL, NULL);
+
+ x1 = floor ((rect.x - d->area.x) * s);
+ y1 = floor ((rect.y - d->area.y) * s);
+ x2 = ceil ((rect.x - d->area.x + rect.width) * s);
+ y2 = ceil ((rect.y - d->area.y + rect.height) * s);
+
+ queue_draw_area(display,
+ display_x + x1, display_y + y1,
+ x2 - x1, y2 - y1);
+}
+
+static void mark(SpiceDisplay *display, gint mark)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ g_return_if_fail(d != NULL);
+
+ SPICE_DEBUG("widget mark: %d, %d:%d %p", mark, d->channel_id, d->monitor_id, display);
+ d->mark = mark;
+ update_ready(display);
+}
+
+static void cursor_set(SpiceCursorChannel *channel,
+ gint width, gint height, gint hot_x, gint hot_y,
+ gpointer rgba, gpointer data)
+{
+ SpiceDisplay *display = data;
+ SpiceDisplayPrivate *d = display->priv;
+ GdkCursor *cursor = NULL;
+
+ cursor_invalidate(display);
+
+ g_clear_object(&d->mouse_pixbuf);
+
+ if (rgba != NULL) {
+ d->mouse_pixbuf = gdk_pixbuf_new_from_data(g_memdup(rgba, width * height * 4),
+ GDK_COLORSPACE_RGB,
+ TRUE, 8,
+ width,
+ height,
+ width * 4,
+ (GdkPixbufDestroyNotify)g_free, NULL);
+ d->mouse_hotspot.x = hot_x;
+ d->mouse_hotspot.y = hot_y;
+ cursor = gdk_cursor_new_from_pixbuf(gtk_widget_get_display(GTK_WIDGET(display)),
+ d->mouse_pixbuf, hot_x, hot_y);
+ } else
+ g_warn_if_reached();
+
+#ifndef G_OS_WIN32
+ if (egl_enabled(d))
+ spice_egl_cursor_set(display);
+#endif
+ if (d->show_cursor) {
+ /* unhide */
+ g_clear_pointer(&d->show_cursor, g_object_unref);
+ if (d->mouse_mode == SPICE_MOUSE_MODE_SERVER) {
+ /* keep a hidden cursor, will be shown in cursor_move() */
+ d->show_cursor = cursor;
+ return;
+ }
+ }
+
+ g_object_unref(d->mouse_cursor);
+ d->mouse_cursor = cursor;
+
+ update_mouse_pointer(display);
+ cursor_invalidate(display);
+}
+
+static void cursor_hide(SpiceCursorChannel *channel, gpointer data)
+{
+ SpiceDisplay *display = data;
+ SpiceDisplayPrivate *d = display->priv;
+
+ if (d->show_cursor != NULL) /* then we are already hidden */
+ return;
+
+ cursor_invalidate(display);
+ d->show_cursor = d->mouse_cursor;
+ d->mouse_cursor = get_blank_cursor();
+ update_mouse_pointer(display);
+}
+
+G_GNUC_INTERNAL
+void spice_display_get_scaling(SpiceDisplay *display,
+ double *s_out,
+ int *x_out, int *y_out,
+ int *w_out, int *h_out)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ int fbw = d->area.width, fbh = d->area.height;
+ int ww, wh;
+ int x, y, w, h;
+ double s;
+
+ if (gtk_widget_get_realized (GTK_WIDGET(display))) {
+ ww = gtk_widget_get_allocated_width(GTK_WIDGET(display));
+ wh = gtk_widget_get_allocated_height(GTK_WIDGET(display));
+ } else {
+ ww = fbw;
+ wh = fbh;
+ }
+
+ if (!spice_cairo_is_scaled(display)) {
+ s = 1.0;
+ x = 0;
+ y = 0;
+ if (ww > d->area.width)
+ x = (ww - d->area.width) / 2;
+ if (wh > d->area.height)
+ y = (wh - d->area.height) / 2;
+ w = fbw;
+ h = fbh;
+ } else {
+ s = MIN ((double)ww / (double)fbw, (double)wh / (double)fbh);
+
+ if (d->only_downscale && s >= 1.0)
+ s = 1.0;
+
+ /* Round to int size */
+ w = floor (fbw * s + 0.5);
+ h = floor (fbh * s + 0.5);
+
+ /* Center the display */
+ x = (ww - w) / 2;
+ y = (wh - h) / 2;
+ }
+
+ if (s_out)
+ *s_out = s;
+ if (w_out)
+ *w_out = w;
+ if (h_out)
+ *h_out = h;
+ if (x_out)
+ *x_out = x;
+ if (y_out)
+ *y_out = y;
+}
+
+static void cursor_invalidate(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ double s;
+ int x, y;
+
+ if (!gtk_widget_get_realized (GTK_WIDGET(display)))
+ return;
+
+ if (d->mouse_pixbuf == NULL)
+ return;
+
+ if (!d->ready || !d->monitor_ready)
+ return;
+
+ spice_display_get_scaling(display, &s, &x, &y, NULL, NULL);
+
+ queue_draw_area(display,
+ floor ((d->mouse_guest_x - d->mouse_hotspot.x - d->area.x) * s) + x,
+ floor ((d->mouse_guest_y - d->mouse_hotspot.y - d->area.y) * s) + y,
+ ceil (gdk_pixbuf_get_width(d->mouse_pixbuf) * s),
+ ceil (gdk_pixbuf_get_height(d->mouse_pixbuf) * s));
+}
+
+static void cursor_move(SpiceCursorChannel *channel, gint x, gint y, gpointer data)
+{
+ SpiceDisplay *display = data;
+ SpiceDisplayPrivate *d = display->priv;
+
+ cursor_invalidate(display);
+
+ d->mouse_guest_x = x;
+ d->mouse_guest_y = y;
+
+ cursor_invalidate(display);
+
+ /* apparently we have to restore cursor when "cursor_move" */
+ if (d->show_cursor != NULL) {
+ g_object_unref(d->mouse_cursor);
+ d->mouse_cursor = d->show_cursor;
+ d->show_cursor = NULL;
+ update_mouse_pointer(display);
+ }
+}
+
+static void cursor_reset(SpiceCursorChannel *channel, gpointer data)
+{
+ SpiceDisplay *display = data;
+ GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(display));
+
+ if (!window) {
+ SPICE_DEBUG("%s: no window, returning", __FUNCTION__);
+ return;
+ }
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+ gdk_window_set_cursor(window, NULL);
+}
+
+static void inputs_channel_event(SpiceChannel *channel, SpiceChannelEvent event,
+ gpointer data)
+{
+ SpiceDisplay *display = data;
+ guint delay = DEFAULT_KEYPRESS_DELAY;
+ GSocket *sock;
+
+ if (event != SPICE_CHANNEL_OPENED)
+ return;
+
+ g_object_get(channel, "socket", &sock, NULL);
+ if (g_socket_get_family(sock) == G_SOCKET_FAMILY_UNIX) {
+ delay = 0;
+ }
+ g_object_unref(sock);
+
+ spice_display_set_keypress_delay(display, delay);
+}
+
+#ifndef G_OS_WIN32
+G_GNUC_INTERNAL
+void spice_display_widget_gl_scanout(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d = display->priv;
+ GError *err = NULL;
+
+ SPICE_DEBUG("%s: got scanout", __FUNCTION__);
+
+#ifdef GDK_WINDOWING_X11
+ GtkWidget *area = gtk_stack_get_child_by_name(d->stack, "draw-area");
+
+ if (GDK_IS_X11_DISPLAY(gdk_display_get_default()) &&
+ !d->egl.context_ready &&
+ gtk_widget_get_realized(area)) {
+ if (!spice_egl_init(display, &err)) {
+ g_critical("egl init failed: %s", err->message);
+ g_clear_error(&err);
+ }
+
+ if (!spice_egl_realize_display(display, gtk_widget_get_window(area), &err)) {
+ g_critical("egl realize failed: %s", err->message);
+ g_clear_error(&err);
+ }
+ }
+#endif
+
+ set_egl_enabled(display, true);
+
+ if (d->egl.context_ready) {
+ const SpiceGlScanout *scanout;
+
+ scanout = spice_display_get_gl_scanout(SPICE_DISPLAY_CHANNEL(d->display));
+ /* should only be called when the display has a scanout */
+ g_return_if_fail(scanout != NULL);
+
+ if (!spice_egl_update_scanout(display, scanout, &err)) {
+ g_critical("update scanout failed: %s", err->message);
+ g_clear_error(&err);
+ }
+ }
+}
+
+static void gl_draw(SpiceDisplay *display,
+ guint32 x, guint32 y, guint32 w, guint32 h)
+{
+ SpiceDisplayPrivate *d = display->priv;
+
+ SPICE_DEBUG("%s", __FUNCTION__);
+
+ set_egl_enabled(display, true);
+
+ g_return_if_fail(d->egl.context_ready);
+
+#if GTK_CHECK_VERSION(3,16,0)
+ GtkWidget *gl = gtk_stack_get_child_by_name(d->stack, "gl-area");
+
+ if (gtk_stack_get_visible_child(d->stack) == gl) {
+ gtk_gl_area_queue_render(GTK_GL_AREA(gl));
+ d->egl.call_draw_done = TRUE;
+ } else
+#endif
+ {
+ spice_egl_update_display(display);
+ spice_display_gl_draw_done(SPICE_DISPLAY_CHANNEL(d->display));
+ }
+}
+#endif
+
+static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
+{
+ SpiceDisplay *display = data;
+ SpiceDisplayPrivate *d = display->priv;
+ int id;
+
+ g_object_get(channel, "channel-id", &id, NULL);
+ if (SPICE_IS_MAIN_CHANNEL(channel)) {
+ d->main = SPICE_MAIN_CHANNEL(channel);
+ spice_g_signal_connect_object(channel, "main-mouse-update",
+ G_CALLBACK(update_mouse_mode), display, 0);
+ update_mouse_mode(channel, display);
+ return;
+ }
+
+ if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
+ SpiceDisplayPrimary primary;
+ if (id != d->channel_id)
+ return;
+ d->display = channel;
+ spice_g_signal_connect_object(channel, "display-primary-create",
+ G_CALLBACK(primary_create), display, 0);
+ spice_g_signal_connect_object(channel, "display-primary-destroy",
+ G_CALLBACK(primary_destroy), display, 0);
+ spice_g_signal_connect_object(channel, "display-invalidate",
+ G_CALLBACK(invalidate), display, 0);
+ spice_g_signal_connect_object(channel, "display-mark",
+ G_CALLBACK(mark), display, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+ spice_g_signal_connect_object(channel, "notify::monitors",
+ G_CALLBACK(spice_display_widget_update_monitor_area),
+ display, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+ if (spice_display_get_primary(channel, 0, &primary)) {
+ primary_create(channel, primary.format, primary.width, primary.height,
+ primary.stride, primary.shmid, primary.data, display);
+ mark(display, primary.marked);
+ }
+
+#ifndef G_OS_WIN32
+ spice_g_signal_connect_object(channel, "notify::gl-scanout",
+ G_CALLBACK(spice_display_widget_gl_scanout),
+ display, G_CONNECT_SWAPPED);
+ spice_g_signal_connect_object(channel, "gl-draw",
+ G_CALLBACK(gl_draw), display, G_CONNECT_SWAPPED);
+#endif
+
+ spice_channel_connect(channel);
+ return;
+ }
+
+ if (SPICE_IS_CURSOR_CHANNEL(channel)) {
+ if (id != d->channel_id)
+ return;
+ d->cursor = SPICE_CURSOR_CHANNEL(channel);
+ spice_g_signal_connect_object(channel, "cursor-set",
+ G_CALLBACK(cursor_set), display, 0);
+ spice_g_signal_connect_object(channel, "cursor-move",
+ G_CALLBACK(cursor_move), display, 0);
+ spice_g_signal_connect_object(channel, "cursor-hide",
+ G_CALLBACK(cursor_hide), display, 0);
+ spice_g_signal_connect_object(channel, "cursor-reset",
+ G_CALLBACK(cursor_reset), display, 0);
+ spice_channel_connect(channel);
+ return;
+ }
+
+ if (SPICE_IS_INPUTS_CHANNEL(channel)) {
+ d->inputs = SPICE_INPUTS_CHANNEL(channel);
+ spice_channel_connect(channel);
+ spice_g_signal_connect_object(channel, "channel-event",
+ G_CALLBACK(inputs_channel_event), display, 0);
+ return;
+ }
+
+#ifdef USE_SMARTCARD
+ if (SPICE_IS_SMARTCARD_CHANNEL(channel)) {
+ d->smartcard = SPICE_SMARTCARD_CHANNEL(channel);
+ spice_channel_connect(channel);
+ return;
+ }
+#endif
+
+ return;
+}
+
+static void channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer data)
+{
+ SpiceDisplay *display = data;
+ SpiceDisplayPrivate *d = display->priv;
+ int id;
+
+ g_object_get(channel, "channel-id", &id, NULL);
+ SPICE_DEBUG("channel_destroy %d", id);
+
+ if (SPICE_IS_MAIN_CHANNEL(channel)) {
+ d->main = NULL;
+ return;
+ }
+
+ if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
+ if (id != d->channel_id)
+ return;
+ primary_destroy(d->display, display);
+ d->display = NULL;
+ return;
+ }
+
+ if (SPICE_IS_CURSOR_CHANNEL(channel)) {
+ if (id != d->channel_id)
+ return;
+ d->cursor = NULL;
+ return;
+ }
+
+ if (SPICE_IS_INPUTS_CHANNEL(channel)) {
+ d->inputs = NULL;
+ return;
+ }
+
+#ifdef USE_SMARTCARD
+ if (SPICE_IS_SMARTCARD_CHANNEL(channel)) {
+ d->smartcard = NULL;
+ return;
+ }
+#endif
+
+ return;
+}
+
+/**
+ * spice_display_new:
+ * @session: a #SpiceSession
+ * @channel_id: the display channel ID to associate with #SpiceDisplay
+ *
+ * Creates a new #SpiceDisplay widget.
+ *
+ * Returns: a new #SpiceDisplay widget.
+ **/
+SpiceDisplay *spice_display_new(SpiceSession *session, int channel_id)
+{
+ return g_object_new(SPICE_TYPE_DISPLAY, "session", session,
+ "channel-id", channel_id, NULL);
+}
+
+/**
+ * spice_display_new_with_monitor:
+ * @session: a #SpiceSession
+ * @channel_id: the display channel ID to associate with #SpiceDisplay
+ * @monitor_id: the monitor id within the display channel
+ *
+ * Creates a new #SpiceDisplay widget associated with the monitor id.
+ *
+ * Since: 0.13
+ * Returns: a new #SpiceDisplay widget.
+ **/
+SpiceDisplay* spice_display_new_with_monitor(SpiceSession *session, gint channel_id, gint monitor_id)
+{
+ return g_object_new(SPICE_TYPE_DISPLAY,
+ "session", session,
+ "channel-id", channel_id,
+ "monitor-id", monitor_id,
+ NULL);
+}
+
+/**
+ * spice_display_mouse_ungrab:
+ * @display: a #SpiceDisplay
+ *
+ * Ungrab the mouse.
+ **/
+void spice_display_mouse_ungrab(SpiceDisplay *display)
+{
+ g_return_if_fail(SPICE_IS_DISPLAY(display));
+
+ try_mouse_ungrab(display);
+}
+
+/**
+ * spice_display_get_pixbuf:
+ * @display: a #SpiceDisplay
+ *
+ * Take a screenshot of the display.
+ *
+ * Returns: (transfer full): a #GdkPixbuf with the screenshot image buffer
+ **/
+GdkPixbuf *spice_display_get_pixbuf(SpiceDisplay *display)
+{
+ SpiceDisplayPrivate *d;
+ GdkPixbuf *pixbuf;
+ guchar *data;
+
+ g_return_val_if_fail(SPICE_IS_DISPLAY(display), NULL);
+
+ d = display->priv;
+
+ g_return_val_if_fail(d != NULL, NULL);
+ g_return_val_if_fail(d->display != NULL, NULL);
+
+#ifndef G_OS_WIN32
+ if (egl_enabled(d)) {
+ GdkPixbuf *tmp;
+
+ data = g_malloc0(d->area.width * d->area.height * 4);
+ glReadBuffer(GL_FRONT);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glReadPixels(0, 0, d->area.width, d->area.height,
+ GL_RGBA, GL_UNSIGNED_BYTE, data);
+ tmp = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, true,
+ 8, d->area.width, d->area.height,
+ d->area.width * 4,
+ (GdkPixbufDestroyNotify)g_free, NULL);
+ pixbuf = gdk_pixbuf_flip(tmp, false);
+ g_object_unref(tmp);
+ } else
+#endif
+ {
+ guchar *src, *dest;
+ int x, y;
+
+ /* TODO: ensure d->data has been exposed? */
+ g_return_val_if_fail(d->canvas.data != NULL, NULL);
+ data = g_malloc0(d->area.width * d->area.height * 3);
+ src = d->canvas.data;
+ dest = data;
+
+ src += d->area.y * d->canvas.stride + d->area.x * 4;
+ for (y = 0; y < d->area.height; ++y) {
+ for (x = 0; x < d->area.width; ++x) {
+ dest[0] = src[x * 4 + 2];
+ dest[1] = src[x * 4 + 1];
+ dest[2] = src[x * 4 + 0];
+ dest += 3;
+ }
+ src += d->canvas.stride;
+ }
+ pixbuf = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, false,
+ 8, d->area.width, d->area.height,
+ d->area.width * 3,
+ (GdkPixbufDestroyNotify)g_free, NULL);
+ }
+
+ return pixbuf;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_CLIENT_WIDGET_H__
+#define __SPICE_CLIENT_WIDGET_H__
+
+#if !defined(__SPICE_CLIENT_GTK_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client-gtk.h> can be included directly"
+#endif
+
+#include "spice-client.h"
+
+#include <gtk/gtk.h>
+#include "spice-grabsequence.h"
+#include "spice-widget-enums.h"
+#include "spice-util.h"
+#include "spice-gtk-session.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_DISPLAY (spice_display_get_type())
+#define SPICE_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SPICE_TYPE_DISPLAY, SpiceDisplay))
+#define SPICE_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SPICE_TYPE_DISPLAY, SpiceDisplayClass))
+#define SPICE_IS_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SPICE_TYPE_DISPLAY))
+#define SPICE_IS_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SPICE_TYPE_DISPLAY))
+#define SPICE_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SPICE_TYPE_DISPLAY, SpiceDisplayClass))
+
+
+typedef struct _SpiceDisplay SpiceDisplay;
+typedef struct _SpiceDisplayClass SpiceDisplayClass;
+
+/**
+ * SpiceDisplayKeyEvent:
+ * @SPICE_DISPLAY_KEY_EVENT_PRESS: key press
+ * @SPICE_DISPLAY_KEY_EVENT_RELEASE: key release
+ * @SPICE_DISPLAY_KEY_EVENT_CLICK: key click (press and release)
+ *
+ * Constants for key events.
+ */
+typedef enum
+{
+ SPICE_DISPLAY_KEY_EVENT_PRESS = 1,
+ SPICE_DISPLAY_KEY_EVENT_RELEASE = 2,
+ SPICE_DISPLAY_KEY_EVENT_CLICK = 3,
+} SpiceDisplayKeyEvent;
+
+GType spice_display_get_type(void);
+
+SpiceDisplay* spice_display_new(SpiceSession *session, int channel_id);
+SpiceDisplay* spice_display_new_with_monitor(SpiceSession *session, gint channel_id, gint monitor_id);
+
+void spice_display_mouse_ungrab(SpiceDisplay *display);
+void spice_display_set_grab_keys(SpiceDisplay *display, SpiceGrabSequence *seq);
+SpiceGrabSequence *spice_display_get_grab_keys(SpiceDisplay *display);
+void spice_display_send_keys(SpiceDisplay *display, const guint *keyvals,
+ int nkeyvals, SpiceDisplayKeyEvent kind);
+GdkPixbuf *spice_display_get_pixbuf(SpiceDisplay *display);
+
+G_END_DECLS
+
+#endif /* __SPICE_CLIENT_WIDGET_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010-2015 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include "spice-common.h"
+#include "spicy-connect.h"
+
+typedef struct
+{
+ gboolean connecting;
+ GMainLoop *loop;
+ SpiceSession *session;
+} ConnectionInfo;
+
+static struct {
+ const char *text;
+ const char *prop;
+ GtkWidget *entry;
+} connect_entries[] = {
+ { .text = "Hostname", .prop = "host" },
+ { .text = "Port", .prop = "port" },
+ { .text = "TLS Port", .prop = "tls-port" },
+};
+
+static gboolean can_connect(void)
+{
+ if ((gtk_entry_get_text_length(GTK_ENTRY(connect_entries[0].entry)) > 0) &&
+ ((gtk_entry_get_text_length(GTK_ENTRY(connect_entries[1].entry)) > 0) ||
+ (gtk_entry_get_text_length(GTK_ENTRY(connect_entries[2].entry)) > 0)))
+ return TRUE;
+
+ return FALSE;
+}
+
+static void set_connection_info(SpiceSession *session)
+{
+ const gchar *txt;
+ int i;
+
+ for (i = 0; i < SPICE_N_ELEMENTS(connect_entries); i++) {
+ txt = gtk_entry_get_text(GTK_ENTRY(connect_entries[i].entry));
+ g_object_set(session, connect_entries[i].prop, txt, NULL);
+ }
+}
+
+static gboolean close_cb(gpointer data)
+{
+ ConnectionInfo *info = data;
+ info->connecting = FALSE;
+ if (g_main_loop_is_running(info->loop))
+ g_main_loop_quit(info->loop);
+
+ return TRUE;
+}
+
+static void entry_changed_cb(GtkEditable* entry, gpointer data)
+{
+ GtkButton *connect_button = data;
+ gtk_widget_set_sensitive(GTK_WIDGET(connect_button), can_connect());
+}
+
+static gboolean entry_focus_in_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+ GtkRecentChooser *recent = GTK_RECENT_CHOOSER(data);
+ gtk_recent_chooser_unselect_all(recent);
+ return TRUE;
+}
+
+static gboolean key_pressed_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+ gboolean tst;
+ if (event->type == GDK_KEY_PRESS) {
+ switch (event->key.keyval) {
+ case GDK_KEY_Escape:
+ g_signal_emit_by_name(GTK_WIDGET(data), "delete-event", NULL, &tst);
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void recent_selection_changed_dialog_cb(GtkRecentChooser *chooser, gpointer data)
+{
+ GtkRecentInfo *info;
+ gchar *txt = NULL;
+ const gchar *uri;
+ SpiceSession *session = data;
+ int i;
+
+ info = gtk_recent_chooser_get_current_item(chooser);
+ if (info == NULL)
+ return;
+
+ uri = gtk_recent_info_get_uri(info);
+ g_return_if_fail(uri != NULL);
+
+ g_object_set(session, "uri", uri, NULL);
+
+ for (i = 0; i < SPICE_N_ELEMENTS(connect_entries); i++) {
+ g_object_get(session, connect_entries[i].prop, &txt, NULL);
+ gtk_entry_set_text(GTK_ENTRY(connect_entries[i].entry), txt ? txt : "");
+ g_free(txt);
+ }
+
+ gtk_recent_info_unref(info);
+}
+
+static void connect_cb(gpointer data)
+{
+ ConnectionInfo *info = data;
+ if (can_connect())
+ {
+ info->connecting = TRUE;
+ set_connection_info(info->session);
+ if (g_main_loop_is_running(info->loop))
+ g_main_loop_quit(info->loop);
+ }
+}
+
+gboolean spicy_connect_dialog(SpiceSession *session)
+{
+ GtkWidget *connect_button, *cancel_button, *label;
+ GtkBox *main_box, *recent_box, *button_box;
+ GtkWindow *window;
+ GtkTable *table;
+ int i;
+
+ ConnectionInfo info = {
+ FALSE,
+ NULL,
+ session
+ };
+
+ /* Create the widgets */
+ window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
+ gtk_window_set_title(window, "Connect to SPICE");
+ gtk_window_set_resizable(window, FALSE);
+ gtk_container_set_border_width(GTK_CONTAINER(window), 5);
+
+ main_box = GTK_BOX(gtk_vbox_new(FALSE, 0));
+ gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(main_box));
+
+ table = GTK_TABLE(gtk_table_new(3, 2, 0));
+ gtk_box_pack_start(main_box, GTK_WIDGET(table), FALSE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(table), 5);
+ gtk_table_set_row_spacings(table, 5);
+ gtk_table_set_col_spacings(table, 5);
+
+ for (i = 0; i < SPICE_N_ELEMENTS(connect_entries); i++) {
+ gchar *txt;
+ label = gtk_label_new(connect_entries[i].text);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_table_attach_defaults(table, label, 0, 1, i, i+1);
+ connect_entries[i].entry = GTK_WIDGET(gtk_entry_new());
+ gtk_table_attach_defaults(table, connect_entries[i].entry, 1, 2, i, i+1);
+ g_object_get(session, connect_entries[i].prop, &txt, NULL);
+ SPICE_DEBUG("%s: #%i [%s]: \"%s\"",
+ __FUNCTION__, i, connect_entries[i].prop, txt);
+ if (txt) {
+ gtk_entry_set_text(GTK_ENTRY(connect_entries[i].entry), txt);
+ g_free(txt);
+ }
+ }
+
+ recent_box = GTK_BOX(gtk_vbox_new(FALSE, 0));
+ gtk_box_pack_start(main_box, GTK_WIDGET(recent_box), TRUE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(recent_box), 5);
+
+ label = gtk_label_new("Recent connections:");
+ gtk_box_pack_start(recent_box, label, FALSE, TRUE, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ button_box = GTK_BOX(gtk_hbutton_box_new());
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing(button_box, 5);
+ gtk_container_set_border_width(GTK_CONTAINER(button_box), 5);
+ connect_button = gtk_button_new_with_label("Connect");
+ cancel_button = gtk_button_new_with_label("Cancel");
+ gtk_box_pack_start(button_box, cancel_button, FALSE, TRUE, 0);
+ gtk_box_pack_start(button_box, connect_button, FALSE, TRUE, 1);
+
+ gtk_box_pack_start(main_box, GTK_WIDGET(button_box), FALSE, TRUE, 0);
+
+ gtk_widget_set_sensitive(GTK_WIDGET(connect_button), can_connect());
+
+ g_signal_connect(window, "key-press-event",
+ G_CALLBACK(key_pressed_cb), window);
+ g_signal_connect_swapped(window, "delete-event",
+ G_CALLBACK(close_cb), &info);
+ g_signal_connect_swapped(connect_button, "clicked",
+ G_CALLBACK(connect_cb), &info);
+ g_signal_connect_swapped(cancel_button, "clicked",
+ G_CALLBACK(close_cb), &info);
+
+ GtkRecentFilter *rfilter;
+ GtkWidget *recent;
+
+ recent = GTK_WIDGET(gtk_recent_chooser_widget_new());
+ gtk_recent_chooser_set_show_icons(GTK_RECENT_CHOOSER(recent), FALSE);
+ gtk_box_pack_start(recent_box, recent, TRUE, TRUE, 0);
+
+ rfilter = gtk_recent_filter_new();
+ gtk_recent_filter_add_mime_type(rfilter, "application/x-spice");
+ gtk_recent_chooser_set_filter(GTK_RECENT_CHOOSER(recent), rfilter);
+ gtk_recent_chooser_set_local_only(GTK_RECENT_CHOOSER(recent), FALSE);
+ g_signal_connect(recent, "selection-changed",
+ G_CALLBACK(recent_selection_changed_dialog_cb), session);
+ g_signal_connect_swapped(recent, "item-activated",
+ G_CALLBACK(connect_cb), &info);
+
+ for (i = 0; i < SPICE_N_ELEMENTS(connect_entries); i++) {
+ g_signal_connect_swapped(connect_entries[i].entry, "activate",
+ G_CALLBACK(connect_cb), &info);
+ g_signal_connect(connect_entries[i].entry, "changed",
+ G_CALLBACK(entry_changed_cb), connect_button);
+ g_signal_connect(connect_entries[i].entry, "focus-in-event",
+ G_CALLBACK(entry_focus_in_cb), recent);
+ }
+
+ /* show and wait for response */
+ gtk_widget_show_all(GTK_WIDGET(window));
+
+ info.loop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(info.loop);
+
+ gtk_widget_destroy(GTK_WIDGET(window));
+
+ return info.connecting;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010-2015 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SPICY_CONNECT_H
+#define SPICY_CONNECT_H
+
+#include "spice-widget.h"
+
+gboolean spicy_connect_dialog(SpiceSession *session);
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+#include "spice-cmdline.h"
+
+/* config */
+static const char *outf = "spicy-screenshot.ppm";
+static gboolean version = FALSE;
+
+/* state */
+static SpiceSession *session;
+static GMainLoop *mainloop;
+
+enum SpiceSurfaceFmt d_format;
+gint d_width, d_height, d_stride;
+gpointer d_data;
+
+/* ------------------------------------------------------------------ */
+
+static void primary_create(SpiceChannel *channel, gint format,
+ gint width, gint height, gint stride,
+ gint shmid, gpointer imgdata, gpointer data)
+{
+ SPICE_DEBUG("%s: %dx%d, format %d", __FUNCTION__, width, height, format);
+ d_format = format;
+ d_width = width;
+ d_height = height;
+ d_stride = stride;
+ d_data = imgdata;
+}
+
+static int write_ppm_32(void)
+{
+ FILE *fp;
+ uint8_t *p;
+ int n;
+
+ fp = fopen(outf,"w");
+ if (NULL == fp) {
+ fprintf(stderr, "%s: can't open %s: %s\n", g_get_prgname(), outf, strerror(errno));
+ return -1;
+ }
+ fprintf(fp, "P6\n%d %d\n255\n",
+ d_width, d_height);
+ n = d_width * d_height;
+ p = d_data;
+ while (n > 0) {
+#ifdef WORDS_BIGENDIAN
+ fputc(p[1], fp);
+ fputc(p[2], fp);
+ fputc(p[3], fp);
+#else
+ fputc(p[2], fp);
+ fputc(p[1], fp);
+ fputc(p[0], fp);
+#endif
+ p += 4;
+ n--;
+ }
+ fclose(fp);
+ return 0;
+}
+
+static void invalidate(SpiceChannel *channel,
+ gint x, gint y, gint w, gint h, gpointer *data)
+{
+ int rc;
+
+ switch (d_format) {
+ case SPICE_SURFACE_FMT_32_xRGB:
+ rc = write_ppm_32();
+ break;
+ default:
+ fprintf(stderr, "unsupported spice surface format %u\n", d_format);
+ rc = -1;
+ break;
+ }
+ if (rc == 0)
+ fprintf(stderr, "wrote screen shot to %s\n", outf);
+ g_main_loop_quit(mainloop);
+}
+
+static void main_channel_event(SpiceChannel *channel, SpiceChannelEvent event,
+ gpointer data)
+{
+ switch (event) {
+ case SPICE_CHANNEL_OPENED:
+ break;
+ default:
+ g_warning("main channel event: %u", event);
+ g_main_loop_quit(mainloop);
+ }
+}
+
+static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer *data)
+{
+ int id;
+
+ if (SPICE_IS_MAIN_CHANNEL(channel)) {
+ g_signal_connect(channel, "channel-event",
+ G_CALLBACK(main_channel_event), data);
+ return;
+ }
+
+ if (!SPICE_IS_DISPLAY_CHANNEL(channel))
+ return;
+
+ g_object_get(channel, "channel-id", &id, NULL);
+ if (id != 0)
+ return;
+
+ g_signal_connect(channel, "display-primary-create",
+ G_CALLBACK(primary_create), NULL);
+ g_signal_connect(channel, "display-invalidate",
+ G_CALLBACK(invalidate), NULL);
+ spice_channel_connect(channel);
+}
+
+/* ------------------------------------------------------------------ */
+
+static GOptionEntry app_entries[] = {
+ {
+ .long_name = "out-file",
+ .short_name = 'o',
+ .arg = G_OPTION_ARG_FILENAME,
+ .arg_data = &outf,
+ .description = "Output file name (default spicy-screenshot.ppm)",
+ .arg_description = "<filename>",
+ },
+ {
+ .long_name = "version",
+ .arg = G_OPTION_ARG_NONE,
+ .arg_data = &version,
+ .description = "Display version and quit",
+ },
+ {
+ /* end of list */
+ }
+};
+
+int main(int argc, char *argv[])
+{
+ GError *error = NULL;
+ GOptionContext *context;
+
+ /* parse opts */
+ context = g_option_context_new(" - make screen shots");
+ g_option_context_set_summary(context, "A Spice server client to take screenshots in ppm format.");
+ g_option_context_set_description(context, "Report bugs to " PACKAGE_BUGREPORT ".");
+ g_option_context_set_main_group(context, spice_cmdline_get_option_group());
+ g_option_context_add_main_entries(context, app_entries, NULL);
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_print("option parsing failed: %s\n", error->message);
+ exit(1);
+ }
+
+ if (version) {
+ g_print("%s " PACKAGE_VERSION "\n", g_get_prgname());
+ exit(0);
+ }
+
+ mainloop = g_main_loop_new(NULL, false);
+
+ session = spice_session_new();
+ g_signal_connect(session, "channel-new",
+ G_CALLBACK(channel_new), NULL);
+ spice_cmdline_session_setup(session);
+
+ if (!spice_session_connect(session)) {
+ fprintf(stderr, "spice_session_connect failed\n");
+ exit(1);
+ }
+
+ g_main_loop_run(mainloop);
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include "spice-client.h"
+#include "spice-common.h"
+#include "spice-cmdline.h"
+
+/* config */
+static gboolean version = FALSE;
+
+/* state */
+static SpiceSession *session;
+static GMainLoop *mainloop;
+
+/* ------------------------------------------------------------------ */
+static void main_channel_event(SpiceChannel *channel, SpiceChannelEvent event,
+ gpointer data)
+{
+ switch (event) {
+ case SPICE_CHANNEL_OPENED:
+ break;
+ default:
+ g_warning("main channel event: %u", event);
+ g_main_loop_quit(mainloop);
+ }
+}
+
+static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer *data)
+{
+ int id;
+
+ if (SPICE_IS_MAIN_CHANNEL(channel)) {
+ SPICE_DEBUG("new main channel");
+ g_signal_connect(channel, "channel-event",
+ G_CALLBACK(main_channel_event), data);
+ }
+
+ if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
+ g_object_get(channel, "channel-id", &id, NULL);
+ if (id != 0)
+ return;
+ }
+
+ spice_channel_connect(channel);
+}
+
+/* ------------------------------------------------------------------ */
+
+static GOptionEntry app_entries[] = {
+ {
+ .long_name = "version",
+ .arg = G_OPTION_ARG_NONE,
+ .arg_data = &version,
+ .description = "Display version and quit",
+ },
+ {
+ /* end of list */
+ }
+};
+
+static void
+signal_handler(int signum)
+{
+ g_main_loop_quit(mainloop);
+}
+
+int main(int argc, char *argv[])
+{
+ GError *error = NULL;
+ GOptionContext *context;
+
+ signal(SIGINT, signal_handler);
+
+ /* parse opts */
+ context = g_option_context_new(NULL);
+ g_option_context_set_summary(context, "A Spice client used for testing and measurements.");
+ g_option_context_set_description(context, "Report bugs to " PACKAGE_BUGREPORT ".");
+ g_option_context_set_main_group(context, spice_cmdline_get_option_group());
+ g_option_context_add_main_entries(context, app_entries, NULL);
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_print("option parsing failed: %s\n", error->message);
+ exit(1);
+ }
+
+ if (version) {
+ g_print("spicy-stats " PACKAGE_VERSION "\n");
+ exit(0);
+ }
+
+ mainloop = g_main_loop_new(NULL, false);
+
+ session = spice_session_new();
+ g_signal_connect(session, "channel-new",
+ G_CALLBACK(channel_new), NULL);
+ spice_cmdline_session_setup(session);
+
+ if (!spice_session_connect(session)) {
+ fprintf(stderr, "spice_session_connect failed\n");
+ exit(1);
+ }
+
+ g_main_loop_run(mainloop);
+ {
+ GList *iter, *list = spice_session_get_channels(session);
+ gulong total_read_bytes;
+ gint channel_type;
+ printf("total bytes read:\n");
+ for (iter = list ; iter ; iter = iter->next) {
+ g_object_get(iter->data,
+ "total-read-bytes", &total_read_bytes,
+ "channel-type", &channel_type,
+ NULL);
+ printf("%s: %lu\n",
+ spice_channel_type_to_string(channel_type),
+ total_read_bytes);
+ }
+ g_list_free(list);
+ }
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2010-2011 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+#include <glib.h>
+
+#include <sys/stat.h>
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+
+#ifdef USE_SMARTCARD_012
+#include <vreader.h>
+#endif
+
+#include "spice-widget.h"
+#include "spice-gtk-session.h"
+#include "spice-audio.h"
+#include "spice-common.h"
+#include "spice-cmdline.h"
+#include "spice-option.h"
+#include "usb-device-widget.h"
+
+#include "spicy-connect.h"
+
+typedef struct spice_connection spice_connection;
+
+enum {
+ STATE_SCROLL_LOCK,
+ STATE_CAPS_LOCK,
+ STATE_NUM_LOCK,
+ STATE_MAX,
+};
+
+#define SPICE_TYPE_WINDOW (spice_window_get_type ())
+#define SPICE_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_WINDOW, SpiceWindow))
+#define SPICE_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_WINDOW))
+#define SPICE_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_WINDOW, SpiceWindowClass))
+#define SPICE_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_WINDOW))
+#define SPICE_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_WINDOW, SpiceWindowClass))
+
+typedef struct _SpiceWindow SpiceWindow;
+typedef struct _SpiceWindowClass SpiceWindowClass;
+
+struct _SpiceWindow {
+ GObject object;
+ spice_connection *conn;
+ gint id;
+ gint monitor_id;
+ GtkWidget *toplevel, *spice;
+ GtkWidget *menubar, *toolbar;
+ GtkWidget *ritem, *rmenu;
+ GtkWidget *statusbar, *status, *st[STATE_MAX];
+ GtkActionGroup *ag;
+ GtkUIManager *ui;
+ bool fullscreen;
+ bool mouse_grabbed;
+ SpiceChannel *display_channel;
+#ifdef G_OS_WIN32
+ gint win_x;
+ gint win_y;
+#endif
+ bool enable_accels_save;
+ bool enable_mnemonics_save;
+};
+
+struct _SpiceWindowClass
+{
+ GObjectClass parent_class;
+};
+
+static GType spice_window_get_type(void);
+
+G_DEFINE_TYPE (SpiceWindow, spice_window, G_TYPE_OBJECT);
+
+#define CHANNELID_MAX 4
+#define MONITORID_MAX 4
+
+
+// FIXME: turn this into an object, get rid of fixed wins array, use
+// signals to replace the various callback that iterate over wins array
+struct spice_connection {
+ SpiceSession *session;
+ SpiceGtkSession *gtk_session;
+ SpiceMainChannel *main;
+ SpiceWindow *wins[CHANNELID_MAX * MONITORID_MAX];
+ SpiceAudio *audio;
+ const char *mouse_state;
+ const char *agent_state;
+ gboolean agent_connected;
+ int channels;
+ int disconnecting;
+
+ /* key: SpiceFileTransferTask, value: TransferTaskWidgets */
+ GHashTable *transfers;
+ GtkWidget *transfer_dialog;
+};
+
+static spice_connection *connection_new(void);
+static void connection_connect(spice_connection *conn);
+static void connection_disconnect(spice_connection *conn);
+static void connection_destroy(spice_connection *conn);
+static void usb_connect_failed(GObject *object,
+ SpiceUsbDevice *device,
+ GError *error,
+ gpointer data);
+static gboolean is_gtk_session_property(const gchar *property);
+static void del_window(spice_connection *conn, SpiceWindow *win);
+
+/* options */
+static gboolean fullscreen = false;
+static gboolean version = false;
+static char *spicy_title = NULL;
+/* globals */
+static GMainLoop *mainloop = NULL;
+static int connections = 0;
+static GKeyFile *keyfile = NULL;
+static SpicePortChannel*stdin_port = NULL;
+
+/* ------------------------------------------------------------------ */
+
+static int ask_user(GtkWidget *parent, char *title, char *message,
+ char *dest, int dlen, int hide)
+{
+ GtkWidget *dialog, *area, *label, *entry;
+ const char *txt;
+ int retval;
+
+ /* Create the widgets */
+ dialog = gtk_dialog_new_with_buttons(title,
+ parent ? GTK_WINDOW(parent) : NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ "_OK",
+ GTK_RESPONSE_ACCEPT,
+ "_Cancel",
+ GTK_RESPONSE_REJECT,
+ NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
+ area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ label = gtk_label_new(message);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(area), label, FALSE, FALSE, 5);
+
+ entry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(entry), dest);
+ gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
+ if (hide)
+ gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
+ gtk_box_pack_start(GTK_BOX(area), entry, FALSE, FALSE, 5);
+
+ /* show and wait for response */
+ gtk_widget_show_all(dialog);
+ switch (gtk_dialog_run(GTK_DIALOG(dialog))) {
+ case GTK_RESPONSE_ACCEPT:
+ txt = gtk_entry_get_text(GTK_ENTRY(entry));
+ snprintf(dest, dlen, "%s", txt);
+ retval = 0;
+ break;
+ default:
+ retval = -1;
+ break;
+ }
+ gtk_widget_destroy(dialog);
+ return retval;
+}
+
+static void update_status_window(SpiceWindow *win)
+{
+ gchar *status;
+
+ if (win == NULL)
+ return;
+
+ if (win->mouse_grabbed) {
+ SpiceGrabSequence *sequence = spice_display_get_grab_keys(SPICE_DISPLAY(win->spice));
+ gchar *seq = spice_grab_sequence_as_string(sequence);
+ status = g_strdup_printf("Use %s to ungrab mouse.", seq);
+ g_free(seq);
+ } else {
+ status = g_strdup_printf("mouse: %s, agent: %s",
+ win->conn->mouse_state, win->conn->agent_state);
+ }
+
+ gtk_label_set_text(GTK_LABEL(win->status), status);
+ g_free(status);
+}
+
+static void update_status(struct spice_connection *conn)
+{
+ int i;
+
+ for (i = 0; i < SPICE_N_ELEMENTS(conn->wins); i++) {
+ if (conn->wins[i] == NULL)
+ continue;
+ update_status_window(conn->wins[i]);
+ }
+}
+
+static const char *spice_edit_properties[] = {
+ "CopyToGuest",
+ "PasteFromGuest",
+};
+
+static void update_edit_menu_window(SpiceWindow *win)
+{
+ int i;
+ GtkAction *toggle;
+
+ if (win == NULL) {
+ return;
+ }
+
+ /* Make "CopyToGuest" and "PasteFromGuest" insensitive if spice
+ * agent is not connected */
+ for (i = 0; i < G_N_ELEMENTS(spice_edit_properties); i++) {
+ toggle = gtk_action_group_get_action(win->ag, spice_edit_properties[i]);
+ if (toggle) {
+ gtk_action_set_sensitive(toggle, win->conn->agent_connected);
+ }
+ }
+}
+
+static void update_edit_menu(struct spice_connection *conn)
+{
+ int i;
+
+ for (i = 0; i < SPICE_N_ELEMENTS(conn->wins); i++) {
+ if (conn->wins[i]) {
+ update_edit_menu_window(conn->wins[i]);
+ }
+ }
+}
+
+static void menu_cb_connect(GtkAction *action, void *data)
+{
+ struct spice_connection *conn;
+
+ conn = connection_new();
+ connection_connect(conn);
+}
+
+static void menu_cb_close(GtkAction *action, void *data)
+{
+ SpiceWindow *win = data;
+
+ connection_disconnect(win->conn);
+}
+
+static void menu_cb_copy(GtkAction *action, void *data)
+{
+ SpiceWindow *win = data;
+
+ spice_gtk_session_copy_to_guest(win->conn->gtk_session);
+}
+
+static void menu_cb_paste(GtkAction *action, void *data)
+{
+ SpiceWindow *win = data;
+
+ spice_gtk_session_paste_from_guest(win->conn->gtk_session);
+}
+
+static void window_set_fullscreen(SpiceWindow *win, gboolean fs)
+{
+ if (fs) {
+#ifdef G_OS_WIN32
+ gtk_window_get_position(GTK_WINDOW(win->toplevel), &win->win_x, &win->win_y);
+#endif
+ gtk_window_fullscreen(GTK_WINDOW(win->toplevel));
+ } else {
+ gtk_window_unfullscreen(GTK_WINDOW(win->toplevel));
+#ifdef G_OS_WIN32
+ gtk_window_move(GTK_WINDOW(win->toplevel), win->win_x, win->win_y);
+#endif
+ }
+}
+
+static void menu_cb_fullscreen(GtkAction *action, void *data)
+{
+ SpiceWindow *win = data;
+
+ window_set_fullscreen(win, !win->fullscreen);
+}
+
+#ifdef USE_SMARTCARD
+static void enable_smartcard_actions(SpiceWindow *win, VReader *reader,
+ gboolean can_insert, gboolean can_remove)
+{
+ GtkAction *action;
+
+ if ((reader != NULL) && (!spice_smartcard_reader_is_software((SpiceSmartcardReader*)reader)))
+ {
+ /* Having menu actions to insert/remove smartcards only makes sense
+ * for software smartcard readers, don't do anything when the event
+ * we received was for a "real" smartcard reader.
+ */
+ return;
+ }
+ action = gtk_action_group_get_action(win->ag, "InsertSmartcard");
+ g_return_if_fail(action != NULL);
+ gtk_action_set_sensitive(action, can_insert);
+ action = gtk_action_group_get_action(win->ag, "RemoveSmartcard");
+ g_return_if_fail(action != NULL);
+ gtk_action_set_sensitive(action, can_remove);
+}
+
+
+static void reader_added_cb(SpiceSmartcardManager *manager, VReader *reader,
+ gpointer user_data)
+{
+ enable_smartcard_actions(user_data, reader, TRUE, FALSE);
+}
+
+static void reader_removed_cb(SpiceSmartcardManager *manager, VReader *reader,
+ gpointer user_data)
+{
+ enable_smartcard_actions(user_data, reader, FALSE, FALSE);
+}
+
+static void card_inserted_cb(SpiceSmartcardManager *manager, VReader *reader,
+ gpointer user_data)
+{
+ enable_smartcard_actions(user_data, reader, FALSE, TRUE);
+}
+
+static void card_removed_cb(SpiceSmartcardManager *manager, VReader *reader,
+ gpointer user_data)
+{
+ enable_smartcard_actions(user_data, reader, TRUE, FALSE);
+}
+
+static void menu_cb_insert_smartcard(GtkAction *action, void *data)
+{
+ spice_smartcard_manager_insert_card(spice_smartcard_manager_get());
+}
+
+static void menu_cb_remove_smartcard(GtkAction *action, void *data)
+{
+ spice_smartcard_manager_remove_card(spice_smartcard_manager_get());
+}
+#endif
+
+static void menu_cb_mouse_mode(GtkAction *action, void *data)
+{
+ SpiceWindow *win = data;
+ SpiceMainChannel *cmain = win->conn->main;
+ int mode;
+
+ g_object_get(cmain, "mouse-mode", &mode, NULL);
+ if (mode == SPICE_MOUSE_MODE_CLIENT)
+ mode = SPICE_MOUSE_MODE_SERVER;
+ else
+ mode = SPICE_MOUSE_MODE_CLIENT;
+
+ spice_main_request_mouse_mode(cmain, mode);
+}
+
+#ifdef USE_USBREDIR
+static void remove_cb(GtkContainer *container, GtkWidget *widget, void *data)
+{
+ gtk_window_resize(GTK_WINDOW(data), 1, 1);
+}
+
+static void menu_cb_select_usb_devices(GtkAction *action, void *data)
+{
+ GtkWidget *dialog, *area, *usb_device_widget;
+ SpiceWindow *win = data;
+
+ /* Create the widgets */
+ dialog = gtk_dialog_new_with_buttons(
+ "Select USB devices for redirection",
+ GTK_WINDOW(win->toplevel),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ "_Close", GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
+ gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
+ gtk_box_set_spacing(GTK_BOX(gtk_bin_get_child(GTK_BIN(dialog))), 12);
+
+ area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+
+ usb_device_widget = spice_usb_device_widget_new(win->conn->session,
+ NULL); /* default format */
+ g_signal_connect(usb_device_widget, "connect-failed",
+ G_CALLBACK(usb_connect_failed), NULL);
+ gtk_box_pack_start(GTK_BOX(area), usb_device_widget, TRUE, TRUE, 0);
+
+ /* This shrinks the dialog when USB devices are unplugged */
+ g_signal_connect(usb_device_widget, "remove",
+ G_CALLBACK(remove_cb), dialog);
+
+ /* show and run */
+ gtk_widget_show_all(dialog);
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+}
+#endif
+
+static void menu_cb_bool_prop(GtkToggleAction *action, gpointer data)
+{
+ SpiceWindow *win = data;
+ gboolean state = gtk_toggle_action_get_active(action);
+ const char *name;
+ gpointer object;
+
+ name = gtk_action_get_name(GTK_ACTION(action));
+ SPICE_DEBUG("%s: %s = %s", __FUNCTION__, name, state ? "yes" : "no");
+
+ g_key_file_set_boolean(keyfile, "general", name, state);
+
+ if (is_gtk_session_property(name)) {
+ object = win->conn->gtk_session;
+ } else {
+ object = win->spice;
+ }
+ g_object_set(object, name, state, NULL);
+}
+
+static void menu_cb_conn_bool_prop_changed(GObject *gobject,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ SpiceWindow *win = user_data;
+ const gchar *property = g_param_spec_get_name(pspec);
+ GtkAction *toggle;
+ gboolean state;
+
+ toggle = gtk_action_group_get_action(win->ag, property);
+ g_object_get(win->conn->gtk_session, property, &state, NULL);
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(toggle), state);
+}
+
+static void menu_cb_toolbar(GtkToggleAction *action, gpointer data)
+{
+ SpiceWindow *win = data;
+ gboolean state = gtk_toggle_action_get_active(action);
+
+ gtk_widget_set_visible(win->toolbar, state);
+ g_key_file_set_boolean(keyfile, "ui", "toolbar", state);
+}
+
+static void menu_cb_statusbar(GtkToggleAction *action, gpointer data)
+{
+ SpiceWindow *win = data;
+ gboolean state = gtk_toggle_action_get_active(action);
+
+ gtk_widget_set_visible(win->statusbar, state);
+ g_key_file_set_boolean(keyfile, "ui", "statusbar", state);
+}
+
+static void menu_cb_about(GtkAction *action, void *data)
+{
+ char *comments = "gtk test client app for the\n"
+ "spice remote desktop protocol";
+ static const char *copyright = "(c) 2010 Red Hat";
+ static const char *website = "http://www.spice-space.org";
+ static const char *authors[] = { "Gerd Hoffmann <kraxel@redhat.com>",
+ "Marc-André Lureau <marcandre.lureau@redhat.com>",
+ NULL };
+ SpiceWindow *win = data;
+
+ gtk_show_about_dialog(GTK_WINDOW(win->toplevel),
+ "authors", authors,
+ "comments", comments,
+ "copyright", copyright,
+ "logo-icon-name", "help-about",
+ "website", website,
+ "version", PACKAGE_VERSION,
+ "license", "LGPLv2.1",
+ NULL);
+}
+
+static gboolean delete_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+ SpiceWindow *win = data;
+
+ if (win->monitor_id == 0)
+ connection_disconnect(win->conn);
+ else
+ del_window(win->conn, win);
+
+ return true;
+}
+
+static gboolean window_state_cb(GtkWidget *widget, GdkEventWindowState *event,
+ gpointer data)
+{
+ SpiceWindow *win = data;
+ if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
+ win->fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN;
+ if (win->fullscreen) {
+ gtk_widget_hide(win->menubar);
+ gtk_widget_hide(win->toolbar);
+ gtk_widget_hide(win->statusbar);
+ gtk_widget_grab_focus(win->spice);
+ } else {
+ gboolean state;
+ GtkAction *toggle;
+
+ gtk_widget_show(win->menubar);
+ toggle = gtk_action_group_get_action(win->ag, "Toolbar");
+ state = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(toggle));
+ gtk_widget_set_visible(win->toolbar, state);
+ toggle = gtk_action_group_get_action(win->ag, "Statusbar");
+ state = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(toggle));
+ gtk_widget_set_visible(win->statusbar, state);
+ }
+ }
+ return TRUE;
+}
+
+static void grab_keys_pressed_cb(GtkWidget *widget, gpointer data)
+{
+ SpiceWindow *win = data;
+
+ /* since mnemonics are disabled, we leave fullscreen when
+ ungrabbing mouse. Perhaps we should have a different handling
+ of fullscreen key, or simply use a UI, like vinagre */
+ window_set_fullscreen(win, FALSE);
+}
+
+static void mouse_grab_cb(GtkWidget *widget, gint grabbed, gpointer data)
+{
+ SpiceWindow *win = data;
+
+ win->mouse_grabbed = grabbed;
+ update_status(win->conn);
+}
+
+static void keyboard_grab_cb(GtkWidget *widget, gint grabbed, gpointer data)
+{
+ SpiceWindow *win = data;
+ GtkSettings *settings = gtk_widget_get_settings (widget);
+
+ if (grabbed) {
+ /* disable mnemonics & accels */
+ g_object_get(settings,
+ "gtk-enable-accels", &win->enable_accels_save,
+ "gtk-enable-mnemonics", &win->enable_mnemonics_save,
+ NULL);
+ g_object_set(settings,
+ "gtk-enable-accels", FALSE,
+ "gtk-enable-mnemonics", FALSE,
+ NULL);
+ } else {
+ g_object_set(settings,
+ "gtk-enable-accels", win->enable_accels_save,
+ "gtk-enable-mnemonics", win->enable_mnemonics_save,
+ NULL);
+ }
+}
+
+static void restore_configuration(SpiceWindow *win)
+{
+ gboolean state;
+ gchar *str;
+ gchar **keys = NULL;
+ gsize nkeys, i;
+ GError *error = NULL;
+ gpointer object;
+
+ keys = g_key_file_get_keys(keyfile, "general", &nkeys, &error);
+ if (error != NULL) {
+ if (error->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND)
+ g_warning("Failed to read configuration file keys: %s", error->message);
+ g_clear_error(&error);
+ return;
+ }
+
+ if (nkeys > 0)
+ g_return_if_fail(keys != NULL);
+
+ for (i = 0; i < nkeys; ++i) {
+ if (g_str_equal(keys[i], "grab-sequence"))
+ continue;
+ state = g_key_file_get_boolean(keyfile, "general", keys[i], &error);
+ if (error != NULL) {
+ g_clear_error(&error);
+ continue;
+ }
+
+ if (is_gtk_session_property(keys[i])) {
+ object = win->conn->gtk_session;
+ } else {
+ object = win->spice;
+ }
+ g_object_set(object, keys[i], state, NULL);
+ }
+
+ g_strfreev(keys);
+
+ str = g_key_file_get_string(keyfile, "general", "grab-sequence", &error);
+ if (error == NULL) {
+ SpiceGrabSequence *seq = spice_grab_sequence_new_from_string(str);
+ spice_display_set_grab_keys(SPICE_DISPLAY(win->spice), seq);
+ spice_grab_sequence_free(seq);
+ g_free(str);
+ }
+ g_clear_error(&error);
+
+
+ state = g_key_file_get_boolean(keyfile, "ui", "toolbar", &error);
+ if (error == NULL)
+ gtk_widget_set_visible(win->toolbar, state);
+ g_clear_error(&error);
+
+ state = g_key_file_get_boolean(keyfile, "ui", "statusbar", &error);
+ if (error == NULL)
+ gtk_widget_set_visible(win->statusbar, state);
+ g_clear_error(&error);
+}
+
+/* ------------------------------------------------------------------ */
+
+static const GtkActionEntry entries[] = {
+ {
+ .name = "FileMenu",
+ .label = "_File",
+ },{
+ .name = "FileRecentMenu",
+ .label = "_Recent",
+ },{
+ .name = "EditMenu",
+ .label = "_Edit",
+ },{
+ .name = "ViewMenu",
+ .label = "_View",
+ },{
+ .name = "InputMenu",
+ .label = "_Input",
+ },{
+ .name = "OptionMenu",
+ .label = "_Options",
+ },{
+ .name = "CompressionMenu",
+ .label = "_Preferred image compression",
+ },{
+ .name = "HelpMenu",
+ .label = "_Help",
+ },{
+
+ /* File menu */
+ .name = "Connect",
+ .stock_id = "_Connect",
+ .label = "_Connect ...",
+ .callback = G_CALLBACK(menu_cb_connect),
+ },{
+ .name = "Close",
+ .stock_id = "window-close",
+ .label = "_Close",
+ .callback = G_CALLBACK(menu_cb_close),
+ .accelerator = "", /* none (disable default "<control>W") */
+ },{
+
+ /* Edit menu */
+ .name = "CopyToGuest",
+ .stock_id = "edit-copy",
+ .label = "_Copy to guest",
+ .callback = G_CALLBACK(menu_cb_copy),
+ .accelerator = "", /* none (disable default "<control>C") */
+ },{
+ .name = "PasteFromGuest",
+ .stock_id = "edit-paste",
+ .label = "_Paste from guest",
+ .callback = G_CALLBACK(menu_cb_paste),
+ .accelerator = "", /* none (disable default "<control>V") */
+ },{
+
+ /* View menu */
+ .name = "Fullscreen",
+ .stock_id = "view-fullscreen",
+ .label = "_Fullscreen",
+ .callback = G_CALLBACK(menu_cb_fullscreen),
+ .accelerator = "<shift>F11",
+ },{
+#ifdef USE_SMARTCARD
+ .name = "InsertSmartcard",
+ .label = "_Insert Smartcard",
+ .callback = G_CALLBACK(menu_cb_insert_smartcard),
+ .accelerator = "<shift>F8",
+ },{
+ .name = "RemoveSmartcard",
+ .label = "_Remove Smartcard",
+ .callback = G_CALLBACK(menu_cb_remove_smartcard),
+ .accelerator = "<shift>F9",
+ },{
+#endif
+
+#ifdef USE_USBREDIR
+ .name = "SelectUsbDevices",
+ .label = "_Select USB Devices for redirection",
+ .callback = G_CALLBACK(menu_cb_select_usb_devices),
+ .accelerator = "<shift>F10",
+ },{
+#endif
+
+ .name = "MouseMode",
+ .label = "Toggle _mouse mode",
+ .callback = G_CALLBACK(menu_cb_mouse_mode),
+ .accelerator = "<shift>F7",
+
+ },{
+ /* Help menu */
+ .name = "About",
+ .stock_id = "help-about",
+ .label = "_About ...",
+ .callback = G_CALLBACK(menu_cb_about),
+ }
+};
+
+static const char *spice_display_properties[] = {
+ "grab-keyboard",
+ "grab-mouse",
+ "resize-guest",
+ "scaling",
+ "disable-inputs",
+};
+
+static const char *spice_gtk_session_properties[] = {
+ "auto-clipboard",
+ "auto-usbredir",
+ "sync-modifiers",
+};
+
+static const GtkToggleActionEntry tentries[] = {
+ {
+ .name = "grab-keyboard",
+ .label = "Grab keyboard when active and focused",
+ .callback = G_CALLBACK(menu_cb_bool_prop),
+ },{
+ .name = "grab-mouse",
+ .label = "Grab mouse in server mode (no tablet/vdagent)",
+ .callback = G_CALLBACK(menu_cb_bool_prop),
+ },{
+ .name = "resize-guest",
+ .label = "Resize guest to match window size",
+ .callback = G_CALLBACK(menu_cb_bool_prop),
+ },{
+ .name = "scaling",
+ .label = "Scale display",
+ .callback = G_CALLBACK(menu_cb_bool_prop),
+ },{
+ .name = "disable-inputs",
+ .label = "Disable inputs",
+ .callback = G_CALLBACK(menu_cb_bool_prop),
+ },{
+ .name = "sync-modifiers",
+ .label = "Sync modifiers",
+ .callback = G_CALLBACK(menu_cb_bool_prop),
+ },{
+ .name = "auto-clipboard",
+ .label = "Automatic clipboard sharing between host and guest",
+ .callback = G_CALLBACK(menu_cb_bool_prop),
+ },{
+ .name = "auto-usbredir",
+ .label = "Auto redirect newly plugged in USB devices",
+ .callback = G_CALLBACK(menu_cb_bool_prop),
+ },{
+ .name = "Statusbar",
+ .label = "Statusbar",
+ .callback = G_CALLBACK(menu_cb_statusbar),
+ },{
+ .name = "Toolbar",
+ .label = "Toolbar",
+ .callback = G_CALLBACK(menu_cb_toolbar),
+ }
+};
+
+static const GtkRadioActionEntry compression_entries[] = {
+ {
+ .name = "auto-glz",
+ .label = "auto-glz",
+ .value = SPICE_IMAGE_COMPRESSION_AUTO_GLZ,
+ },{
+ .name = "auto-lz",
+ .label = "auto-lz",
+ .value = SPICE_IMAGE_COMPRESSION_AUTO_LZ,
+ },{
+ .name = "quic",
+ .label = "quic",
+ .value = SPICE_IMAGE_COMPRESSION_QUIC,
+ },{
+ .name = "glz",
+ .label = "glz",
+ .value = SPICE_IMAGE_COMPRESSION_GLZ,
+ },{
+ .name = "lz",
+ .label = "lz",
+ .value = SPICE_IMAGE_COMPRESSION_LZ,
+ },{
+#ifdef USE_LZ4
+ .name = "lz4",
+ .label = "lz4",
+ .value = SPICE_IMAGE_COMPRESSION_LZ4,
+ },{
+#endif
+ .name = "off",
+ .label = "off",
+ .value = SPICE_IMAGE_COMPRESSION_OFF,
+ }
+};
+
+static char ui_xml[] =
+"<ui>\n"
+" <menubar action='MainMenu'>\n"
+" <menu action='FileMenu'>\n"
+" <menuitem action='Connect'/>\n"
+" <menu action='FileRecentMenu'/>\n"
+" <separator/>\n"
+" <menuitem action='Close'/>\n"
+" </menu>\n"
+" <menu action='EditMenu'>\n"
+" <menuitem action='CopyToGuest'/>\n"
+" <menuitem action='PasteFromGuest'/>\n"
+" </menu>\n"
+" <menu action='ViewMenu'>\n"
+" <menuitem action='Fullscreen'/>\n"
+" <menuitem action='Toolbar'/>\n"
+" <menuitem action='Statusbar'/>\n"
+" </menu>\n"
+" <menu action='InputMenu'>\n"
+#ifdef USE_SMARTCARD
+" <menuitem action='InsertSmartcard'/>\n"
+" <menuitem action='RemoveSmartcard'/>\n"
+#endif
+#ifdef USE_USBREDIR
+" <menuitem action='SelectUsbDevices'/>\n"
+#endif
+" </menu>\n"
+" <menu action='OptionMenu'>\n"
+" <menuitem action='grab-keyboard'/>\n"
+" <menuitem action='grab-mouse'/>\n"
+" <menuitem action='MouseMode'/>\n"
+" <menuitem action='resize-guest'/>\n"
+" <menuitem action='scaling'/>\n"
+" <menuitem action='disable-inputs'/>\n"
+" <menuitem action='sync-modifiers'/>\n"
+" <menuitem action='auto-clipboard'/>\n"
+" <menuitem action='auto-usbredir'/>\n"
+" <menu action='CompressionMenu'>\n"
+" <menuitem action='auto-glz'/>\n"
+" <menuitem action='auto-lz'/>\n"
+" <menuitem action='quic'/>\n"
+" <menuitem action='glz'/>\n"
+" <menuitem action='lz'/>\n"
+#ifdef USE_LZ4
+" <menuitem action='lz4'/>\n"
+#endif
+" <menuitem action='off'/>\n"
+" </menu>\n"
+" </menu>\n"
+" <menu action='HelpMenu'>\n"
+" <menuitem action='About'/>\n"
+" </menu>\n"
+" </menubar>\n"
+" <toolbar action='ToolBar'>\n"
+" <toolitem action='Close'/>\n"
+" <separator/>\n"
+" <toolitem action='CopyToGuest'/>\n"
+" <toolitem action='PasteFromGuest'/>\n"
+" <separator/>\n"
+" <toolitem action='Fullscreen'/>\n"
+" </toolbar>\n"
+"</ui>\n";
+
+static gboolean is_gtk_session_property(const gchar *property)
+{
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS(spice_gtk_session_properties); i++) {
+ if (!strcmp(spice_gtk_session_properties[i], property)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void recent_item_activated_cb(GtkRecentChooser *chooser, gpointer data)
+{
+ GtkRecentInfo *info;
+ struct spice_connection *conn;
+ const char *uri;
+
+ info = gtk_recent_chooser_get_current_item(chooser);
+
+ uri = gtk_recent_info_get_uri(info);
+ g_return_if_fail(uri != NULL);
+
+ conn = connection_new();
+ g_object_set(conn->session, "uri", uri, NULL);
+ gtk_recent_info_unref(info);
+ connection_connect(conn);
+}
+
+static void compression_cb(GtkRadioAction *action G_GNUC_UNUSED,
+ GtkRadioAction *current,
+ gpointer user_data)
+{
+ spice_display_change_preferred_compression(SPICE_CHANNEL(user_data),
+ gtk_radio_action_get_current_value(current));
+}
+
+static void
+spice_window_class_init (SpiceWindowClass *klass)
+{
+}
+
+static void
+spice_window_init (SpiceWindow *self)
+{
+}
+
+static SpiceWindow *create_spice_window(spice_connection *conn, SpiceChannel *channel, int id, gint monitor_id)
+{
+ char title[32];
+ SpiceWindow *win;
+ GtkAction *toggle;
+ gboolean state;
+ GtkWidget *vbox, *frame;
+ GError *err = NULL;
+ int i;
+ SpiceGrabSequence *seq;
+
+ win = g_object_new(SPICE_TYPE_WINDOW, NULL);
+ win->id = id;
+ win->monitor_id = monitor_id;
+ win->conn = conn;
+ win->display_channel = channel;
+
+ /* toplevel */
+ win->toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ if (spicy_title == NULL) {
+ snprintf(title, sizeof(title), "spice display %d:%d", id, monitor_id);
+ } else {
+ snprintf(title, sizeof(title), "%s", spicy_title);
+ }
+
+ gtk_window_set_title(GTK_WINDOW(win->toplevel), title);
+ g_signal_connect(G_OBJECT(win->toplevel), "window-state-event",
+ G_CALLBACK(window_state_cb), win);
+ g_signal_connect(G_OBJECT(win->toplevel), "delete-event",
+ G_CALLBACK(delete_cb), win);
+
+ /* menu + toolbar */
+ win->ui = gtk_ui_manager_new();
+ win->ag = gtk_action_group_new("MenuActions");
+ gtk_action_group_add_actions(win->ag, entries, G_N_ELEMENTS(entries), win);
+ gtk_action_group_add_toggle_actions(win->ag, tentries,
+ G_N_ELEMENTS(tentries), win);
+ gtk_action_group_add_radio_actions(win->ag, compression_entries,
+ G_N_ELEMENTS(compression_entries), -1,
+ G_CALLBACK(compression_cb), win->display_channel);
+ if (!spice_channel_test_capability(win->display_channel, SPICE_DISPLAY_CAP_PREF_COMPRESSION)) {
+ GtkAction *compression_menu_action = gtk_action_group_get_action(win->ag, "CompressionMenu");
+ gtk_action_set_sensitive(compression_menu_action, FALSE);
+ }
+ gtk_ui_manager_insert_action_group(win->ui, win->ag, 0);
+ gtk_window_add_accel_group(GTK_WINDOW(win->toplevel),
+ gtk_ui_manager_get_accel_group(win->ui));
+
+ err = NULL;
+ if (!gtk_ui_manager_add_ui_from_string(win->ui, ui_xml, -1, &err)) {
+ g_warning("building menus failed: %s", err->message);
+ g_error_free(err);
+ exit(1);
+ }
+ win->menubar = gtk_ui_manager_get_widget(win->ui, "/MainMenu");
+ win->toolbar = gtk_ui_manager_get_widget(win->ui, "/ToolBar");
+
+ /* recent menu */
+ win->ritem = gtk_ui_manager_get_widget
+ (win->ui, "/MainMenu/FileMenu/FileRecentMenu");
+
+ GtkRecentFilter *rfilter;
+
+ win->rmenu = gtk_recent_chooser_menu_new();
+ gtk_recent_chooser_set_show_icons(GTK_RECENT_CHOOSER(win->rmenu), FALSE);
+ rfilter = gtk_recent_filter_new();
+ gtk_recent_filter_add_mime_type(rfilter, "application/x-spice");
+ gtk_recent_chooser_add_filter(GTK_RECENT_CHOOSER(win->rmenu), rfilter);
+ gtk_recent_chooser_set_local_only(GTK_RECENT_CHOOSER(win->rmenu), FALSE);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(win->ritem), win->rmenu);
+ g_signal_connect(win->rmenu, "item-activated",
+ G_CALLBACK(recent_item_activated_cb), win);
+
+ /* spice display */
+ win->spice = GTK_WIDGET(spice_display_new_with_monitor(conn->session, id, monitor_id));
+ seq = spice_grab_sequence_new_from_string("Shift_L+F12");
+ spice_display_set_grab_keys(SPICE_DISPLAY(win->spice), seq);
+ spice_grab_sequence_free(seq);
+
+ g_signal_connect(G_OBJECT(win->spice), "mouse-grab",
+ G_CALLBACK(mouse_grab_cb), win);
+ g_signal_connect(G_OBJECT(win->spice), "keyboard-grab",
+ G_CALLBACK(keyboard_grab_cb), win);
+ g_signal_connect(G_OBJECT(win->spice), "grab-keys-pressed",
+ G_CALLBACK(grab_keys_pressed_cb), win);
+
+ /* status line */
+ win->statusbar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 1);
+
+ win->status = gtk_label_new("status line");
+ gtk_misc_set_alignment(GTK_MISC(win->status), 0, 0.5);
+ gtk_misc_set_padding(GTK_MISC(win->status), 3, 1);
+ update_status_window(win);
+
+ frame = gtk_frame_new(NULL);
+ gtk_box_pack_start(GTK_BOX(win->statusbar), frame, TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(frame), win->status);
+
+ for (i = 0; i < STATE_MAX; i++) {
+ win->st[i] = gtk_label_new("?");
+ gtk_label_set_width_chars(GTK_LABEL(win->st[i]), 5);
+ frame = gtk_frame_new(NULL);
+ gtk_box_pack_end(GTK_BOX(win->statusbar), frame, FALSE, FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(frame), win->st[i]);
+ }
+
+ /* Make a vbox and put stuff in */
+ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 0);
+ gtk_container_add(GTK_CONTAINER(win->toplevel), vbox);
+ gtk_box_pack_start(GTK_BOX(vbox), win->menubar, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), win->toolbar, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), win->spice, TRUE, TRUE, 0);
+ gtk_box_pack_end(GTK_BOX(vbox), win->statusbar, FALSE, TRUE, 0);
+
+ /* show window */
+ if (fullscreen)
+ gtk_window_fullscreen(GTK_WINDOW(win->toplevel));
+
+ gtk_widget_show_all(vbox);
+ restore_configuration(win);
+
+ /* init toggle actions */
+ for (i = 0; i < G_N_ELEMENTS(spice_display_properties); i++) {
+ toggle = gtk_action_group_get_action(win->ag,
+ spice_display_properties[i]);
+ g_object_get(win->spice, spice_display_properties[i], &state, NULL);
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(toggle), state);
+ }
+
+ for (i = 0; i < G_N_ELEMENTS(spice_gtk_session_properties); i++) {
+ char notify[64];
+
+ toggle = gtk_action_group_get_action(win->ag,
+ spice_gtk_session_properties[i]);
+ g_object_get(win->conn->gtk_session, spice_gtk_session_properties[i],
+ &state, NULL);
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(toggle), state);
+
+ snprintf(notify, sizeof(notify), "notify::%s",
+ spice_gtk_session_properties[i]);
+ spice_g_signal_connect_object(win->conn->gtk_session, notify,
+ G_CALLBACK(menu_cb_conn_bool_prop_changed),
+ win, 0);
+ }
+
+ update_edit_menu_window(win);
+
+ toggle = gtk_action_group_get_action(win->ag, "Toolbar");
+ state = gtk_widget_get_visible(win->toolbar);
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(toggle), state);
+
+ toggle = gtk_action_group_get_action(win->ag, "Statusbar");
+ state = gtk_widget_get_visible(win->statusbar);
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(toggle), state);
+
+#ifdef USE_SMARTCARD
+ gboolean smartcard;
+
+ enable_smartcard_actions(win, NULL, FALSE, FALSE);
+ g_object_get(G_OBJECT(conn->session),
+ "enable-smartcard", &smartcard,
+ NULL);
+ if (smartcard) {
+ g_signal_connect(G_OBJECT(spice_smartcard_manager_get()), "reader-added",
+ (GCallback)reader_added_cb, win);
+ g_signal_connect(G_OBJECT(spice_smartcard_manager_get()), "reader-removed",
+ (GCallback)reader_removed_cb, win);
+ g_signal_connect(G_OBJECT(spice_smartcard_manager_get()), "card-inserted",
+ (GCallback)card_inserted_cb, win);
+ g_signal_connect(G_OBJECT(spice_smartcard_manager_get()), "card-removed",
+ (GCallback)card_removed_cb, win);
+ }
+#endif
+
+#ifndef USE_USBREDIR
+ GtkAction *usbredir = gtk_action_group_get_action(win->ag, "auto-usbredir");
+ gtk_action_set_visible(usbredir, FALSE);
+#endif
+
+ gtk_widget_grab_focus(win->spice);
+
+ return win;
+}
+
+static void destroy_spice_window(SpiceWindow *win)
+{
+ if (win == NULL)
+ return;
+
+ SPICE_DEBUG("destroy window (#%d:%d)", win->id, win->monitor_id);
+ g_object_unref(win->ag);
+ g_object_unref(win->ui);
+ gtk_widget_destroy(win->toplevel);
+ g_object_unref(win);
+}
+
+/* ------------------------------------------------------------------ */
+
+static void recent_add(SpiceSession *session)
+{
+ GtkRecentManager *recent;
+ GtkRecentData meta = {
+ .mime_type = (char*)"application/x-spice",
+ .app_name = (char*)"spicy",
+ .app_exec = (char*)"spicy --uri=%u",
+ };
+ char *uri;
+
+ g_object_get(session, "uri", &uri, NULL);
+ SPICE_DEBUG("%s: %s", __FUNCTION__, uri);
+
+ recent = gtk_recent_manager_get_default();
+ if (g_str_has_prefix(uri, "spice://"))
+ meta.display_name = uri + 8;
+ else if (g_str_has_prefix(uri, "spice+unix://"))
+ meta.display_name = uri + 13;
+ else
+ g_return_if_reached();
+
+ if (!gtk_recent_manager_add_full(recent, uri, &meta))
+ g_warning("Recent item couldn't be added successfully");
+
+ g_free(uri);
+}
+
+static void main_channel_event(SpiceChannel *channel, SpiceChannelEvent event,
+ gpointer data)
+{
+ const GError *error = NULL;
+ spice_connection *conn = data;
+ char password[64];
+ int rc;
+
+ switch (event) {
+ case SPICE_CHANNEL_OPENED:
+ g_message("main channel: opened");
+ recent_add(conn->session);
+ break;
+ case SPICE_CHANNEL_SWITCHING:
+ g_message("main channel: switching host");
+ break;
+ case SPICE_CHANNEL_CLOSED:
+ /* this event is only sent if the channel was succesfully opened before */
+ g_message("main channel: closed");
+ connection_disconnect(conn);
+ break;
+ case SPICE_CHANNEL_ERROR_IO:
+ connection_disconnect(conn);
+ break;
+ case SPICE_CHANNEL_ERROR_TLS:
+ case SPICE_CHANNEL_ERROR_LINK:
+ case SPICE_CHANNEL_ERROR_CONNECT:
+ error = spice_channel_get_error(channel);
+ g_message("main channel: failed to connect");
+ if (error) {
+ g_message("channel error: %s", error->message);
+ }
+
+ if (spicy_connect_dialog(conn->session)) {
+ connection_connect(conn);
+ } else {
+ connection_disconnect(conn);
+ }
+ break;
+ case SPICE_CHANNEL_ERROR_AUTH:
+ g_warning("main channel: auth failure (wrong password?)");
+ strcpy(password, "");
+ /* FIXME i18 */
+ rc = ask_user(NULL, "Authentication",
+ "Please enter the spice server password",
+ password, sizeof(password), true);
+ if (rc == 0) {
+ g_object_set(conn->session, "password", password, NULL);
+ connection_connect(conn);
+ } else {
+ connection_disconnect(conn);
+ }
+ break;
+ default:
+ /* TODO: more sophisticated error handling */
+ g_warning("unknown main channel event: %u", event);
+ /* connection_disconnect(conn); */
+ break;
+ }
+}
+
+static void main_mouse_update(SpiceChannel *channel, gpointer data)
+{
+ spice_connection *conn = data;
+ gint mode;
+
+ g_object_get(channel, "mouse-mode", &mode, NULL);
+ switch (mode) {
+ case SPICE_MOUSE_MODE_SERVER:
+ conn->mouse_state = "server";
+ break;
+ case SPICE_MOUSE_MODE_CLIENT:
+ conn->mouse_state = "client";
+ break;
+ default:
+ conn->mouse_state = "?";
+ break;
+ }
+ update_status(conn);
+}
+
+static void main_agent_update(SpiceChannel *channel, gpointer data)
+{
+ spice_connection *conn = data;
+
+ g_object_get(channel, "agent-connected", &conn->agent_connected, NULL);
+ conn->agent_state = conn->agent_connected ? "yes" : "no";
+ update_status(conn);
+ update_edit_menu(conn);
+}
+
+static void inputs_modifiers(SpiceChannel *channel, gpointer data)
+{
+ spice_connection *conn = data;
+ int m, i;
+
+ g_object_get(channel, "key-modifiers", &m, NULL);
+ for (i = 0; i < SPICE_N_ELEMENTS(conn->wins); i++) {
+ if (conn->wins[i] == NULL)
+ continue;
+
+ gtk_label_set_text(GTK_LABEL(conn->wins[i]->st[STATE_SCROLL_LOCK]),
+ m & SPICE_KEYBOARD_MODIFIER_FLAGS_SCROLL_LOCK ? "SCROLL" : "");
+ gtk_label_set_text(GTK_LABEL(conn->wins[i]->st[STATE_CAPS_LOCK]),
+ m & SPICE_KEYBOARD_MODIFIER_FLAGS_CAPS_LOCK ? "CAPS" : "");
+ gtk_label_set_text(GTK_LABEL(conn->wins[i]->st[STATE_NUM_LOCK]),
+ m & SPICE_KEYBOARD_MODIFIER_FLAGS_NUM_LOCK ? "NUM" : "");
+ }
+}
+
+static void display_mark(SpiceChannel *channel, gint mark, SpiceWindow *win)
+{
+ g_return_if_fail(win != NULL);
+ g_return_if_fail(win->toplevel != NULL);
+
+ if (mark == TRUE) {
+ gtk_widget_show(win->toplevel);
+ } else {
+ gtk_widget_hide(win->toplevel);
+ }
+}
+
+static void update_auto_usbredir_sensitive(spice_connection *conn)
+{
+#ifdef USE_USBREDIR
+ int i;
+ GtkAction *ac;
+ gboolean sensitive;
+
+ sensitive = spice_session_has_channel_type(conn->session,
+ SPICE_CHANNEL_USBREDIR);
+ for (i = 0; i < SPICE_N_ELEMENTS(conn->wins); i++) {
+ if (conn->wins[i] == NULL)
+ continue;
+ ac = gtk_action_group_get_action(conn->wins[i]->ag, "auto-usbredir");
+ gtk_action_set_sensitive(ac, sensitive);
+ }
+#endif
+}
+
+static SpiceWindow* get_window(spice_connection *conn, int channel_id, int monitor_id)
+{
+ g_return_val_if_fail(channel_id < CHANNELID_MAX, NULL);
+ g_return_val_if_fail(monitor_id < MONITORID_MAX, NULL);
+
+ return conn->wins[channel_id * CHANNELID_MAX + monitor_id];
+}
+
+static void add_window(spice_connection *conn, SpiceWindow *win)
+{
+ g_return_if_fail(win != NULL);
+ g_return_if_fail(win->id < CHANNELID_MAX);
+ g_return_if_fail(win->monitor_id < MONITORID_MAX);
+ g_return_if_fail(conn->wins[win->id * CHANNELID_MAX + win->monitor_id] == NULL);
+
+ SPICE_DEBUG("add display monitor %d:%d", win->id, win->monitor_id);
+ conn->wins[win->id * CHANNELID_MAX + win->monitor_id] = win;
+}
+
+static void del_window(spice_connection *conn, SpiceWindow *win)
+{
+ if (win == NULL)
+ return;
+
+ g_return_if_fail(win->id < CHANNELID_MAX);
+ g_return_if_fail(win->monitor_id < MONITORID_MAX);
+
+ g_debug("del display monitor %d:%d", win->id, win->monitor_id);
+ conn->wins[win->id * CHANNELID_MAX + win->monitor_id] = NULL;
+ if (win->id > 0)
+ spice_main_set_display_enabled(conn->main, win->id, FALSE);
+ else
+ spice_main_set_display_enabled(conn->main, win->monitor_id, FALSE);
+ spice_main_send_monitor_config(conn->main);
+
+ destroy_spice_window(win);
+}
+
+static void display_monitors(SpiceChannel *display, GParamSpec *pspec,
+ spice_connection *conn)
+{
+ GArray *monitors = NULL;
+ int id;
+ guint i;
+
+ g_object_get(display,
+ "channel-id", &id,
+ "monitors", &monitors,
+ NULL);
+ g_return_if_fail(monitors != NULL);
+
+ for (i = 0; i < monitors->len; i++) {
+ SpiceWindow *w;
+
+ if (!get_window(conn, id, i)) {
+ w = create_spice_window(conn, display, id, i);
+ add_window(conn, w);
+ spice_g_signal_connect_object(display, "display-mark",
+ G_CALLBACK(display_mark), w, 0);
+ gtk_widget_show(w->toplevel);
+ update_auto_usbredir_sensitive(conn);
+ }
+ }
+
+ for (; i < MONITORID_MAX; i++)
+ del_window(conn, get_window(conn, id, i));
+
+ g_clear_pointer(&monitors, g_array_unref);
+}
+
+static void port_write_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpicePortChannel *port = SPICE_PORT_CHANNEL(source_object);
+ GError *error = NULL;
+
+ spice_port_write_finish(port, res, &error);
+ if (error != NULL)
+ g_warning("%s", error->message);
+ g_clear_error(&error);
+}
+
+static void port_flushed_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceChannel *channel = SPICE_CHANNEL(source_object);
+ GError *error = NULL;
+
+ spice_channel_flush_finish(channel, res, &error);
+ if (error != NULL)
+ g_warning("%s", error->message);
+ g_clear_error(&error);
+
+ spice_channel_disconnect(channel, SPICE_CHANNEL_CLOSED);
+}
+
+static gboolean input_cb(GIOChannel *gin, GIOCondition condition, gpointer data)
+{
+ char buf[4096];
+ gsize bytes_read;
+ GIOStatus status;
+
+ if (!(condition & G_IO_IN))
+ return FALSE;
+
+ status = g_io_channel_read_chars(gin, buf, sizeof(buf), &bytes_read, NULL);
+ if (status != G_IO_STATUS_NORMAL)
+ return FALSE;
+
+ if (stdin_port != NULL)
+ spice_port_write_async(stdin_port, buf, bytes_read, NULL, port_write_cb, NULL);
+
+ return TRUE;
+}
+
+static void watch_stdin(void);
+
+static void port_opened(SpiceChannel *channel, GParamSpec *pspec,
+ spice_connection *conn)
+{
+ SpicePortChannel *port = SPICE_PORT_CHANNEL(channel);
+ gchar *name = NULL;
+ gboolean opened = FALSE;
+
+ g_object_get(channel,
+ "port-name", &name,
+ "port-opened", &opened,
+ NULL);
+
+ g_printerr("port %p %s: %s\n", channel, name, opened ? "opened" : "closed");
+
+ if (opened) {
+ /* only send a break event and disconnect */
+ if (g_strcmp0(name, "org.spice.spicy.break") == 0) {
+ spice_port_event(port, SPICE_PORT_EVENT_BREAK);
+ spice_channel_flush_async(channel, NULL, port_flushed_cb, conn);
+ }
+
+ /* handle the first spicy port and connect it to stdin/out */
+ if (g_strcmp0(name, "org.spice.spicy") == 0 && stdin_port == NULL) {
+ watch_stdin();
+ stdin_port = port;
+ }
+ } else {
+ if (port == stdin_port)
+ stdin_port = NULL;
+ }
+
+ g_free(name);
+}
+
+static void port_data(SpicePortChannel *port,
+ gpointer data, int size, spice_connection *conn)
+{
+ int r;
+
+ if (port != stdin_port)
+ return;
+
+ r = write(fileno(stdout), data, size);
+ if (r != size) {
+ g_warning("port write failed result %d/%d errno %d", r, size, errno);
+ }
+}
+
+typedef struct {
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *progress;
+ GtkWidget *label;
+ GtkWidget *cancel;
+} TransferTaskWidgets;
+
+static void transfer_update_progress(GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ spice_connection *conn = user_data;
+ TransferTaskWidgets *widgets = g_hash_table_lookup(conn->transfers, object);
+ g_return_if_fail(widgets);
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(widgets->progress),
+ spice_file_transfer_task_get_progress(SPICE_FILE_TRANSFER_TASK(object)));
+}
+
+static void transfer_task_finished(SpiceFileTransferTask *task, GError *error, spice_connection *conn)
+{
+ if (error)
+ g_warning("%s", error->message);
+ g_hash_table_remove(conn->transfers, task);
+ if (!g_hash_table_size(conn->transfers))
+ gtk_widget_hide(conn->transfer_dialog);
+}
+
+static void dialog_response_cb(GtkDialog *dialog,
+ gint response_id,
+ gpointer user_data)
+{
+ spice_connection *conn = user_data;
+ g_print("Reponse: %i\n", response_id);
+
+ if (response_id == GTK_RESPONSE_CANCEL) {
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_hash_table_iter_init(&iter, conn->transfers);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ SpiceFileTransferTask *task = key;
+ spice_file_transfer_task_cancel(task);
+ }
+ }
+}
+
+static void
+task_cancel_cb(GtkButton *button,
+ gpointer user_data)
+{
+ SpiceFileTransferTask *task = SPICE_FILE_TRANSFER_TASK(user_data);
+ spice_file_transfer_task_cancel(task);
+}
+
+static TransferTaskWidgets *
+transfer_task_widgets_new(SpiceFileTransferTask *task)
+{
+ char *filename;
+ TransferTaskWidgets *widgets = g_new0(TransferTaskWidgets, 1);
+
+ widgets->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ widgets->hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
+ widgets->cancel = gtk_button_new_with_label("Cancel");
+
+ widgets->progress = gtk_progress_bar_new();
+ filename = spice_file_transfer_task_get_filename(task);
+ widgets->label = gtk_label_new(filename);
+ g_free(filename);
+
+ gtk_widget_set_halign(widgets->label, GTK_ALIGN_START);
+ gtk_widget_set_valign(widgets->label, GTK_ALIGN_BASELINE);
+ gtk_widget_set_valign(widgets->progress, GTK_ALIGN_CENTER);
+ gtk_widget_set_hexpand(widgets->progress, TRUE);
+ gtk_widget_set_valign(widgets->cancel, GTK_ALIGN_CENTER);
+ gtk_widget_set_hexpand(widgets->progress, FALSE);
+
+ gtk_box_pack_start(GTK_BOX(widgets->hbox), widgets->progress,
+ TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(widgets->hbox), widgets->cancel,
+ FALSE, TRUE, 0);
+
+ gtk_box_pack_start(GTK_BOX(widgets->vbox), widgets->label,
+ TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(widgets->vbox), widgets->hbox,
+ TRUE, TRUE, 0);
+
+ g_signal_connect(widgets->cancel, "clicked",
+ G_CALLBACK(task_cancel_cb), task);
+
+ gtk_widget_show_all(widgets->vbox);
+
+ return widgets;
+}
+
+static void
+transfer_task_widgets_free(TransferTaskWidgets *widgets)
+{
+ /* child widgets will be destroyed automatically */
+ gtk_widget_destroy(widgets->vbox);
+ g_free(widgets);
+}
+
+static void spice_connection_add_task(spice_connection *conn, SpiceFileTransferTask *task)
+{
+ TransferTaskWidgets *widgets;
+ GtkWidget *content = NULL;
+
+ g_signal_connect(task, "notify::progress",
+ G_CALLBACK(transfer_update_progress), conn);
+ g_signal_connect(task, "finished",
+ G_CALLBACK(transfer_task_finished), conn);
+ if (!conn->transfer_dialog) {
+ conn->transfer_dialog = gtk_dialog_new_with_buttons("File Transfers",
+ GTK_WINDOW(conn->wins[0]->toplevel), 0,
+ "Cancel", GTK_RESPONSE_CANCEL, NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(conn->transfer_dialog),
+ GTK_RESPONSE_CANCEL);
+ gtk_window_set_resizable(GTK_WINDOW(conn->transfer_dialog), FALSE);
+ g_signal_connect(conn->transfer_dialog, "response",
+ G_CALLBACK(dialog_response_cb), conn);
+ }
+ gtk_widget_show(conn->transfer_dialog);
+ content = gtk_dialog_get_content_area(GTK_DIALOG(conn->transfer_dialog));
+ gtk_container_set_border_width(GTK_CONTAINER(content), 12);
+
+ widgets = transfer_task_widgets_new(task);
+ g_hash_table_insert(conn->transfers, g_object_ref(task), widgets);
+ gtk_box_pack_start(GTK_BOX(content),
+ widgets->vbox, TRUE, TRUE, 6);
+}
+
+static void new_file_transfer(SpiceMainChannel *main, SpiceFileTransferTask *task, gpointer user_data)
+{
+ spice_connection *conn = user_data;
+ g_debug("new file transfer task");
+ spice_connection_add_task(conn, task);
+}
+
+static void channel_new(SpiceSession *s, SpiceChannel *channel, gpointer data)
+{
+ spice_connection *conn = data;
+ int id;
+
+ g_object_get(channel, "channel-id", &id, NULL);
+ conn->channels++;
+ SPICE_DEBUG("new channel (#%d)", id);
+
+ if (SPICE_IS_MAIN_CHANNEL(channel)) {
+ SPICE_DEBUG("new main channel");
+ conn->main = SPICE_MAIN_CHANNEL(channel);
+ g_signal_connect(channel, "channel-event",
+ G_CALLBACK(main_channel_event), conn);
+ g_signal_connect(channel, "main-mouse-update",
+ G_CALLBACK(main_mouse_update), conn);
+ g_signal_connect(channel, "main-agent-update",
+ G_CALLBACK(main_agent_update), conn);
+ g_signal_connect(channel, "new-file-transfer",
+ G_CALLBACK(new_file_transfer), conn);
+ main_mouse_update(channel, conn);
+ main_agent_update(channel, conn);
+ }
+
+ if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
+ if (id >= SPICE_N_ELEMENTS(conn->wins))
+ return;
+ if (conn->wins[id] != NULL)
+ return;
+ SPICE_DEBUG("new display channel (#%d)", id);
+ g_signal_connect(channel, "notify::monitors",
+ G_CALLBACK(display_monitors), conn);
+ spice_channel_connect(channel);
+ }
+
+ if (SPICE_IS_INPUTS_CHANNEL(channel)) {
+ SPICE_DEBUG("new inputs channel");
+ g_signal_connect(channel, "inputs-modifiers",
+ G_CALLBACK(inputs_modifiers), conn);
+ }
+
+ if (SPICE_IS_PLAYBACK_CHANNEL(channel)) {
+ SPICE_DEBUG("new audio channel");
+ conn->audio = spice_audio_get(s, NULL);
+ }
+
+ if (SPICE_IS_USBREDIR_CHANNEL(channel)) {
+ update_auto_usbredir_sensitive(conn);
+ }
+
+ if (SPICE_IS_PORT_CHANNEL(channel)) {
+ g_signal_connect(channel, "notify::port-opened",
+ G_CALLBACK(port_opened), conn);
+ g_signal_connect(channel, "port-data",
+ G_CALLBACK(port_data), conn);
+ spice_channel_connect(channel);
+ }
+}
+
+static void channel_destroy(SpiceSession *s, SpiceChannel *channel, gpointer data)
+{
+ spice_connection *conn = data;
+ int id;
+
+ g_object_get(channel, "channel-id", &id, NULL);
+ if (SPICE_IS_MAIN_CHANNEL(channel)) {
+ SPICE_DEBUG("zap main channel");
+ conn->main = NULL;
+ }
+
+ if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
+ if (id >= SPICE_N_ELEMENTS(conn->wins))
+ return;
+ SPICE_DEBUG("zap display channel (#%d)", id);
+ /* FIXME destroy widget only */
+ }
+
+ if (SPICE_IS_PLAYBACK_CHANNEL(channel)) {
+ SPICE_DEBUG("zap audio channel");
+ }
+
+ if (SPICE_IS_USBREDIR_CHANNEL(channel)) {
+ update_auto_usbredir_sensitive(conn);
+ }
+
+ if (SPICE_IS_PORT_CHANNEL(channel)) {
+ if (SPICE_PORT_CHANNEL(channel) == stdin_port)
+ stdin_port = NULL;
+ }
+
+ conn->channels--;
+ if (conn->channels > 0) {
+ return;
+ }
+
+ connection_destroy(conn);
+}
+
+static void migration_state(GObject *session,
+ GParamSpec *pspec, gpointer data)
+{
+ SpiceSessionMigration mig;
+
+ g_object_get(session, "migration-state", &mig, NULL);
+ if (mig == SPICE_SESSION_MIGRATION_SWITCHING)
+ g_message("migrating session");
+}
+
+static spice_connection *connection_new(void)
+{
+ spice_connection *conn;
+ SpiceUsbDeviceManager *manager;
+
+ conn = g_new0(spice_connection, 1);
+ conn->session = spice_session_new();
+ conn->gtk_session = spice_gtk_session_get(conn->session);
+ g_signal_connect(conn->session, "channel-new",
+ G_CALLBACK(channel_new), conn);
+ g_signal_connect(conn->session, "channel-destroy",
+ G_CALLBACK(channel_destroy), conn);
+ g_signal_connect(conn->session, "notify::migration-state",
+ G_CALLBACK(migration_state), conn);
+
+ manager = spice_usb_device_manager_get(conn->session, NULL);
+ if (manager) {
+ g_signal_connect(manager, "auto-connect-failed",
+ G_CALLBACK(usb_connect_failed), NULL);
+ g_signal_connect(manager, "device-error",
+ G_CALLBACK(usb_connect_failed), NULL);
+ }
+
+ conn->transfers = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ g_object_unref,
+ (GDestroyNotify)transfer_task_widgets_free);
+ connections++;
+ SPICE_DEBUG("%s (%d)", __FUNCTION__, connections);
+ return conn;
+}
+
+static void connection_connect(spice_connection *conn)
+{
+ conn->disconnecting = false;
+ spice_session_connect(conn->session);
+}
+
+static void connection_disconnect(spice_connection *conn)
+{
+ if (conn->disconnecting)
+ return;
+ conn->disconnecting = true;
+ spice_session_disconnect(conn->session);
+}
+
+static void connection_destroy(spice_connection *conn)
+{
+ g_object_unref(conn->session);
+ g_hash_table_unref(conn->transfers);
+ free(conn);
+
+ connections--;
+ SPICE_DEBUG("%s (%d)", __FUNCTION__, connections);
+ if (connections > 0) {
+ return;
+ }
+
+ g_main_loop_quit(mainloop);
+}
+
+/* ------------------------------------------------------------------ */
+
+static GOptionEntry cmd_entries[] = {
+ {
+ .long_name = "full-screen",
+ .short_name = 'f',
+ .arg = G_OPTION_ARG_NONE,
+ .arg_data = &fullscreen,
+ .description = "Open in full screen mode",
+ },{
+ .long_name = "version",
+ .arg = G_OPTION_ARG_NONE,
+ .arg_data = &version,
+ .description = "Display version and quit",
+ },{
+ .long_name = "title",
+ .arg = G_OPTION_ARG_STRING,
+ .arg_data = &spicy_title,
+ .description = "Set the window title",
+ .arg_description = "<title>",
+ },{
+ /* end of list */
+ }
+};
+
+static void usb_connect_failed(GObject *object,
+ SpiceUsbDevice *device,
+ GError *error,
+ gpointer data)
+{
+ GtkWidget *dialog;
+
+ if (error->domain == G_IO_ERROR && error->code == G_IO_ERROR_CANCELLED)
+ return;
+
+ dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "USB redirection error");
+ gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
+ "%s", error->message);
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+}
+
+static void setup_terminal(gboolean reset)
+{
+ int stdinfd = fileno(stdin);
+
+ if (!isatty(stdinfd))
+ return;
+
+#ifdef HAVE_TERMIOS_H
+ struct termios tios;
+ static struct termios saved_tios;
+ static bool saved = false;
+
+ if (reset) {
+ if (!saved)
+ return;
+ tios = saved_tios;
+ } else {
+ tcgetattr(stdinfd, &tios);
+ saved_tios = tios;
+ saved = true;
+ tios.c_lflag &= ~(ICANON | ECHO);
+ }
+
+ tcsetattr(stdinfd, TCSANOW, &tios);
+#endif
+}
+
+static void watch_stdin(void)
+{
+ int stdinfd = fileno(stdin);
+ GIOChannel *gin;
+
+ setup_terminal(false);
+ gin = g_io_channel_unix_new(stdinfd);
+ g_io_channel_set_flags(gin, G_IO_FLAG_NONBLOCK, NULL);
+ g_io_add_watch(gin, G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL, input_cb, NULL);
+}
+
+int main(int argc, char *argv[])
+{
+ GError *error = NULL;
+ GOptionContext *context;
+ spice_connection *conn;
+ gchar *conf_file, *conf;
+ char *host = NULL, *port = NULL, *tls_port = NULL, *unix_path = NULL;
+
+ keyfile = g_key_file_new();
+
+ int mode = S_IRWXU;
+ conf_file = g_build_filename(g_get_user_config_dir(), "spicy", NULL);
+ if (g_mkdir_with_parents(conf_file, mode) == -1)
+ SPICE_DEBUG("failed to create config directory");
+ g_free(conf_file);
+
+ conf_file = g_build_filename(g_get_user_config_dir(), "spicy", "settings", NULL);
+ if (!g_key_file_load_from_file(keyfile, conf_file,
+ G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS, &error)) {
+ SPICE_DEBUG("Couldn't load configuration: %s", error->message);
+ g_clear_error(&error);
+ }
+
+ /* parse opts */
+ gtk_init(&argc, &argv);
+ context = g_option_context_new("- spice client test application");
+ g_option_context_set_summary(context, "Gtk+ test client to connect to Spice servers.");
+ g_option_context_set_description(context, "Report bugs to " PACKAGE_BUGREPORT ".");
+ g_option_context_add_group(context, spice_get_option_group());
+ g_option_context_set_main_group(context, spice_cmdline_get_option_group());
+ g_option_context_add_main_entries(context, cmd_entries, NULL);
+ g_option_context_add_group(context, gtk_get_option_group(TRUE));
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_print("option parsing failed: %s\n", error->message);
+ exit(1);
+ }
+ g_option_context_free(context);
+
+ if (version) {
+ g_print("spicy " PACKAGE_VERSION "\n");
+ exit(0);
+ }
+
+ mainloop = g_main_loop_new(NULL, false);
+
+ conn = connection_new();
+ spice_set_session_option(conn->session);
+ spice_cmdline_session_setup(conn->session);
+
+ g_object_get(conn->session,
+ "unix-path", &unix_path,
+ "host", &host,
+ "port", &port,
+ "tls-port", &tls_port,
+ NULL);
+ /* If user doesn't provide hostname and port, show the dialog window
+ instead of connecting to server automatically */
+ if ((host == NULL || (port == NULL && tls_port == NULL)) && unix_path == NULL) {
+ if (!spicy_connect_dialog(conn->session)) {
+ exit(0);
+ }
+ }
+ g_free(host);
+ g_free(port);
+ g_free(tls_port);
+ g_free(unix_path);
+
+ connection_connect(conn);
+ if (connections > 0)
+ g_main_loop_run(mainloop);
+ g_main_loop_unref(mainloop);
+
+ if ((conf = g_key_file_to_data(keyfile, NULL, &error)) == NULL ||
+ !g_file_set_contents(conf_file, conf, -1, &error)) {
+ SPICE_DEBUG("Couldn't save configuration: %s", error->message);
+ g_error_free(error);
+ error = NULL;
+ }
+
+ g_free(conf_file);
+ g_free(conf);
+ g_key_file_free(keyfile);
+
+ g_free(spicy_title);
+
+ setup_terminal(true);
+ return 0;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "usb-acl-helper.h"
+
+/* ------------------------------------------------------------------ */
+/* gobject glue */
+
+#define SPICE_USB_ACL_HELPER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SPICE_TYPE_USB_ACL_HELPER, SpiceUsbAclHelperPrivate))
+
+struct _SpiceUsbAclHelperPrivate {
+ GTask *task;
+ GIOChannel *in_ch;
+ GIOChannel *out_ch;
+ GCancellable *cancellable;
+ gulong cancellable_id;
+};
+
+G_DEFINE_TYPE(SpiceUsbAclHelper, spice_usb_acl_helper, G_TYPE_OBJECT);
+
+static void spice_usb_acl_helper_init(SpiceUsbAclHelper *self)
+{
+ self->priv = SPICE_USB_ACL_HELPER_GET_PRIVATE(self);
+}
+
+static void spice_usb_acl_helper_cleanup(SpiceUsbAclHelper *self)
+{
+ SpiceUsbAclHelperPrivate *priv = self->priv;
+
+ g_cancellable_disconnect(priv->cancellable, priv->cancellable_id);
+ priv->cancellable = NULL;
+ priv->cancellable_id = 0;
+
+ g_clear_object(&priv->task);
+
+ g_clear_pointer(&priv->in_ch, g_io_channel_unref);
+ g_clear_pointer(&priv->out_ch, g_io_channel_unref);
+}
+
+static void spice_usb_acl_helper_finalize(GObject *gobject)
+{
+ spice_usb_acl_helper_cleanup(SPICE_USB_ACL_HELPER(gobject));
+
+ if (G_OBJECT_CLASS(spice_usb_acl_helper_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_usb_acl_helper_parent_class)->finalize(gobject);
+}
+
+static void spice_usb_acl_helper_class_init(SpiceUsbAclHelperClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = spice_usb_acl_helper_finalize;
+
+ g_type_class_add_private(klass, sizeof(SpiceUsbAclHelperPrivate));
+}
+
+/* ------------------------------------------------------------------ */
+/* callbacks */
+
+static void async_result_set_cancelled(GTask *task)
+{
+ g_task_return_new_error(task,
+ G_IO_ERROR, G_IO_ERROR_CANCELLED,
+ "Setting USB device node ACL cancelled");
+}
+
+static gboolean cb_out_watch(GIOChannel *channel,
+ GIOCondition cond,
+ gpointer *user_data)
+{
+ SpiceUsbAclHelper *self = SPICE_USB_ACL_HELPER(user_data);
+ SpiceUsbAclHelperPrivate *priv = self->priv;
+ gboolean success = FALSE;
+ GError *err = NULL;
+ GIOStatus status;
+ gchar *string;
+ gsize size;
+
+ /* Check that we've not been cancelled */
+ if (priv->task == NULL)
+ goto done;
+
+ g_return_val_if_fail(channel == priv->out_ch, FALSE);
+
+ status = g_io_channel_read_line(priv->out_ch, &string, &size, NULL, &err);
+ switch (status) {
+ case G_IO_STATUS_NORMAL:
+ string[strlen(string) - 1] = 0;
+ if (!strcmp(string, "SUCCESS")) {
+ success = TRUE;
+ g_task_return_boolean(priv->task, TRUE);
+ } else if (!strcmp(string, "CANCELED")) {
+ async_result_set_cancelled(priv->task);
+ } else {
+ g_task_return_new_error(priv->task,
+ SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Error setting USB device node ACL: '%s'",
+ string);
+ }
+ g_free(string);
+ break;
+ case G_IO_STATUS_ERROR:
+ g_task_return_error(priv->task, err);
+ break;
+ case G_IO_STATUS_EOF:
+ g_task_return_new_error(priv->task,
+ SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Unexpected EOF reading from acl helper stdout");
+ break;
+ case G_IO_STATUS_AGAIN:
+ return TRUE; /* Wait for more input */
+ }
+
+ g_cancellable_disconnect(priv->cancellable, priv->cancellable_id);
+ priv->cancellable = NULL;
+ priv->cancellable_id = 0;
+
+ g_clear_object(&priv->task);
+
+ if (!success)
+ spice_usb_acl_helper_cleanup(self);
+
+done:
+ g_object_unref(self);
+ return FALSE;
+}
+
+static void cancelled_cb(GCancellable *cancellable, gpointer user_data)
+{
+ SpiceUsbAclHelper *self = SPICE_USB_ACL_HELPER(user_data);
+
+ spice_usb_acl_helper_cancel(self);
+}
+
+static void helper_child_watch_cb(GPid pid, gint status, gpointer user_data)
+{
+ /* Nothing to do, but we need the child watch to avoid zombies */
+}
+
+/* ------------------------------------------------------------------ */
+/* private api */
+
+G_GNUC_INTERNAL
+SpiceUsbAclHelper *spice_usb_acl_helper_new(void)
+{
+ GObject *obj;
+
+ obj = g_object_new(SPICE_TYPE_USB_ACL_HELPER, NULL);
+
+ return SPICE_USB_ACL_HELPER(obj);
+}
+
+G_GNUC_INTERNAL
+void spice_usb_acl_helper_open_acl_async(SpiceUsbAclHelper *self,
+ gint busnum, gint devnum,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail(SPICE_IS_USB_ACL_HELPER(self));
+
+ SpiceUsbAclHelperPrivate *priv = self->priv;
+ GTask *task;
+ GError *err = NULL;
+ GIOStatus status;
+ GPid helper_pid;
+ gsize bytes_written;
+ const gchar *acl_helper = g_getenv("SPICE_USB_ACL_BINARY");
+ if (acl_helper == NULL)
+ acl_helper = ACL_HELPER_PATH"/spice-client-glib-usb-acl-helper";
+ gchar *argv[] = { (char*)acl_helper, NULL };
+ gint in, out;
+ gchar buf[128];
+
+ task = g_task_new(self, cancellable, callback, user_data);
+
+ if (priv->out_ch) {
+ g_task_return_new_error(task,
+ SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Error acl-helper already has an acl open");
+ goto done;
+ }
+
+ if (g_cancellable_set_error_if_cancelled(cancellable, &err)) {
+ g_task_return_error(task, err);
+ goto done;
+ }
+
+ if (!g_spawn_async_with_pipes(NULL, argv, NULL,
+ G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
+ NULL, NULL, &helper_pid, &in, &out, NULL, &err)) {
+ g_task_return_error(task, err);
+ goto done;
+ }
+ g_child_watch_add(helper_pid, helper_child_watch_cb, NULL);
+
+ priv->in_ch = g_io_channel_unix_new(in);
+ g_io_channel_set_close_on_unref(priv->in_ch, TRUE);
+
+ priv->out_ch = g_io_channel_unix_new(out);
+ g_io_channel_set_close_on_unref(priv->out_ch, TRUE);
+ status = g_io_channel_set_flags(priv->out_ch, G_IO_FLAG_NONBLOCK, &err);
+ if (status != G_IO_STATUS_NORMAL) {
+ g_task_return_error(task, err);
+ goto done;
+ }
+
+ snprintf(buf, sizeof(buf), "%d %d\n", busnum, devnum);
+ status = g_io_channel_write_chars(priv->in_ch, buf, -1,
+ &bytes_written, &err);
+ if (status != G_IO_STATUS_NORMAL) {
+ g_task_return_error(task, err);
+ goto done;
+ }
+ status = g_io_channel_flush(priv->in_ch, &err);
+ if (status != G_IO_STATUS_NORMAL) {
+ g_task_return_error(task, err);
+ goto done;
+ }
+
+ priv->task = task;
+ if (cancellable) {
+ priv->cancellable = cancellable;
+ priv->cancellable_id = g_cancellable_connect(cancellable,
+ G_CALLBACK(cancelled_cb),
+ self, NULL);
+ }
+ g_io_add_watch(priv->out_ch, G_IO_IN|G_IO_HUP,
+ (GIOFunc)cb_out_watch, g_object_ref(self));
+ return;
+
+done:
+ spice_usb_acl_helper_cleanup(self);
+ g_object_unref(task);
+}
+
+G_GNUC_INTERNAL
+gboolean spice_usb_acl_helper_open_acl_finish(
+ SpiceUsbAclHelper *self, GAsyncResult *res, GError **err)
+{
+ GTask *task = G_TASK(res);
+
+ g_return_val_if_fail(g_task_is_valid(task, self),
+ FALSE);
+
+ return g_task_propagate_boolean(task, err);
+}
+
+G_GNUC_INTERNAL
+void spice_usb_acl_helper_cancel(SpiceUsbAclHelper *self)
+{
+ g_return_if_fail(SPICE_IS_USB_ACL_HELPER(self));
+
+ SpiceUsbAclHelperPrivate *priv = self->priv;
+ g_return_if_fail(priv->task != NULL);
+
+ async_result_set_cancelled(priv->task);
+ g_clear_object(&priv->task);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_USB_ACL_HELPER_H__
+#define __SPICE_USB_ACL_HELPER_H__
+
+#include "spice-client.h"
+#include <gio/gio.h>
+
+/* Note the entire usb-acl-helper class is private to spice-client-glib !! */
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_USB_ACL_HELPER (spice_usb_acl_helper_get_type ())
+#define SPICE_USB_ACL_HELPER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_USB_ACL_HELPER, SpiceUsbAclHelper))
+#define SPICE_USB_ACL_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_USB_ACL_HELPER, SpiceUsbAclHelperClass))
+#define SPICE_IS_USB_ACL_HELPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_USB_ACL_HELPER))
+#define SPICE_IS_USB_ACL_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_USB_ACL_HELPER))
+#define SPICE_USB_ACL_HELPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_USB_ACL_HELPER, SpiceUsbAclHelperClass))
+
+typedef struct _SpiceUsbAclHelper SpiceUsbAclHelper;
+typedef struct _SpiceUsbAclHelperClass SpiceUsbAclHelperClass;
+typedef struct _SpiceUsbAclHelperPrivate SpiceUsbAclHelperPrivate;
+
+struct _SpiceUsbAclHelper
+{
+ GObject parent;
+
+ /*< private >*/
+ SpiceUsbAclHelperPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+struct _SpiceUsbAclHelperClass
+{
+ GObjectClass parent_class;
+};
+
+GType spice_usb_acl_helper_get_type(void);
+
+SpiceUsbAclHelper *spice_usb_acl_helper_new(void);
+
+void spice_usb_acl_helper_open_acl_async(SpiceUsbAclHelper *self,
+ gint busnum, gint devnum,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean spice_usb_acl_helper_open_acl_finish(
+ SpiceUsbAclHelper *self, GAsyncResult *res, GError **err);
+
+void spice_usb_acl_helper_cancel(SpiceUsbAclHelper *self);
+
+G_END_DECLS
+
+#endif /* __SPICE_USB_ACL_HELPER_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011,2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_USB_DEVICE_MANAGER_PRIV_H__
+#define __SPICE_USB_DEVICE_MANAGER_PRIV_H__
+
+#include "usb-device-manager.h"
+
+G_BEGIN_DECLS
+
+gboolean spice_usb_device_manager_start_event_listening(
+ SpiceUsbDeviceManager *manager, GError **err);
+
+void spice_usb_device_manager_stop_event_listening(
+ SpiceUsbDeviceManager *manager);
+
+#ifdef USE_USBREDIR
+#include <libusb.h>
+void spice_usb_device_manager_device_error(
+ SpiceUsbDeviceManager *manager, SpiceUsbDevice *device, GError *err);
+
+guint8 spice_usb_device_get_busnum(const SpiceUsbDevice *device);
+guint8 spice_usb_device_get_devaddr(const SpiceUsbDevice *device);
+guint16 spice_usb_device_get_vid(const SpiceUsbDevice *device);
+guint16 spice_usb_device_get_pid(const SpiceUsbDevice *device);
+gboolean spice_usb_device_is_isochronous(const SpiceUsbDevice *device);
+
+#endif
+
+G_END_DECLS
+
+#endif /* __SPICE_USB_DEVICE_MANAGER_PRIV_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011, 2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include <glib-object.h>
+
+#ifdef USE_USBREDIR
+#include <errno.h>
+#include <libusb.h>
+
+#ifdef G_OS_WIN32
+#include "usbdk_api.h"
+#endif
+
+#if defined(USE_GUDEV)
+#include <gudev/gudev.h>
+#elif defined(G_OS_WIN32)
+#include "win-usb-dev.h"
+#include "win-usb-driver-install.h"
+#define USE_GUDEV /* win-usb-dev.h provides a fake gudev interface */
+#elif !defined USE_LIBUSB_HOTPLUG
+#error "Expecting one of USE_GUDEV or USE_LIBUSB_HOTPLUG to be defined"
+#endif
+
+#include "channel-usbredir-priv.h"
+#include "usbredirhost.h"
+#include "usbutil.h"
+#endif
+
+#include "spice-session-priv.h"
+#include "spice-client.h"
+#include "spice-marshal.h"
+#include "usb-device-manager-priv.h"
+
+#include <glib/gi18n-lib.h>
+
+#ifndef G_OS_WIN32 /* Linux -- device id is bus.addr */
+#define DEV_ID_FMT "at %u.%u"
+#else /* Windows -- device id is vid:pid */
+#define DEV_ID_FMT "0x%04x:0x%04x"
+#endif
+
+/**
+ * SECTION:usb-device-manager
+ * @short_description: USB device management
+ * @title: Spice USB Manager
+ * @section_id:
+ * @see_also:
+ * @stability: Stable
+ * @include: spice-client.h
+ *
+ * #SpiceUsbDeviceManager monitors USB redirection channels and USB
+ * devices plugging/unplugging. If #SpiceUsbDeviceManager:auto-connect
+ * is set to %TRUE, it will automatically connect newly plugged USB
+ * devices to available channels.
+ *
+ * There should always be a 1:1 relation between #SpiceUsbDeviceManager objects
+ * and #SpiceSession objects. Therefor there is no
+ * spice_usb_device_manager_new, instead there is
+ * spice_usb_device_manager_get() which ensures this 1:1 relation.
+ */
+
+/* ------------------------------------------------------------------ */
+/* gobject glue */
+
+#define SPICE_USB_DEVICE_MANAGER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SPICE_TYPE_USB_DEVICE_MANAGER, SpiceUsbDeviceManagerPrivate))
+
+enum {
+ PROP_0,
+ PROP_SESSION,
+ PROP_AUTO_CONNECT,
+ PROP_AUTO_CONNECT_FILTER,
+ PROP_REDIRECT_ON_CONNECT,
+ PROP_FREE_CHANNELS,
+};
+
+enum
+{
+ DEVICE_ADDED,
+ DEVICE_REMOVED,
+ AUTO_CONNECT_FAILED,
+ DEVICE_ERROR,
+ LAST_SIGNAL,
+};
+
+struct _SpiceUsbDeviceManagerPrivate {
+ SpiceSession *session;
+ gboolean auto_connect;
+ gchar *auto_connect_filter;
+ gchar *redirect_on_connect;
+#ifdef USE_USBREDIR
+ libusb_context *context;
+ int event_listeners;
+ GThread *event_thread;
+ gint event_thread_run;
+ struct usbredirfilter_rule *auto_conn_filter_rules;
+ struct usbredirfilter_rule *redirect_on_connect_rules;
+ int auto_conn_filter_rules_count;
+ int redirect_on_connect_rules_count;
+#ifdef USE_GUDEV
+ GUdevClient *udev;
+ libusb_device **coldplug_list; /* Avoid needless reprobing during init */
+#else
+ gboolean redirecting; /* Handled by GUdevClient in the gudev case */
+ libusb_hotplug_callback_handle hp_handle;
+#endif
+#ifdef G_OS_WIN32
+ usbdk_api_wrapper *usbdk_api;
+ HANDLE usbdk_hider_handle;
+ SpiceWinUsbDriver *installer;
+#endif
+ gboolean use_usbclerk;
+#endif
+ GPtrArray *devices;
+ GPtrArray *channels;
+};
+
+enum {
+ SPICE_USB_DEVICE_STATE_NONE = 0, /* this is also DISCONNECTED */
+ SPICE_USB_DEVICE_STATE_CONNECTING,
+ SPICE_USB_DEVICE_STATE_CONNECTED,
+ SPICE_USB_DEVICE_STATE_DISCONNECTING,
+ SPICE_USB_DEVICE_STATE_INSTALLING,
+ SPICE_USB_DEVICE_STATE_UNINSTALLING,
+ SPICE_USB_DEVICE_STATE_INSTALLED,
+ SPICE_USB_DEVICE_STATE_MAX
+};
+
+#ifdef USE_USBREDIR
+
+typedef struct _SpiceUsbDeviceInfo {
+ guint8 busnum;
+ guint8 devaddr;
+ guint16 vid;
+ guint16 pid;
+ gboolean isochronous;
+#ifdef G_OS_WIN32
+ guint8 state;
+#else
+ libusb_device *libdev;
+#endif
+ gint ref;
+} SpiceUsbDeviceInfo;
+
+
+static void channel_new(SpiceSession *session, SpiceChannel *channel,
+ gpointer user_data);
+static void channel_destroy(SpiceSession *session, SpiceChannel *channel,
+ gpointer user_data);
+#ifdef USE_GUDEV
+static void spice_usb_device_manager_uevent_cb(GUdevClient *client,
+ const gchar *action,
+ GUdevDevice *udevice,
+ gpointer user_data);
+static void spice_usb_device_manager_add_udev(SpiceUsbDeviceManager *self,
+ GUdevDevice *udev);
+#else
+static int spice_usb_device_manager_hotplug_cb(libusb_context *ctx,
+ libusb_device *device,
+ libusb_hotplug_event event,
+ void *data);
+#endif
+static void spice_usb_device_manager_check_redir_on_connect(
+ SpiceUsbDeviceManager *self, SpiceChannel *channel);
+
+static SpiceUsbDeviceInfo *spice_usb_device_new(libusb_device *libdev);
+static SpiceUsbDevice *spice_usb_device_ref(SpiceUsbDevice *device);
+static void spice_usb_device_unref(SpiceUsbDevice *device);
+
+#ifdef G_OS_WIN32
+static guint8 spice_usb_device_get_state(SpiceUsbDevice *device);
+static void spice_usb_device_set_state(SpiceUsbDevice *device, guint8 s);
+
+static void _usbdk_hider_update(SpiceUsbDeviceManager *manager);
+static void _usbdk_hider_clear(SpiceUsbDeviceManager *manager);
+#endif
+
+static gboolean spice_usb_manager_device_equal_libdev(SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device,
+ libusb_device *libdev);
+static libusb_device *
+spice_usb_device_manager_device_to_libdev(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device);
+
+static void
+_spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+static
+void _connect_device_async_cb(GObject *gobject,
+ GAsyncResult *channel_res,
+ gpointer user_data);
+
+G_DEFINE_BOXED_TYPE(SpiceUsbDevice, spice_usb_device,
+ (GBoxedCopyFunc)spice_usb_device_ref,
+ (GBoxedFreeFunc)spice_usb_device_unref)
+
+static void
+_set_redirecting(SpiceUsbDeviceManager *self, gboolean is_redirecting)
+{
+#ifdef USE_GUDEV
+ g_object_set(self->priv->udev, "redirecting", is_redirecting, NULL);
+#else
+ self->priv->redirecting = is_redirecting;
+#endif
+}
+
+#else
+G_DEFINE_BOXED_TYPE(SpiceUsbDevice, spice_usb_device, g_object_ref, g_object_unref)
+#endif
+
+/**
+ * spice_usb_device_manager_is_redirecting:
+ * @self: the #SpiceUsbDeviceManager manager
+ *
+ * Checks whether a device is being redirected
+ *
+ * Returns: %TRUE if device redirection negotiation flow is in progress
+ *
+ * Since: 0.32
+ */
+gboolean spice_usb_device_manager_is_redirecting(SpiceUsbDeviceManager *self)
+{
+#ifdef USE_USBREDIR
+
+#ifdef USE_GUDEV
+ gboolean redirecting;
+ g_object_get(self->priv->udev, "redirecting", &redirecting, NULL);
+ return redirecting;
+#else
+ return self->priv->redirecting;
+#endif
+
+#else
+ return FALSE;
+#endif
+}
+
+static void spice_usb_device_manager_initable_iface_init(GInitableIface *iface);
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE_WITH_CODE(SpiceUsbDeviceManager, spice_usb_device_manager, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, spice_usb_device_manager_initable_iface_init));
+
+static void spice_usb_device_manager_init(SpiceUsbDeviceManager *self)
+{
+ SpiceUsbDeviceManagerPrivate *priv;
+
+ priv = SPICE_USB_DEVICE_MANAGER_GET_PRIVATE(self);
+ self->priv = priv;
+
+#if defined(G_OS_WIN32) && defined(USE_USBREDIR)
+ priv->use_usbclerk = !usbdk_is_driver_installed() ||
+ !(priv->usbdk_api = usbdk_api_load());
+#endif
+ priv->channels = g_ptr_array_new();
+#ifdef USE_USBREDIR
+ priv->devices = g_ptr_array_new_with_free_func((GDestroyNotify)
+ spice_usb_device_unref);
+#endif
+}
+
+static gboolean spice_usb_device_manager_initable_init(GInitable *initable,
+ GCancellable *cancellable,
+ GError **err)
+{
+#ifdef USE_USBREDIR
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(initable);
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+ GList *list;
+ GList *it;
+ int rc;
+#ifdef USE_GUDEV
+ const gchar *const subsystems[] = {"usb", NULL};
+#endif
+
+#ifdef G_OS_WIN32
+ if (priv->use_usbclerk) {
+ priv->installer = spice_win_usb_driver_new(err);
+ if (!priv->installer) {
+ SPICE_DEBUG("failed to initialize winusb driver");
+ return FALSE;
+ }
+ }
+#endif
+
+ /* Initialize libusb */
+ rc = libusb_init(&priv->context);
+ if (rc < 0) {
+ const char *desc = spice_usbutil_libusb_strerror(rc);
+ g_warning("Error initializing USB support: %s [%i]", desc, rc);
+ g_set_error(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Error initializing USB support: %s [%i]", desc, rc);
+ return FALSE;
+ }
+
+ /* Start listening for usb devices plug / unplug */
+#ifdef USE_GUDEV
+ priv->udev = g_udev_client_new(subsystems);
+ g_signal_connect(G_OBJECT(priv->udev), "uevent",
+ G_CALLBACK(spice_usb_device_manager_uevent_cb), self);
+ /* Do coldplug (detection of already connected devices) */
+ libusb_get_device_list(priv->context, &priv->coldplug_list);
+ list = g_udev_client_query_by_subsystem(priv->udev, "usb");
+ for (it = g_list_first(list); it; it = g_list_next(it)) {
+ spice_usb_device_manager_add_udev(self, it->data);
+ g_object_unref(it->data);
+ }
+ g_list_free(list);
+ libusb_free_device_list(priv->coldplug_list, 1);
+ priv->coldplug_list = NULL;
+#else
+ rc = libusb_hotplug_register_callback(priv->context,
+ LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
+ LIBUSB_HOTPLUG_ENUMERATE, LIBUSB_HOTPLUG_MATCH_ANY,
+ LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
+ spice_usb_device_manager_hotplug_cb, self, &priv->hp_handle);
+ if (rc < 0) {
+ const char *desc = spice_usbutil_libusb_strerror(rc);
+ g_warning("Error initializing USB hotplug support: %s [%i]", desc, rc);
+ g_set_error(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Error initializing USB hotplug support: %s [%i]", desc, rc);
+ return FALSE;
+ }
+ spice_usb_device_manager_start_event_listening(self, NULL);
+#endif
+
+ /* Start listening for usb channels connect/disconnect */
+ spice_g_signal_connect_object(priv->session, "channel-new", G_CALLBACK(channel_new), self, G_CONNECT_AFTER);
+ g_signal_connect(priv->session, "channel-destroy",
+ G_CALLBACK(channel_destroy), self);
+ list = spice_session_get_channels(priv->session);
+ for (it = g_list_first(list); it != NULL; it = g_list_next(it)) {
+ channel_new(priv->session, it->data, (gpointer*)self);
+ }
+ g_list_free(list);
+
+ return TRUE;
+#else
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("USB redirection support not compiled in"));
+ return FALSE;
+#endif
+}
+
+static void spice_usb_device_manager_dispose(GObject *gobject)
+{
+#ifdef USE_USBREDIR
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(gobject);
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+
+#ifdef USE_LIBUSB_HOTPLUG
+ if (priv->hp_handle) {
+ spice_usb_device_manager_stop_event_listening(self);
+ if (g_atomic_int_get(&priv->event_thread_run)) {
+ /* Force termination of the event thread even if there were some
+ * mismatched spice_usb_device_manager_{start,stop}_event_listening
+ * calls. Otherwise, the usb event thread will be leaked, and will
+ * try to use the libusb context we destroy in finalize(), which would
+ * cause a crash */
+ g_warn_if_reached();
+ g_atomic_int_set(&priv->event_thread_run, FALSE);
+ }
+ /* This also wakes up the libusb_handle_events() in the event_thread */
+ libusb_hotplug_deregister_callback(priv->context, priv->hp_handle);
+ priv->hp_handle = 0;
+ }
+#endif
+ if (priv->event_thread) {
+ g_warn_if_fail(g_atomic_int_get(&priv->event_thread_run) == FALSE);
+ g_thread_join(priv->event_thread);
+ priv->event_thread = NULL;
+ }
+#endif
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_usb_device_manager_parent_class)->dispose)
+ G_OBJECT_CLASS(spice_usb_device_manager_parent_class)->dispose(gobject);
+}
+
+static void spice_usb_device_manager_finalize(GObject *gobject)
+{
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(gobject);
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+
+ g_ptr_array_unref(priv->channels);
+ if (priv->devices)
+ g_ptr_array_unref(priv->devices);
+
+#ifdef USE_USBREDIR
+#ifdef USE_GUDEV
+ g_clear_object(&priv->udev);
+#endif
+ g_return_if_fail(priv->event_thread == NULL);
+ if (priv->context)
+ libusb_exit(priv->context);
+ free(priv->auto_conn_filter_rules);
+ free(priv->redirect_on_connect_rules);
+#ifdef G_OS_WIN32
+ if (priv->installer) {
+ g_warn_if_fail(priv->use_usbclerk);
+ g_object_unref(priv->installer);
+ }
+ if (!priv->use_usbclerk) {
+ _usbdk_hider_clear(self);
+ usbdk_api_unload(priv->usbdk_api);
+ }
+#endif
+#endif
+
+ g_free(priv->auto_connect_filter);
+ g_free(priv->redirect_on_connect);
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(spice_usb_device_manager_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_usb_device_manager_parent_class)->finalize(gobject);
+}
+
+static void spice_usb_device_manager_initable_iface_init(GInitableIface *iface)
+{
+ iface->init = spice_usb_device_manager_initable_init;
+}
+
+static void spice_usb_device_manager_get_property(GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(gobject);
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+
+ switch (prop_id) {
+ case PROP_SESSION:
+ g_value_set_object(value, priv->session);
+ break;
+ case PROP_AUTO_CONNECT:
+ g_value_set_boolean(value, priv->auto_connect);
+ break;
+ case PROP_AUTO_CONNECT_FILTER:
+ g_value_set_string(value, priv->auto_connect_filter);
+ break;
+ case PROP_REDIRECT_ON_CONNECT:
+ g_value_set_string(value, priv->redirect_on_connect);
+ break;
+ case PROP_FREE_CHANNELS: {
+ int free_channels = 0;
+#ifdef USE_USBREDIR
+ int i;
+ for (i = 0; i < priv->channels->len; i++) {
+ SpiceUsbredirChannel *channel = g_ptr_array_index(priv->channels, i);
+
+ if (!spice_usbredir_channel_get_device(channel))
+ free_channels++;
+ }
+#endif
+ g_value_set_int(value, free_channels);
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_usb_device_manager_set_property(GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(gobject);
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+
+ switch (prop_id) {
+ case PROP_SESSION:
+ priv->session = g_value_get_object(value);
+ break;
+ case PROP_AUTO_CONNECT:
+ priv->auto_connect = g_value_get_boolean(value);
+#if defined(G_OS_WIN32) && defined(USE_USBREDIR)
+ if (!priv->use_usbclerk) {
+ _usbdk_hider_update(self);
+ }
+#endif
+ break;
+ case PROP_AUTO_CONNECT_FILTER: {
+ const gchar *filter = g_value_get_string(value);
+#ifdef USE_USBREDIR
+ struct usbredirfilter_rule *rules;
+ int r, count;
+
+ r = usbredirfilter_string_to_rules(filter, ",", "|", &rules, &count);
+ if (r) {
+ if (r == -ENOMEM)
+ g_error("Failed to allocate memory for auto-connect-filter");
+ g_warning("Error parsing auto-connect-filter string, keeping old filter");
+ break;
+ }
+
+ SPICE_DEBUG("auto-connect filter set to %s", filter);
+ free(priv->auto_conn_filter_rules);
+ priv->auto_conn_filter_rules = rules;
+ priv->auto_conn_filter_rules_count = count;
+#endif
+ g_free(priv->auto_connect_filter);
+ priv->auto_connect_filter = g_strdup(filter);
+
+#if defined(G_OS_WIN32) && defined(USE_USBREDIR)
+ if (!priv->use_usbclerk) {
+ _usbdk_hider_update(self);
+ }
+#endif
+ break;
+ }
+ case PROP_REDIRECT_ON_CONNECT: {
+ const gchar *filter = g_value_get_string(value);
+#ifdef USE_USBREDIR
+ struct usbredirfilter_rule *rules = NULL;
+ int r = 0, count = 0;
+
+ if (filter)
+ r = usbredirfilter_string_to_rules(filter, ",", "|",
+ &rules, &count);
+ if (r) {
+ if (r == -ENOMEM)
+ g_error("Failed to allocate memory for redirect-on-connect");
+ g_warning("Error parsing redirect-on-connect string, keeping old filter");
+ break;
+ }
+
+ SPICE_DEBUG("redirect-on-connect filter set to %s", filter);
+ free(priv->redirect_on_connect_rules);
+ priv->redirect_on_connect_rules = rules;
+ priv->redirect_on_connect_rules_count = count;
+#endif
+ g_free(priv->redirect_on_connect);
+ priv->redirect_on_connect = g_strdup(filter);
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_usb_device_manager_class_init(SpiceUsbDeviceManagerClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GParamSpec *pspec;
+
+ gobject_class->dispose = spice_usb_device_manager_dispose;
+ gobject_class->finalize = spice_usb_device_manager_finalize;
+ gobject_class->get_property = spice_usb_device_manager_get_property;
+ gobject_class->set_property = spice_usb_device_manager_set_property;
+
+ /**
+ * SpiceUsbDeviceManager:session:
+ *
+ * #SpiceSession this #SpiceUsbDeviceManager is associated with
+ *
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_SESSION,
+ g_param_spec_object("session",
+ "Session",
+ "SpiceSession",
+ SPICE_TYPE_SESSION,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * SpiceUsbDeviceManager:auto-connect:
+ *
+ * Set this to TRUE to automatically redirect newly plugged in device.
+ *
+ * Note when #SpiceGtkSession's auto-usbredir property is TRUE, this
+ * property is controlled by #SpiceGtkSession.
+ */
+ pspec = g_param_spec_boolean("auto-connect", "Auto Connect",
+ "Auto connect plugged in USB devices",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property(gobject_class, PROP_AUTO_CONNECT, pspec);
+
+ /**
+ * SpiceUsbDeviceManager:auto-connect-filter:
+ *
+ * Set a string specifying a filter to use to determine which USB devices
+ * to autoconnect when plugged in, a filter consists of one or more rules.
+ * Where each rule has the form of:
+ *
+ * @class,@vendor,@product,@version,@allow
+ *
+ * Use -1 for @class/@vendor/@product/@version to accept any value.
+ *
+ * And the rules themselves are concatenated like this:
+ *
+ * @rule1|@rule2|@rule3
+ *
+ * The default setting filters out HID (class 0x03) USB devices from auto
+ * connect and auto connects anything else. Note the explicit allow rule at
+ * the end, this is necessary since by default all devices without a
+ * matching filter rule will not auto-connect.
+ *
+ * Filter strings in this format can be easily created with the RHEV-M
+ * USB filter editor tool.
+ */
+ pspec = g_param_spec_string("auto-connect-filter", "Auto Connect Filter ",
+ "Filter determining which USB devices to auto connect",
+ "0x03,-1,-1,-1,0|-1,-1,-1,-1,1",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property(gobject_class, PROP_AUTO_CONNECT_FILTER,
+ pspec);
+
+ /**
+ * SpiceUsbDeviceManager:redirect-on-connect:
+ *
+ * Set a string specifying a filter selecting USB devices to automatically
+ * redirect after a Spice connection has been established.
+ *
+ * See #SpiceUsbDeviceManager:auto-connect-filter for the filter string
+ * format.
+ */
+ pspec = g_param_spec_string("redirect-on-connect", "Redirect on connect",
+ "Filter selecting USB devices to redirect on connect", NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property(gobject_class, PROP_REDIRECT_ON_CONNECT,
+ pspec);
+
+ /**
+ * SpiceUsbDeviceManager:n-free-channels:
+ *
+ * Get a list of avaialable channels for redirecting USB devices.
+ *
+ * Since: 0.31
+ */
+ pspec = g_param_spec_int("free-channels", "Free channels",
+ "The number of available channels for redirecting USB devices",
+ 0,
+ G_MAXINT,
+ 0,
+ G_PARAM_READABLE);
+ g_object_class_install_property(gobject_class, PROP_FREE_CHANNELS,
+ pspec);
+
+ /**
+ * SpiceUsbDeviceManager::device-added:
+ * @manager: the #SpiceUsbDeviceManager that emitted the signal
+ * @device: #SpiceUsbDevice boxed object corresponding to the added device
+ *
+ * The #SpiceUsbDeviceManager::device-added signal is emitted whenever
+ * a new USB device has been plugged in.
+ **/
+ signals[DEVICE_ADDED] =
+ g_signal_new("device-added",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceUsbDeviceManagerClass, device_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1,
+ SPICE_TYPE_USB_DEVICE);
+
+ /**
+ * SpiceUsbDeviceManager::device-removed:
+ * @manager: the #SpiceUsbDeviceManager that emitted the signal
+ * @device: #SpiceUsbDevice boxed object corresponding to the removed device
+ *
+ * The #SpiceUsbDeviceManager::device-removed signal is emitted whenever
+ * an USB device has been removed.
+ **/
+ signals[DEVICE_REMOVED] =
+ g_signal_new("device-removed",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceUsbDeviceManagerClass, device_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1,
+ SPICE_TYPE_USB_DEVICE);
+
+ /**
+ * SpiceUsbDeviceManager::auto-connect-failed:
+ * @manager: the #SpiceUsbDeviceManager that emitted the signal
+ * @device: #SpiceUsbDevice boxed object corresponding to the device which failed to auto connect
+ * @error: #GError describing the reason why the autoconnect failed
+ *
+ * The #SpiceUsbDeviceManager::auto-connect-failed signal is emitted
+ * whenever the auto-connect property is true, and a newly plugged in
+ * device could not be auto-connected.
+ **/
+ signals[AUTO_CONNECT_FAILED] =
+ g_signal_new("auto-connect-failed",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceUsbDeviceManagerClass, auto_connect_failed),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__BOXED_BOXED,
+ G_TYPE_NONE,
+ 2,
+ SPICE_TYPE_USB_DEVICE,
+ G_TYPE_ERROR);
+
+ /**
+ * SpiceUsbDeviceManager::device-error:
+ * @manager: #SpiceUsbDeviceManager that emitted the signal
+ * @device: #SpiceUsbDevice boxed object corresponding to the device which has an error
+ * @error: #GError describing the error
+ *
+ * The #SpiceUsbDeviceManager::device-error signal is emitted whenever an
+ * error happens which causes a device to no longer be available to the
+ * guest.
+ **/
+ signals[DEVICE_ERROR] =
+ g_signal_new("device-error",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceUsbDeviceManagerClass, device_error),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__BOXED_BOXED,
+ G_TYPE_NONE,
+ 2,
+ SPICE_TYPE_USB_DEVICE,
+ G_TYPE_ERROR);
+
+ g_type_class_add_private(klass, sizeof(SpiceUsbDeviceManagerPrivate));
+}
+
+#ifdef USE_USBREDIR
+
+/* ------------------------------------------------------------------ */
+/* gudev / libusb Helper functions */
+
+#ifdef USE_GUDEV
+static gboolean spice_usb_device_manager_get_udev_bus_n_address(
+ SpiceUsbDeviceManager *manager, GUdevDevice *udev,
+ int *bus, int *address)
+{
+ const gchar *bus_str, *address_str;
+
+ *bus = *address = 0;
+
+ if (manager->priv->use_usbclerk) {
+ /* Windows WinUsb/UsbClerk -- request vid:pid instead */
+ bus_str = g_udev_device_get_property(udev, "VID");
+ address_str = g_udev_device_get_property(udev, "PID");
+ } else {
+ /* Linux or UsbDk backend on Windows*/
+ bus_str = g_udev_device_get_property(udev, "BUSNUM");
+ address_str = g_udev_device_get_property(udev, "DEVNUM");
+ }
+ if (bus_str)
+ *bus = atoi(bus_str);
+ if (address_str)
+ *address = atoi(address_str);
+
+ return *bus && *address;
+}
+#endif
+
+static gboolean spice_usb_device_manager_get_device_descriptor(
+ libusb_device *libdev,
+ struct libusb_device_descriptor *desc)
+{
+ int errcode;
+ const gchar *errstr;
+
+ g_return_val_if_fail(libdev != NULL, FALSE);
+ g_return_val_if_fail(desc != NULL, FALSE);
+
+ errcode = libusb_get_device_descriptor(libdev, desc);
+ if (errcode < 0) {
+ int bus, addr;
+
+ bus = libusb_get_bus_number(libdev);
+ addr = libusb_get_device_address(libdev);
+ errstr = spice_usbutil_libusb_strerror(errcode);
+ g_warning("cannot get device descriptor for (%p) %d.%d -- %s(%d)",
+ libdev, bus, addr, errstr, errcode);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/**
+ * spice_usb_device_get_libusb_device:
+ * @device: #SpiceUsbDevice to get the descriptor information of
+ *
+ * Finds the %libusb_device associated with the @device.
+ *
+ * Returns: (transfer none): the %libusb_device associated to %SpiceUsbDevice.
+ *
+ * Since: 0.27
+ **/
+gconstpointer
+spice_usb_device_get_libusb_device(const SpiceUsbDevice *device G_GNUC_UNUSED)
+{
+#ifdef USE_USBREDIR
+#ifndef G_OS_WIN32
+ const SpiceUsbDeviceInfo *info = (const SpiceUsbDeviceInfo *)device;
+
+ g_return_val_if_fail(info != NULL, FALSE);
+
+ return info->libdev;
+#endif
+#endif
+ return NULL;
+}
+
+static gboolean spice_usb_device_manager_get_libdev_vid_pid(
+ libusb_device *libdev, int *vid, int *pid)
+{
+ struct libusb_device_descriptor desc;
+
+ g_return_val_if_fail(libdev != NULL, FALSE);
+ g_return_val_if_fail(vid != NULL, FALSE);
+ g_return_val_if_fail(pid != NULL, FALSE);
+
+ *vid = *pid = 0;
+
+ if (!spice_usb_device_manager_get_device_descriptor(libdev, &desc)) {
+ return FALSE;
+ }
+ *vid = desc.idVendor;
+ *pid = desc.idProduct;
+
+ return TRUE;
+}
+
+/* ------------------------------------------------------------------ */
+/* callbacks */
+
+static void channel_new(SpiceSession *session, SpiceChannel *channel,
+ gpointer user_data)
+{
+ SpiceUsbDeviceManager *self = user_data;
+
+ if (!SPICE_IS_USBREDIR_CHANNEL(channel))
+ return;
+
+ spice_usbredir_channel_set_context(SPICE_USBREDIR_CHANNEL(channel),
+ self->priv->context);
+ spice_channel_connect(channel);
+ g_ptr_array_add(self->priv->channels, channel);
+
+ spice_usb_device_manager_check_redir_on_connect(self, channel);
+
+ /*
+ * add a reference to ourself, to make sure the libusb context is
+ * alive as long as the channel is.
+ * TODO: moving to gusb could help here too.
+ */
+ g_object_ref(self);
+ g_object_weak_ref(G_OBJECT(channel), (GWeakNotify)g_object_unref, self);
+}
+
+static void channel_destroy(SpiceSession *session, SpiceChannel *channel,
+ gpointer user_data)
+{
+ SpiceUsbDeviceManager *self = user_data;
+
+ if (!SPICE_IS_USBREDIR_CHANNEL(channel))
+ return;
+
+ g_ptr_array_remove(self->priv->channels, channel);
+}
+
+static void spice_usb_device_manager_auto_connect_cb(GObject *gobject,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(gobject);
+ SpiceUsbDevice *device = user_data;
+ GError *err = NULL;
+
+ spice_usb_device_manager_connect_device_finish(self, res, &err);
+ if (err) {
+ gchar *desc = spice_usb_device_get_description(device, NULL);
+ g_prefix_error(&err, "Could not auto-redirect %s: ", desc);
+ g_free(desc);
+
+ SPICE_DEBUG("%s", err->message);
+ g_signal_emit(self, signals[AUTO_CONNECT_FAILED], 0, device, err);
+ g_error_free(err);
+ }
+ spice_usb_device_unref(device);
+}
+
+static gboolean
+spice_usb_device_manager_device_match(SpiceUsbDeviceManager *self, SpiceUsbDevice *device,
+ const int bus, const int address)
+{
+ if (self->priv->use_usbclerk) {
+ return (spice_usb_device_get_vid(device) == bus &&
+ spice_usb_device_get_pid(device) == address);
+ } else {
+ return (spice_usb_device_get_busnum(device) == bus &&
+ spice_usb_device_get_devaddr(device) == address);
+ }
+}
+
+#ifdef USE_GUDEV
+static gboolean
+spice_usb_device_manager_libdev_match(SpiceUsbDeviceManager *self, libusb_device *libdev,
+ const int bus, const int address)
+{
+ if (self->priv->use_usbclerk) {
+ /* WinUSB -- match functions for Windows -- match by vid:pid */
+ int vid, pid;
+
+ if (!spice_usb_device_manager_get_libdev_vid_pid(libdev, &vid, &pid)) {
+ return FALSE;
+ }
+ return (bus == vid && address == pid);
+ } else {
+ /* match functions for Linux/UsbDk -- match by bus.addr */
+ return (libusb_get_bus_number(libdev) == bus &&
+ libusb_get_device_address(libdev) == address);
+ }
+}
+#endif
+
+static SpiceUsbDevice*
+spice_usb_device_manager_find_device(SpiceUsbDeviceManager *self,
+ const int bus, const int address)
+{
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+ SpiceUsbDevice *curr, *device = NULL;
+ guint i;
+
+ for (i = 0; i < priv->devices->len; i++) {
+ curr = g_ptr_array_index(priv->devices, i);
+ if (spice_usb_device_manager_device_match(self, curr, bus, address)) {
+ device = curr;
+ break;
+ }
+ }
+ return device;
+}
+
+static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager *self,
+ libusb_device *libdev)
+{
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+ struct libusb_device_descriptor desc;
+ SpiceUsbDevice *device;
+
+ if (!spice_usb_device_manager_get_device_descriptor(libdev, &desc))
+ return;
+
+ /* Skip hubs */
+ if (desc.bDeviceClass == LIBUSB_CLASS_HUB)
+ return;
+
+ device = (SpiceUsbDevice*)spice_usb_device_new(libdev);
+ if (!device)
+ return;
+
+ g_ptr_array_add(priv->devices, device);
+
+ if (priv->auto_connect) {
+ gboolean can_redirect, auto_ok;
+
+ can_redirect = spice_usb_device_manager_can_redirect_device(
+ self, device, NULL);
+
+ auto_ok = usbredirhost_check_device_filter(
+ priv->auto_conn_filter_rules,
+ priv->auto_conn_filter_rules_count,
+ libdev, 0) == 0;
+
+ if (can_redirect && auto_ok)
+ spice_usb_device_manager_connect_device_async(self,
+ device, NULL,
+ spice_usb_device_manager_auto_connect_cb,
+ spice_usb_device_ref(device));
+ }
+
+ SPICE_DEBUG("device added %04x:%04x (%p)",
+ spice_usb_device_get_vid(device),
+ spice_usb_device_get_pid(device),
+ device);
+ g_signal_emit(self, signals[DEVICE_ADDED], 0, device);
+}
+
+static void spice_usb_device_manager_remove_dev(SpiceUsbDeviceManager *self,
+ guint bus, guint address)
+{
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+ SpiceUsbDevice *device;
+
+ device = spice_usb_device_manager_find_device(self, bus, address);
+ if (!device) {
+ g_warning("Could not find USB device to remove " DEV_ID_FMT,
+ bus, address);
+ return;
+ }
+
+#ifdef G_OS_WIN32
+ if (priv->use_usbclerk) {
+ const guint8 state = spice_usb_device_get_state(device);
+ if ((state == SPICE_USB_DEVICE_STATE_INSTALLING) ||
+ (state == SPICE_USB_DEVICE_STATE_UNINSTALLING)) {
+ SPICE_DEBUG("skipping " DEV_ID_FMT ". It is un/installing its driver",
+ bus, address);
+ return;
+ }
+ }
+#endif
+
+ spice_usb_device_manager_disconnect_device(self, device);
+
+ SPICE_DEBUG("device removed %04x:%04x (%p)",
+ spice_usb_device_get_vid(device),
+ spice_usb_device_get_pid(device),
+ device);
+ spice_usb_device_ref(device);
+ g_ptr_array_remove(priv->devices, device);
+ g_signal_emit(self, signals[DEVICE_REMOVED], 0, device);
+ spice_usb_device_unref(device);
+}
+
+#ifdef USE_GUDEV
+static void spice_usb_device_manager_add_udev(SpiceUsbDeviceManager *self,
+ GUdevDevice *udev)
+{
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+ libusb_device *libdev = NULL, **dev_list = NULL;
+ SpiceUsbDevice *device;
+ const gchar *devtype;
+ int i, bus, address;
+
+ devtype = g_udev_device_get_property(udev, "DEVTYPE");
+ /* Check if this is a usb device (and not an interface) */
+ if (!devtype || strcmp(devtype, "usb_device"))
+ return;
+
+ if (!spice_usb_device_manager_get_udev_bus_n_address(self, udev, &bus, &address)) {
+ g_warning("USB device without bus number or device address");
+ return;
+ }
+
+ device = spice_usb_device_manager_find_device(self, bus, address);
+ if (device) {
+ SPICE_DEBUG("USB device 0x%04x:0x%04x at %d.%d already exists, ignored",
+ spice_usb_device_get_vid(device),
+ spice_usb_device_get_pid(device),
+ spice_usb_device_get_busnum(device),
+ spice_usb_device_get_devaddr(device));
+ return;
+ }
+
+ if (priv->coldplug_list)
+ dev_list = priv->coldplug_list;
+ else
+ libusb_get_device_list(priv->context, &dev_list);
+
+ for (i = 0; dev_list && dev_list[i]; i++) {
+ if (spice_usb_device_manager_libdev_match(self, dev_list[i], bus, address)) {
+ libdev = dev_list[i];
+ break;
+ }
+ }
+
+ if (libdev)
+ spice_usb_device_manager_add_dev(self, libdev);
+ else
+ g_warning("Could not find USB device to add " DEV_ID_FMT,
+ (guint) bus, (guint) address);
+
+ if (!priv->coldplug_list)
+ libusb_free_device_list(dev_list, 1);
+}
+
+static void spice_usb_device_manager_remove_udev(SpiceUsbDeviceManager *self,
+ GUdevDevice *udev)
+{
+ int bus, address;
+
+ if (!spice_usb_device_manager_get_udev_bus_n_address(self, udev, &bus, &address))
+ return;
+
+ spice_usb_device_manager_remove_dev(self, bus, address);
+}
+
+static void spice_usb_device_manager_uevent_cb(GUdevClient *client,
+ const gchar *action,
+ GUdevDevice *udevice,
+ gpointer user_data)
+{
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(user_data);
+
+ if (g_str_equal(action, "add"))
+ spice_usb_device_manager_add_udev(self, udevice);
+ else if (g_str_equal (action, "remove"))
+ spice_usb_device_manager_remove_udev(self, udevice);
+}
+#else
+struct hotplug_idle_cb_args {
+ SpiceUsbDeviceManager *self;
+ libusb_device *device;
+ libusb_hotplug_event event;
+};
+
+static gboolean spice_usb_device_manager_hotplug_idle_cb(gpointer user_data)
+{
+ struct hotplug_idle_cb_args *args = user_data;
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(args->self);
+
+ switch (args->event) {
+ case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED:
+ spice_usb_device_manager_add_dev(self, args->device);
+ break;
+ case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT:
+ spice_usb_device_manager_remove_dev(self,
+ libusb_get_bus_number(args->device),
+ libusb_get_device_address(args->device));
+ break;
+ }
+ libusb_unref_device(args->device);
+ g_object_unref(self);
+ g_free(args);
+ return FALSE;
+}
+
+/* Can be called from both the main-thread as well as the event_thread */
+static int spice_usb_device_manager_hotplug_cb(libusb_context *ctx,
+ libusb_device *device,
+ libusb_hotplug_event event,
+ void *user_data)
+{
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(user_data);
+ struct hotplug_idle_cb_args *args = g_malloc0(sizeof(*args));
+
+ args->self = g_object_ref(self);
+ args->device = libusb_ref_device(device);
+ args->event = event;
+ g_idle_add(spice_usb_device_manager_hotplug_idle_cb, args);
+ return 0;
+}
+#endif
+
+static void spice_usb_device_manager_channel_connect_cb(
+ GObject *gobject, GAsyncResult *channel_res, gpointer user_data)
+{
+ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(gobject);
+ GTask *task = G_TASK(user_data);
+ GError *err = NULL;
+
+ spice_usbredir_channel_connect_device_finish(channel, channel_res, &err);
+ if (err)
+ g_task_return_error(task, err);
+ else
+ g_task_return_boolean(task, TRUE);
+
+ g_object_unref(task);
+}
+
+#ifdef G_OS_WIN32
+
+typedef struct _UsbInstallCbInfo {
+ SpiceUsbDeviceManager *manager;
+ SpiceUsbDevice *device;
+ SpiceWinUsbDriver *installer;
+ GCancellable *cancellable;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+} UsbInstallCbInfo;
+
+/**
+ * spice_usb_device_manager_drv_install_cb:
+ * @gobject: #SpiceWinUsbDriver in charge of installing the driver
+ * @res: #GAsyncResult of async win usb driver installation
+ * @user_data: #SpiceUsbDeviceManager requested the installation
+ *
+ * Called when an Windows libusb driver installation completed.
+ *
+ * If the driver installation was successful, continue with USB
+ * device redirection
+ *
+ * Always call _spice_usb_device_manager_connect_device_async.
+ * When installation fails, libusb_open fails too, but cleanup would be better.
+ */
+static void spice_usb_device_manager_drv_install_cb(GObject *gobject,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceUsbDeviceManager *self;
+ SpiceWinUsbDriver *installer;
+ GError *err = NULL;
+ SpiceUsbDevice *device;
+ UsbInstallCbInfo *cbinfo;
+ GCancellable *cancellable;
+ gpointer data;
+
+ g_return_if_fail(user_data != NULL);
+
+ cbinfo = user_data;
+ self = cbinfo->manager;
+ device = cbinfo->device;
+ installer = cbinfo->installer;
+ cancellable = cbinfo->cancellable;
+ data = cbinfo->user_data;
+
+ g_free(cbinfo);
+
+ g_return_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self));
+ g_return_if_fail(self->priv->use_usbclerk);
+ g_return_if_fail(SPICE_IS_WIN_USB_DRIVER(installer));
+ g_return_if_fail(device!= NULL);
+
+ SPICE_DEBUG("Win USB driver install finished");
+
+ if (!spice_win_usb_driver_install_finish(installer, res, &err)) {
+ g_warning("win usb driver install failed -- %s", err->message);
+ g_error_free(err);
+ }
+
+ spice_usb_device_set_state(device, SPICE_USB_DEVICE_STATE_INSTALLED);
+
+ /* device is already ref'ed */
+ _spice_usb_device_manager_connect_device_async(self,
+ device,
+ cancellable,
+ _connect_device_async_cb,
+ data);
+
+ spice_usb_device_unref(device);
+}
+
+static void spice_usb_device_manager_drv_uninstall_cb(GObject *gobject,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *err = NULL;
+
+ UsbInstallCbInfo *cbinfo = user_data;
+ SpiceUsbDeviceManager *self = cbinfo->manager;
+ SpiceUsbDevice *device = cbinfo->device;
+ SpiceWinUsbDriver *installer = cbinfo->installer;
+
+ g_free(cbinfo);
+
+ SPICE_DEBUG("Win USB driver uninstall finished");
+ g_return_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self));
+ g_return_if_fail(self->priv->use_usbclerk);
+
+ if (!spice_win_usb_driver_uninstall_finish(installer, res, &err)) {
+ g_warning("win usb driver uninstall failed -- %s", err->message);
+ g_clear_error(&err);
+ }
+
+ spice_usb_device_set_state(device, SPICE_USB_DEVICE_STATE_NONE);
+ spice_usb_device_unref(device);
+}
+
+#endif
+
+/* ------------------------------------------------------------------ */
+/* private api */
+
+static gpointer spice_usb_device_manager_usb_ev_thread(gpointer user_data)
+{
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(user_data);
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+ int rc;
+
+ while (g_atomic_int_get(&priv->event_thread_run)) {
+ rc = libusb_handle_events(priv->context);
+ if (rc && rc != LIBUSB_ERROR_INTERRUPTED) {
+ const char *desc = spice_usbutil_libusb_strerror(rc);
+ g_warning("Error handling USB events: %s [%i]", desc, rc);
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+gboolean spice_usb_device_manager_start_event_listening(
+ SpiceUsbDeviceManager *self, GError **err)
+{
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ priv->event_listeners++;
+ if (priv->event_listeners > 1)
+ return TRUE;
+
+ /* We don't join the thread when we stop event listening, as the
+ libusb_handle_events call in the thread won't exit until the
+ libusb_close call for the device is made from usbredirhost_close. */
+ if (priv->event_thread) {
+ g_thread_join(priv->event_thread);
+ priv->event_thread = NULL;
+ }
+ g_atomic_int_set(&priv->event_thread_run, TRUE);
+ priv->event_thread = g_thread_new("usb_ev_thread",
+ spice_usb_device_manager_usb_ev_thread,
+ self);
+ return priv->event_thread != NULL;
+}
+
+void spice_usb_device_manager_stop_event_listening(
+ SpiceUsbDeviceManager *self)
+{
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+
+ g_return_if_fail(priv->event_listeners > 0);
+
+ priv->event_listeners--;
+ if (priv->event_listeners == 0)
+ g_atomic_int_set(&priv->event_thread_run, FALSE);
+}
+
+static void spice_usb_device_manager_check_redir_on_connect(
+ SpiceUsbDeviceManager *self, SpiceChannel *channel)
+{
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+ GTask *task;
+ SpiceUsbDevice *device;
+ libusb_device *libdev;
+ guint i;
+
+ if (priv->redirect_on_connect == NULL)
+ return;
+
+ for (i = 0; i < priv->devices->len; i++) {
+ device = g_ptr_array_index(priv->devices, i);
+
+ if (spice_usb_device_manager_is_device_connected(self, device))
+ continue;
+
+ libdev = spice_usb_device_manager_device_to_libdev(self, device);
+#ifdef G_OS_WIN32
+ if (libdev == NULL)
+ continue;
+#endif
+ if (usbredirhost_check_device_filter(
+ priv->redirect_on_connect_rules,
+ priv->redirect_on_connect_rules_count,
+ libdev, 0) == 0) {
+ /* Note: re-uses spice_usb_device_manager_connect_device_async's
+ completion handling code! */
+ task = g_task_new(self,
+ NULL,
+ spice_usb_device_manager_auto_connect_cb,
+ spice_usb_device_ref(device));
+
+ spice_usbredir_channel_connect_device_async(
+ SPICE_USBREDIR_CHANNEL(channel),
+ libdev, device, NULL,
+ spice_usb_device_manager_channel_connect_cb,
+ task);
+ libusb_unref_device(libdev);
+ return; /* We've taken the channel! */
+ }
+
+ libusb_unref_device(libdev);
+ }
+}
+
+void spice_usb_device_manager_device_error(
+ SpiceUsbDeviceManager *self, SpiceUsbDevice *device, GError *err)
+{
+ g_return_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self));
+ g_return_if_fail(device != NULL);
+
+ g_signal_emit(self, signals[DEVICE_ERROR], 0, device, err);
+}
+#endif
+
+static SpiceUsbredirChannel *spice_usb_device_manager_get_channel_for_dev(
+ SpiceUsbDeviceManager *manager, SpiceUsbDevice *device)
+{
+#ifdef USE_USBREDIR
+ SpiceUsbDeviceManagerPrivate *priv = manager->priv;
+ guint i;
+
+ for (i = 0; i < priv->channels->len; i++) {
+ SpiceUsbredirChannel *channel = g_ptr_array_index(priv->channels, i);
+ spice_usbredir_channel_lock(channel);
+ libusb_device *libdev = spice_usbredir_channel_get_device(channel);
+ if (spice_usb_manager_device_equal_libdev(manager, device, libdev)) {
+ spice_usbredir_channel_unlock(channel);
+ return channel;
+ }
+ spice_usbredir_channel_unlock(channel);
+ }
+#endif
+ return NULL;
+}
+
+/* ------------------------------------------------------------------ */
+/* public api */
+
+/**
+ * spice_usb_device_manager_get_devices_with_filter:
+ * @manager: the #SpiceUsbDeviceManager manager
+ * @filter: (allow-none): filter string for selecting which devices to return,
+ * see #SpiceUsbDeviceManager:auto-connect-filter for the filter
+ * string format
+ *
+ * Finds devices associated with the @manager complying with the @filter
+ *
+ * Returns: (element-type SpiceUsbDevice) (transfer full): a
+ * %GPtrArray array of %SpiceUsbDevice
+ *
+ * Since: 0.20
+ */
+GPtrArray* spice_usb_device_manager_get_devices_with_filter(
+ SpiceUsbDeviceManager *self, const gchar *filter)
+{
+ GPtrArray *devices_copy = NULL;
+
+ g_return_val_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self), NULL);
+
+#ifdef USE_USBREDIR
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+ struct usbredirfilter_rule *rules = NULL;
+ int r, count = 0;
+ guint i;
+
+ if (filter) {
+ r = usbredirfilter_string_to_rules(filter, ",", "|", &rules, &count);
+ if (r) {
+ if (r == -ENOMEM)
+ g_error("Failed to allocate memory for filter");
+ g_warning("Error parsing filter, ignoring");
+ rules = NULL;
+ count = 0;
+ }
+ }
+
+ devices_copy = g_ptr_array_new_with_free_func((GDestroyNotify)
+ spice_usb_device_unref);
+ for (i = 0; i < priv->devices->len; i++) {
+ SpiceUsbDevice *device = g_ptr_array_index(priv->devices, i);
+
+ if (rules) {
+ libusb_device *libdev =
+ spice_usb_device_manager_device_to_libdev(self, device);
+#ifdef G_OS_WIN32
+ if (libdev == NULL)
+ continue;
+#endif
+ if (usbredirhost_check_device_filter(rules, count, libdev, 0) != 0)
+ continue;
+ }
+ g_ptr_array_add(devices_copy, spice_usb_device_ref(device));
+ }
+
+ free(rules);
+#endif
+
+ return devices_copy;
+}
+
+/**
+ * spice_usb_device_manager_get_devices:
+ * @manager: the #SpiceUsbDeviceManager manager
+ *
+ * Finds devices associated with the @manager
+ *
+ * Returns: (element-type SpiceUsbDevice) (transfer full): a %GPtrArray array of %SpiceUsbDevice
+ */
+GPtrArray* spice_usb_device_manager_get_devices(SpiceUsbDeviceManager *self)
+{
+ return spice_usb_device_manager_get_devices_with_filter(self, NULL);
+}
+
+/**
+ * spice_usb_device_manager_is_device_connected:
+ * @manager: the #SpiceUsbDeviceManager manager
+ * @device: a #SpiceUsbDevice
+ *
+ * Finds if the @device is connected.
+ *
+ * Returns: %TRUE if @device has an associated USB redirection channel
+ */
+gboolean spice_usb_device_manager_is_device_connected(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device)
+{
+ g_return_val_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self), FALSE);
+ g_return_val_if_fail(device != NULL, FALSE);
+
+ return !!spice_usb_device_manager_get_channel_for_dev(self, device);
+}
+
+#if defined(USE_USBREDIR) && defined(G_OS_WIN32)
+
+static void
+_spice_usb_device_manager_install_driver_async(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SpiceWinUsbDriver *installer;
+ UsbInstallCbInfo *cbinfo;
+
+ g_return_if_fail(self->priv->installer);
+
+ spice_usb_device_set_state(device, SPICE_USB_DEVICE_STATE_INSTALLING);
+
+ installer = self->priv->installer;
+ cbinfo = g_new0(UsbInstallCbInfo, 1);
+ cbinfo->manager = self;
+ cbinfo->device = spice_usb_device_ref(device);
+ cbinfo->installer = installer;
+ cbinfo->cancellable = cancellable;
+ cbinfo->callback = callback;
+ cbinfo->user_data = user_data;
+
+ spice_win_usb_driver_install_async(installer, device, cancellable,
+ spice_usb_device_manager_drv_install_cb,
+ cbinfo);
+}
+
+static void
+_spice_usb_device_manager_uninstall_driver_async(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device)
+{
+ SpiceWinUsbDriver *installer;
+ UsbInstallCbInfo *cbinfo;
+ guint8 state;
+
+ g_warn_if_fail(device != NULL);
+ g_return_if_fail(self->priv->installer);
+
+ state = spice_usb_device_get_state(device);
+ if ((state != SPICE_USB_DEVICE_STATE_INSTALLED) &&
+ (state != SPICE_USB_DEVICE_STATE_CONNECTED)) {
+ return;
+ }
+
+ spice_usb_device_set_state(device, SPICE_USB_DEVICE_STATE_UNINSTALLING);
+
+ installer = self->priv->installer;
+ cbinfo = g_new0(UsbInstallCbInfo, 1);
+ cbinfo->manager = self;
+ cbinfo->device = spice_usb_device_ref(device);
+ cbinfo->installer = installer;
+
+ spice_win_usb_driver_uninstall_async(installer, device, NULL,
+ spice_usb_device_manager_drv_uninstall_cb,
+ cbinfo);
+}
+
+#endif
+
+#ifdef USE_USBREDIR
+
+static gboolean
+_spice_usb_device_manager_connect_device_finish(SpiceUsbDeviceManager *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ GTask *task = G_TASK(res);
+
+ g_return_val_if_fail(g_task_is_valid(task, G_OBJECT(self)), FALSE);
+
+ return g_task_propagate_boolean(task, error);
+}
+
+static void
+_spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+
+ g_return_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self));
+ g_return_if_fail(device != NULL);
+
+ SPICE_DEBUG("connecting device %p", device);
+
+ task = g_task_new(self, cancellable, callback, user_data);
+
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+ libusb_device *libdev;
+ guint i;
+
+ if (spice_usb_device_manager_is_device_connected(self, device)) {
+ g_task_return_new_error(task,
+ SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Cannot connect an already connected usb device");
+ goto done;
+ }
+
+ for (i = 0; i < priv->channels->len; i++) {
+ SpiceUsbredirChannel *channel = g_ptr_array_index(priv->channels, i);
+
+ if (spice_usbredir_channel_get_device(channel))
+ continue; /* Skip already used channels */
+
+ libdev = spice_usb_device_manager_device_to_libdev(self, device);
+#ifdef G_OS_WIN32
+ if (libdev == NULL) {
+ /* Most likely, the device was plugged out at driver installation
+ * time, and its remove-device event was ignored.
+ * So remove the device now
+ */
+ SPICE_DEBUG("libdev does not exist for %p -- removing", device);
+ spice_usb_device_ref(device);
+ g_ptr_array_remove(priv->devices, device);
+ g_signal_emit(self, signals[DEVICE_REMOVED], 0, device);
+ spice_usb_device_unref(device);
+ g_task_return_new_error(task,
+ SPICE_CLIENT_ERROR,
+ SPICE_CLIENT_ERROR_FAILED,
+ _("Device was not found"));
+ goto done;
+ }
+#endif
+ spice_usbredir_channel_connect_device_async(channel,
+ libdev,
+ device,
+ cancellable,
+ spice_usb_device_manager_channel_connect_cb,
+ task);
+ libusb_unref_device(libdev);
+ return;
+ }
+
+ g_task_return_new_error(task,
+ SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("No free USB channel"));
+done:
+ g_object_unref(task);
+}
+
+#endif
+
+/**
+ * spice_usb_device_manager_connect_device_async:
+ * @self: a #SpiceUsbDeviceManager.
+ * @device: a #SpiceUsbDevice to redirect
+ * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: the data to pass to callback function
+ *
+ * Asynchronously connects the @device. When completed, @callback will be called.
+ * Then it is possible to call spice_usb_device_manager_connect_device_finish()
+ * to get the result of the operation.
+ */
+void spice_usb_device_manager_connect_device_async(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self));
+
+#ifdef USE_USBREDIR
+
+ GTask *task =
+ g_task_new(G_OBJECT(self), cancellable, callback, user_data);
+
+ _set_redirecting(self, TRUE);
+
+#ifdef G_OS_WIN32
+ if (self->priv->use_usbclerk) {
+ _spice_usb_device_manager_install_driver_async(self, device, cancellable,
+ callback, task);
+ return;
+ }
+#endif
+
+ _spice_usb_device_manager_connect_device_async(self,
+ device,
+ cancellable,
+ _connect_device_async_cb,
+ task);
+
+#endif
+}
+
+/**
+ * spice_usb_device_manager_connect_device_finish:
+ * @self: a #SpiceUsbDeviceManager.
+ * @res: a #GAsyncResult
+ * @err: (allow-none): a return location for a #GError, or %NULL.
+ *
+ * Finishes an async operation. See spice_usb_device_manager_connect_device_async().
+ *
+ * Returns: %TRUE if connection is successful
+ */
+gboolean spice_usb_device_manager_connect_device_finish(
+ SpiceUsbDeviceManager *self, GAsyncResult *res, GError **err)
+{
+ GTask *task = G_TASK(res);
+
+ g_return_val_if_fail(g_task_is_valid(task, self),
+ FALSE);
+
+ return g_task_propagate_boolean(task, err);
+}
+
+/**
+ * spice_usb_device_manager_disconnect_device_finish:
+ * @self: a #SpiceUsbDeviceManager.
+ * @res: a #GAsyncResult
+ * @err: (allow-none): a return location for a #GError, or %NULL.
+ *
+ * Finishes an async operation. See spice_usb_device_manager_disconnect_device_async().
+ *
+ * Returns: %TRUE if disconnection is successful
+ */
+gboolean spice_usb_device_manager_disconnect_device_finish(
+ SpiceUsbDeviceManager *self, GAsyncResult *res, GError **err)
+{
+ GTask *task = G_TASK(res);
+
+ g_return_val_if_fail(g_task_is_valid(task, G_OBJECT(self)), FALSE);
+
+ return g_task_propagate_boolean(task, err);
+}
+
+#ifdef USE_USBREDIR
+static
+void _connect_device_async_cb(GObject *gobject,
+ GAsyncResult *channel_res,
+ gpointer user_data)
+{
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(gobject);
+ GTask *task = user_data;
+ GError *error = NULL;
+
+ _set_redirecting(self, FALSE);
+ if (_spice_usb_device_manager_connect_device_finish(self, channel_res, &error))
+ g_task_return_boolean(task, TRUE);
+ else
+ g_task_return_error(task, error);
+ g_object_unref(task);
+}
+#endif
+
+/**
+ * spice_usb_device_manager_disconnect_device:
+ * @manager: the #SpiceUsbDeviceManager manager
+ * @device: a #SpiceUsbDevice to disconnect
+ *
+ * Disconnects the @device.
+ */
+void spice_usb_device_manager_disconnect_device(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device)
+{
+ g_return_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self));
+ g_return_if_fail(device != NULL);
+
+ SPICE_DEBUG("disconnecting device %p", device);
+
+#ifdef USE_USBREDIR
+ SpiceUsbredirChannel *channel;
+
+ channel = spice_usb_device_manager_get_channel_for_dev(self, device);
+ if (channel)
+ spice_usbredir_channel_disconnect_device(channel);
+
+#ifdef G_OS_WIN32
+ if(self->priv->use_usbclerk)
+ _spice_usb_device_manager_uninstall_driver_async(self, device);
+#endif
+
+#endif
+}
+
+typedef struct _disconnect_cb_data
+{
+ SpiceUsbDeviceManager *self;
+ SpiceUsbDevice *device;
+} disconnect_cb_data;
+
+#ifdef USE_USBREDIR
+static
+void _disconnect_device_async_cb(GObject *gobject,
+ GAsyncResult *channel_res,
+ gpointer user_data)
+{
+ SpiceUsbredirChannel *channel = SPICE_USBREDIR_CHANNEL(gobject);
+ GTask *task = user_data;
+ GError *err = NULL;
+ disconnect_cb_data *data = g_task_get_task_data(task);
+ SpiceUsbDeviceManager *self = SPICE_USB_DEVICE_MANAGER(data->self);
+
+#ifdef G_OS_WIN32
+ if (self->priv->use_usbclerk) {
+ _spice_usb_device_manager_uninstall_driver_async(self, data->device);
+ }
+#endif
+
+ _set_redirecting(self, FALSE);
+
+ spice_usbredir_channel_disconnect_device_finish(channel, channel_res, &err);
+ if (err)
+ g_task_return_error(task, err);
+ else
+ g_task_return_boolean(task, TRUE);
+
+ g_object_unref(task);
+}
+#endif
+
+void spice_usb_device_manager_disconnect_device_async(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+#ifdef USE_USBREDIR
+ GTask *nested;
+ g_return_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self));
+
+ g_return_if_fail(device != NULL);
+ g_return_if_fail(spice_usb_device_manager_is_device_connected(self, device));
+
+ SPICE_DEBUG("disconnecting device %p", device);
+
+ SpiceUsbredirChannel *channel;
+
+ _set_redirecting(self, TRUE);
+
+ channel = spice_usb_device_manager_get_channel_for_dev(self, device);
+ nested = g_task_new(G_OBJECT(self), cancellable, callback, user_data);
+ disconnect_cb_data *data = g_new(disconnect_cb_data, 1);
+ data->self = self;
+ data->device = device;
+ g_task_set_task_data(nested, data, g_free);
+
+ spice_usbredir_channel_disconnect_device_async(channel, cancellable,
+ _disconnect_device_async_cb,
+ nested);
+#endif
+}
+
+/**
+ * spice_usb_device_manager_can_redirect_device:
+ * @self: the #SpiceUsbDeviceManager manager
+ * @device: a #SpiceUsbDevice to disconnect
+ * @err: (allow-none): a return location for a #GError, or %NULL.
+ *
+ * Checks whether it is possible to redirect the @device.
+ *
+ * Returns: %TRUE if @device can be redirected
+ */
+gboolean
+spice_usb_device_manager_can_redirect_device(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device,
+ GError **err)
+{
+#ifdef USE_USBREDIR
+ const struct usbredirfilter_rule *guest_filter_rules = NULL;
+ SpiceUsbDeviceManagerPrivate *priv = self->priv;
+ int i, guest_filter_rules_count;
+
+ g_return_val_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self), FALSE);
+ g_return_val_if_fail(device != NULL, FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ if (!spice_session_get_usbredir_enabled(priv->session)) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("USB redirection is disabled"));
+ return FALSE;
+ }
+
+ if (!priv->channels->len) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("The connected VM is not configured for USB redirection"));
+ return FALSE;
+ }
+
+ /* Skip the other checks for already connected devices */
+ if (spice_usb_device_manager_is_device_connected(self, device))
+ return TRUE;
+
+ /* We assume all channels have the same filter, so we just take the
+ filter from the first channel */
+ spice_usbredir_channel_get_guest_filter(
+ g_ptr_array_index(priv->channels, 0),
+ &guest_filter_rules, &guest_filter_rules_count);
+
+ if (guest_filter_rules) {
+ gboolean filter_ok;
+ libusb_device *libdev;
+
+ libdev = spice_usb_device_manager_device_to_libdev(self, device);
+#ifdef G_OS_WIN32
+ if (libdev == NULL) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("Some USB devices were not found"));
+ return FALSE;
+ }
+#endif
+ filter_ok = (usbredirhost_check_device_filter(
+ guest_filter_rules, guest_filter_rules_count,
+ libdev, 0) == 0);
+ libusb_unref_device(libdev);
+ if (!filter_ok) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("Some USB devices are blocked by host policy"));
+ return FALSE;
+ }
+ }
+
+ /* Check if there are free channels */
+ for (i = 0; i < priv->channels->len; i++) {
+ SpiceUsbredirChannel *channel = g_ptr_array_index(priv->channels, i);
+ spice_usbredir_channel_lock(channel);
+
+ if (!spice_usbredir_channel_get_device(channel)){
+ spice_usbredir_channel_unlock(channel);
+ break;
+ }
+ spice_usbredir_channel_unlock(channel);
+ }
+ if (i == priv->channels->len) {
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("There are no free USB channels"));
+ return FALSE;
+ }
+
+ return TRUE;
+#else
+ g_set_error_literal(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ _("USB redirection support not compiled in"));
+ return FALSE;
+#endif
+}
+
+/**
+ * spice_usb_device_get_description:
+ * @device: #SpiceUsbDevice to get the description of
+ * @format: (allow-none): an optional printf() format string with
+ * positional parameters
+ *
+ * Get a string describing the device which is suitable as a description of
+ * the device for the end user. The returned string should be freed with
+ * g_free() when no longer needed.
+ *
+ * The @format positional parameters are the following:
+ * - '%%1$s' manufacturer
+ * - '%%2$s' product
+ * - '%%3$s' descriptor (a [vendor_id:product_id] string)
+ * - '%%4$d' bus
+ * - '%%5$d' address
+ *
+ * (the default format string is "%%s %%s %%s at %%d-%%d")
+ *
+ * Returns: a newly-allocated string holding the description, or %NULL if failed
+ */
+gchar *spice_usb_device_get_description(SpiceUsbDevice *device, const gchar *format)
+{
+#ifdef USE_USBREDIR
+ guint16 bus, address, vid, pid;
+ gchar *description, *descriptor, *manufacturer = NULL, *product = NULL;
+
+ g_return_val_if_fail(device != NULL, NULL);
+
+ bus = spice_usb_device_get_busnum(device);
+ address = spice_usb_device_get_devaddr(device);
+ vid = spice_usb_device_get_vid(device);
+ pid = spice_usb_device_get_pid(device);
+
+ if ((vid > 0) && (pid > 0)) {
+ descriptor = g_strdup_printf("[%04x:%04x]", vid, pid);
+ } else {
+ descriptor = g_strdup("");
+ }
+
+ spice_usb_util_get_device_strings(bus, address, vid, pid,
+ &manufacturer, &product);
+
+ if (!format)
+ format = _("%s %s %s at %d-%d");
+
+ description = g_strdup_printf(format, manufacturer, product, descriptor, bus, address);
+
+ g_free(manufacturer);
+ g_free(descriptor);
+ g_free(product);
+
+ return description;
+#else
+ return NULL;
+#endif
+}
+
+
+
+#ifdef USE_USBREDIR
+static gboolean probe_isochronous_endpoint(libusb_device *libdev)
+{
+ struct libusb_config_descriptor *conf_desc;
+ gboolean isoc_found = FALSE;
+ gint i, j, k;
+
+ g_return_val_if_fail(libdev != NULL, FALSE);
+
+ if (libusb_get_active_config_descriptor(libdev, &conf_desc) != 0) {
+ g_return_val_if_reached(FALSE);
+ }
+
+ for (i = 0; !isoc_found && i < conf_desc->bNumInterfaces; i++) {
+ for (j = 0; !isoc_found && j < conf_desc->interface[i].num_altsetting; j++) {
+ for (k = 0; !isoc_found && k < conf_desc->interface[i].altsetting[j].bNumEndpoints;k++) {
+ gint attributes = conf_desc->interface[i].altsetting[j].endpoint[k].bmAttributes;
+ gint type = attributes & LIBUSB_TRANSFER_TYPE_MASK;
+ if (type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
+ isoc_found = TRUE;
+ }
+ }
+ }
+
+ libusb_free_config_descriptor(conf_desc);
+ return isoc_found;
+}
+
+/*
+ * SpiceUsbDeviceInfo
+ */
+static SpiceUsbDeviceInfo *spice_usb_device_new(libusb_device *libdev)
+{
+ SpiceUsbDeviceInfo *info;
+ int vid, pid;
+ guint8 bus, addr;
+
+ g_return_val_if_fail(libdev != NULL, NULL);
+
+ bus = libusb_get_bus_number(libdev);
+ addr = libusb_get_device_address(libdev);
+
+ if (!spice_usb_device_manager_get_libdev_vid_pid(libdev, &vid, &pid)) {
+ return NULL;
+ }
+
+ info = g_new0(SpiceUsbDeviceInfo, 1);
+
+ info->busnum = bus;
+ info->devaddr = addr;
+ info->vid = vid;
+ info->pid = pid;
+ info->ref = 1;
+ info->isochronous = probe_isochronous_endpoint(libdev);
+#ifndef G_OS_WIN32
+ info->libdev = libusb_ref_device(libdev);
+#endif
+
+ return info;
+}
+
+guint8 spice_usb_device_get_busnum(const SpiceUsbDevice *device)
+{
+ const SpiceUsbDeviceInfo *info = (const SpiceUsbDeviceInfo *)device;
+
+ g_return_val_if_fail(info != NULL, 0);
+
+ return info->busnum;
+}
+
+guint8 spice_usb_device_get_devaddr(const SpiceUsbDevice *device)
+{
+ const SpiceUsbDeviceInfo *info = (const SpiceUsbDeviceInfo *)device;
+
+ g_return_val_if_fail(info != NULL, 0);
+
+ return info->devaddr;
+}
+
+guint16 spice_usb_device_get_vid(const SpiceUsbDevice *device)
+{
+ const SpiceUsbDeviceInfo *info = (const SpiceUsbDeviceInfo *)device;
+
+ g_return_val_if_fail(info != NULL, 0);
+
+ return info->vid;
+}
+
+guint16 spice_usb_device_get_pid(const SpiceUsbDevice *device)
+{
+ const SpiceUsbDeviceInfo *info = (const SpiceUsbDeviceInfo *)device;
+
+ g_return_val_if_fail(info != NULL, 0);
+
+ return info->pid;
+}
+
+gboolean spice_usb_device_is_isochronous(const SpiceUsbDevice *device)
+{
+ const SpiceUsbDeviceInfo *info = (const SpiceUsbDeviceInfo *)device;
+
+ g_return_val_if_fail(info != NULL, 0);
+
+ return info->isochronous;
+}
+
+#ifdef G_OS_WIN32
+void spice_usb_device_set_state(SpiceUsbDevice *device, guint8 state)
+{
+ SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+ g_return_if_fail(info != NULL);
+
+ info->state = state;
+}
+
+guint8 spice_usb_device_get_state(SpiceUsbDevice *device)
+{
+ SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+ g_return_val_if_fail(info != NULL, 0);
+
+ return info->state;
+}
+
+static
+gboolean _usbdk_hider_prepare(SpiceUsbDeviceManager *manager)
+{
+ SpiceUsbDeviceManagerPrivate *priv = manager->priv;
+
+ g_return_val_if_fail(!priv->use_usbclerk, FALSE);
+
+ if (priv->usbdk_hider_handle == NULL) {
+ priv->usbdk_hider_handle = usbdk_create_hider_handle(priv->usbdk_api);
+ if (priv->usbdk_hider_handle == NULL) {
+ g_warning("Failed to instantiate UsbDk hider interface");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static
+void _usbdk_hider_clear(SpiceUsbDeviceManager *manager)
+{
+ SpiceUsbDeviceManagerPrivate *priv = manager->priv;
+
+ g_return_if_fail(!priv->use_usbclerk);
+
+ if (priv->usbdk_hider_handle != NULL) {
+ usbdk_clear_hide_rules(priv->usbdk_api, priv->usbdk_hider_handle);
+ usbdk_close_hider_handle(priv->usbdk_api, priv->usbdk_hider_handle);
+ priv->usbdk_hider_handle = NULL;
+ }
+}
+
+static
+void _usbdk_hider_update(SpiceUsbDeviceManager *manager)
+{
+ SpiceUsbDeviceManagerPrivate *priv = manager->priv;
+
+ g_return_if_fail(!priv->use_usbclerk);
+
+ if (priv->auto_connect_filter == NULL) {
+ SPICE_DEBUG("No autoredirect rules, no hider setup needed");
+ _usbdk_hider_clear(manager);
+ return;
+ }
+
+ if (!priv->auto_connect) {
+ SPICE_DEBUG("Auto-connect disabled, no hider setup needed");
+ _usbdk_hider_clear(manager);
+ return;
+ }
+
+ if(_usbdk_hider_prepare(manager)) {
+ usbdk_api_set_hide_rules(priv->usbdk_api,
+ priv->usbdk_hider_handle,
+ priv->auto_connect_filter);
+ }
+}
+
+#endif
+
+static SpiceUsbDevice *spice_usb_device_ref(SpiceUsbDevice *device)
+{
+ SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+ g_return_val_if_fail(info != NULL, NULL);
+ g_atomic_int_inc(&info->ref);
+ return device;
+}
+
+static void spice_usb_device_unref(SpiceUsbDevice *device)
+{
+ gboolean ref_count_is_0;
+
+ SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+ g_return_if_fail(info != NULL);
+
+ ref_count_is_0 = g_atomic_int_dec_and_test(&info->ref);
+ if (ref_count_is_0) {
+#ifndef G_OS_WIN32
+ libusb_unref_device(info->libdev);
+#endif
+ g_free(info);
+ }
+}
+
+#ifndef G_OS_WIN32 /* Linux -- directly compare libdev */
+static gboolean
+spice_usb_manager_device_equal_libdev(SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device,
+ libusb_device *libdev)
+{
+ SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+ if ((device == NULL) || (libdev == NULL))
+ return FALSE;
+
+ return info->libdev == libdev;
+}
+#else /* Windows -- compare vid:pid of device and libdev */
+static gboolean
+spice_usb_manager_device_equal_libdev(SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device,
+ libusb_device *libdev)
+{
+ int busnum, devaddr;
+
+ if ((device == NULL) || (libdev == NULL))
+ return FALSE;
+
+ if (manager->priv->use_usbclerk) {
+ busnum = spice_usb_device_get_vid(device);
+ devaddr = spice_usb_device_get_pid(device);
+ } else {
+ busnum = spice_usb_device_get_busnum(device);
+ devaddr = spice_usb_device_get_devaddr(device);
+ }
+
+ return spice_usb_device_manager_libdev_match(manager, libdev,
+ busnum, devaddr);
+}
+#endif
+
+/*
+ * Caller must libusb_unref_device the libusb_device returned by this function.
+ * Returns a libusb_device, or NULL upon failure
+ */
+static libusb_device *
+spice_usb_device_manager_device_to_libdev(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device)
+{
+#ifdef G_OS_WIN32
+ /*
+ * On win32 we need to do this the hard and slow way, by asking libusb to
+ * re-enumerate all devices and then finding a matching device.
+ * We cannot cache the libusb_device like we do under Linux since the
+ * driver swap we do under windows invalidates the cached libdev.
+ */
+
+ libusb_device *d, **devlist;
+ int i;
+
+ g_return_val_if_fail(SPICE_IS_USB_DEVICE_MANAGER(self), NULL);
+ g_return_val_if_fail(device != NULL, NULL);
+ g_return_val_if_fail(self->priv != NULL, NULL);
+ g_return_val_if_fail(self->priv->context != NULL, NULL);
+
+ libusb_get_device_list(self->priv->context, &devlist);
+ if (!devlist)
+ return NULL;
+
+ for (i = 0; (d = devlist[i]) != NULL; i++) {
+ if (spice_usb_manager_device_equal_libdev(self, device, d)) {
+ libusb_ref_device(d);
+ break;
+ }
+ }
+
+ libusb_free_device_list(devlist, 1);
+
+ return d;
+
+#else
+ /* Simply return a ref to the cached libdev */
+ SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+ return libusb_ref_device(info->libdev);
+#endif
+}
+#endif /* USE_USBREDIR */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011, 2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_USB_DEVICE_MANAGER_H__
+#define __SPICE_USB_DEVICE_MANAGER_H__
+
+#if !defined(__SPICE_CLIENT_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client.h> can be included directly"
+#endif
+
+#include "spice-client.h"
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_USB_DEVICE_MANAGER (spice_usb_device_manager_get_type ())
+#define SPICE_USB_DEVICE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_USB_DEVICE_MANAGER, SpiceUsbDeviceManager))
+#define SPICE_USB_DEVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_USB_DEVICE_MANAGER, SpiceUsbDeviceManagerClass))
+#define SPICE_IS_USB_DEVICE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_USB_DEVICE_MANAGER))
+#define SPICE_IS_USB_DEVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_USB_DEVICE_MANAGER))
+#define SPICE_USB_DEVICE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_USB_DEVICE_MANAGER, SpiceUsbDeviceManagerClass))
+
+#define SPICE_TYPE_USB_DEVICE (spice_usb_device_get_type())
+
+typedef struct _SpiceUsbDeviceManager SpiceUsbDeviceManager;
+typedef struct _SpiceUsbDeviceManagerClass SpiceUsbDeviceManagerClass;
+typedef struct _SpiceUsbDeviceManagerPrivate SpiceUsbDeviceManagerPrivate;
+
+/**
+ * SpiceUsbDevice:
+ *
+ * The #SpiceUsbDevice struct is opaque and cannot be accessed directly.
+ */
+typedef struct _SpiceUsbDevice SpiceUsbDevice;
+
+/**
+ * SpiceUsbDeviceManager:
+ *
+ * The #SpiceUsbDeviceManager struct is opaque and should not be accessed directly.
+ */
+struct _SpiceUsbDeviceManager
+{
+ GObject parent;
+
+ /*< private >*/
+ SpiceUsbDeviceManagerPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+/**
+ * SpiceUsbDeviceManagerClass:
+ * @parent_class: Parent class.
+ * @device_added: Signal class handler for the #SpiceUsbDeviceManager::device-added signal.
+ * @device_removed: Signal class handler for the #SpiceUsbDeviceManager::device-removed signal.
+ * @auto_connect_failed: Signal class handler for the #SpiceUsbDeviceManager::auto-connect-failed signal.
+ * @device_error: Signal class handler for the #SpiceUsbDeviceManager::device_error signal.
+ *
+ * Class structure for #SpiceUsbDeviceManager.
+ */
+struct _SpiceUsbDeviceManagerClass
+{
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*device_added) (SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device);
+ void (*device_removed) (SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device);
+ void (*auto_connect_failed) (SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device, GError *error);
+ void (*device_error) (SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device, GError *error);
+ /*< private >*/
+ /*
+ * If adding fields to this struct, remove corresponding
+ * amount of padding to avoid changing overall struct size
+ */
+ gchar _spice_reserved[SPICE_RESERVED_PADDING];
+};
+
+GType spice_usb_device_get_type(void);
+GType spice_usb_device_manager_get_type(void);
+
+gchar *spice_usb_device_get_description(SpiceUsbDevice *device, const gchar *format);
+gconstpointer spice_usb_device_get_libusb_device(const SpiceUsbDevice *device);
+
+SpiceUsbDeviceManager *spice_usb_device_manager_get(SpiceSession *session,
+ GError **err);
+
+GPtrArray *spice_usb_device_manager_get_devices(SpiceUsbDeviceManager *manager);
+GPtrArray* spice_usb_device_manager_get_devices_with_filter(
+ SpiceUsbDeviceManager *manager, const gchar *filter);
+
+gboolean spice_usb_device_manager_is_device_connected(SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device);
+void spice_usb_device_manager_connect_device_async(
+ SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+void spice_usb_device_manager_disconnect_device_async(
+ SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean spice_usb_device_manager_connect_device_finish(
+ SpiceUsbDeviceManager *self, GAsyncResult *res, GError **err);
+
+gboolean spice_usb_device_manager_disconnect_device_finish(
+ SpiceUsbDeviceManager *self, GAsyncResult *res, GError **err);
+
+#ifndef SPICE_DISABLE_DEPRECATED
+SPICE_DEPRECATED
+void spice_usb_device_manager_disconnect_device(SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device);
+#endif
+
+gboolean
+spice_usb_device_manager_can_redirect_device(SpiceUsbDeviceManager *self,
+ SpiceUsbDevice *device,
+ GError **err);
+
+gboolean spice_usb_device_manager_is_redirecting(SpiceUsbDeviceManager *self);
+
+G_END_DECLS
+
+#endif /* __SPICE_USB_DEVICE_MANAGER_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+#include "spice-client.h"
+#include "spice-marshal.h"
+#include "usb-device-widget.h"
+
+/**
+ * SECTION:usb-device-widget
+ * @short_description: USB device selection widget
+ * @title: Spice USB device selection widget
+ * @section_id:
+ * @see_also:
+ * @stability: Stable
+ * @include: spice-client-gtk.h
+ *
+ * #SpiceUsbDeviceWidget is a gtk widget which apps can use to easily
+ * add an UI to select USB devices to redirect (or unredirect).
+ */
+
+struct _SpiceUsbDeviceWidget
+{
+ GtkVBox parent;
+
+ SpiceUsbDeviceWidgetPrivate *priv;
+};
+
+struct _SpiceUsbDeviceWidgetClass
+{
+ GtkVBoxClass parent_class;
+
+ /* signals */
+ void (*connect_failed) (SpiceUsbDeviceWidget *widget,
+ SpiceUsbDevice *device, GError *error);
+};
+
+/* ------------------------------------------------------------------ */
+/* Prototypes for callbacks */
+static void device_added_cb(SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device, gpointer user_data);
+static void device_removed_cb(SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device, gpointer user_data);
+static void device_error_cb(SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device, GError *err, gpointer user_data);
+static gboolean spice_usb_device_widget_update_status(gpointer user_data);
+
+/* ------------------------------------------------------------------ */
+/* gobject glue */
+
+#define SPICE_USB_DEVICE_WIDGET_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), SPICE_TYPE_USB_DEVICE_WIDGET, \
+ SpiceUsbDeviceWidgetPrivate))
+
+enum {
+ PROP_0,
+ PROP_SESSION,
+ PROP_DEVICE_FORMAT_STRING,
+};
+
+enum {
+ CONNECT_FAILED,
+ LAST_SIGNAL,
+};
+
+struct _SpiceUsbDeviceWidgetPrivate {
+ SpiceSession *session;
+ gchar *device_format_string;
+ SpiceUsbDeviceManager *manager;
+ GtkWidget *info_bar;
+ GtkWidget *label;
+ gchar *err_msg;
+ gsize device_count;
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE(SpiceUsbDeviceWidget, spice_usb_device_widget, GTK_TYPE_BOX);
+
+static void spice_usb_device_widget_get_property(GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceUsbDeviceWidget *self = SPICE_USB_DEVICE_WIDGET(gobject);
+ SpiceUsbDeviceWidgetPrivate *priv = self->priv;
+
+ switch (prop_id) {
+ case PROP_SESSION:
+ g_value_set_object(value, priv->session);
+ break;
+ case PROP_DEVICE_FORMAT_STRING:
+ g_value_set_string(value, priv->device_format_string);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_usb_device_widget_set_property(GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SpiceUsbDeviceWidget *self = SPICE_USB_DEVICE_WIDGET(gobject);
+ SpiceUsbDeviceWidgetPrivate *priv = self->priv;
+
+ switch (prop_id) {
+ case PROP_SESSION:
+ priv->session = g_value_dup_object(value);
+ break;
+ case PROP_DEVICE_FORMAT_STRING:
+ priv->device_format_string = g_value_dup_string(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void spice_usb_device_widget_hide_info_bar(SpiceUsbDeviceWidget *self)
+{
+ SpiceUsbDeviceWidgetPrivate *priv = self->priv;
+
+ if (priv->info_bar) {
+ gtk_widget_destroy(priv->info_bar);
+ priv->info_bar = NULL;
+ }
+}
+
+static void
+spice_usb_device_widget_show_info_bar(SpiceUsbDeviceWidget *self,
+ const gchar *message,
+ GtkMessageType message_type,
+ const gchar *stock_icon_id)
+{
+ SpiceUsbDeviceWidgetPrivate *priv = self->priv;
+ GtkWidget *info_bar, *content_area, *hbox, *widget;
+
+ spice_usb_device_widget_hide_info_bar(self);
+
+ info_bar = gtk_info_bar_new();
+ gtk_info_bar_set_message_type(GTK_INFO_BAR(info_bar), message_type);
+
+ content_area = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_bar));
+ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
+ gtk_container_add(GTK_CONTAINER(content_area), hbox);
+
+ widget = gtk_image_new_from_icon_name(stock_icon_id,
+ GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
+
+ widget = gtk_label_new(message);
+ gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
+
+ priv->info_bar = gtk_alignment_new(0.0, 0.0, 1.0, 0.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(priv->info_bar), 0, 0, 12, 0);
+ gtk_container_add(GTK_CONTAINER(priv->info_bar), info_bar);
+ gtk_box_pack_start(GTK_BOX(self), priv->info_bar, FALSE, FALSE, 0);
+ gtk_widget_show_all(priv->info_bar);
+}
+
+static GObject *spice_usb_device_widget_constructor(
+ GType gtype, guint n_properties, GObjectConstructParam *properties)
+{
+ GObject *obj;
+ SpiceUsbDeviceWidget *self;
+ SpiceUsbDeviceWidgetPrivate *priv;
+ GPtrArray *devices = NULL;
+ GError *err = NULL;
+ gchar *str;
+ int i;
+
+ {
+ /* Always chain up to the parent constructor */
+ GObjectClass *parent_class;
+ parent_class = G_OBJECT_CLASS(spice_usb_device_widget_parent_class);
+ obj = parent_class->constructor(gtype, n_properties, properties);
+ }
+
+ self = SPICE_USB_DEVICE_WIDGET(obj);
+ priv = self->priv;
+ if (!priv->session)
+ g_error("SpiceUsbDeviceWidget constructed without a session");
+
+ priv->label = gtk_label_new(NULL);
+ str = g_strdup_printf("<b>%s</b>", _("Select USB devices to redirect"));
+ gtk_label_set_markup(GTK_LABEL (priv->label), str);
+ g_free(str);
+ gtk_misc_set_alignment(GTK_MISC(priv->label), 0.0, 0.5);
+ gtk_box_pack_start(GTK_BOX(self), priv->label, FALSE, FALSE, 0);
+
+ priv->manager = spice_usb_device_manager_get(priv->session, &err);
+ if (err) {
+ spice_usb_device_widget_show_info_bar(self, err->message,
+ GTK_MESSAGE_WARNING,
+ "dialog-warning");
+ g_clear_error(&err);
+ return obj;
+ }
+
+ g_signal_connect(priv->manager, "device-added",
+ G_CALLBACK(device_added_cb), self);
+ g_signal_connect(priv->manager, "device-removed",
+ G_CALLBACK(device_removed_cb), self);
+ g_signal_connect(priv->manager, "device-error",
+ G_CALLBACK(device_error_cb), self);
+
+ devices = spice_usb_device_manager_get_devices(priv->manager);
+ if (!devices)
+ goto end;
+
+ for (i = 0; i < devices->len; i++)
+ device_added_cb(NULL, g_ptr_array_index(devices, i), self);
+
+ g_ptr_array_unref(devices);
+
+end:
+ spice_usb_device_widget_update_status(self);
+
+ return obj;
+}
+
+static void spice_usb_device_widget_finalize(GObject *object)
+{
+ SpiceUsbDeviceWidget *self = SPICE_USB_DEVICE_WIDGET(object);
+ SpiceUsbDeviceWidgetPrivate *priv = self->priv;
+
+ if (priv->manager) {
+ g_signal_handlers_disconnect_by_func(priv->manager,
+ device_added_cb, self);
+ g_signal_handlers_disconnect_by_func(priv->manager,
+ device_removed_cb, self);
+ g_signal_handlers_disconnect_by_func(priv->manager,
+ device_error_cb, self);
+ }
+ g_object_unref(priv->session);
+ g_free(priv->device_format_string);
+
+ if (G_OBJECT_CLASS(spice_usb_device_widget_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_usb_device_widget_parent_class)->finalize(object);
+}
+
+static void spice_usb_device_widget_class_init(
+ SpiceUsbDeviceWidgetClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *)klass;
+ GParamSpec *pspec;
+
+ g_type_class_add_private (klass, sizeof (SpiceUsbDeviceWidgetPrivate));
+
+ gobject_class->constructor = spice_usb_device_widget_constructor;
+ gobject_class->finalize = spice_usb_device_widget_finalize;
+ gobject_class->get_property = spice_usb_device_widget_get_property;
+ gobject_class->set_property = spice_usb_device_widget_set_property;
+
+ /**
+ * SpiceUsbDeviceWidget:session:
+ *
+ * #SpiceSession this #SpiceUsbDeviceWidget is associated with
+ *
+ **/
+ pspec = g_param_spec_object("session",
+ "Session",
+ "SpiceSession",
+ SPICE_TYPE_SESSION,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property(gobject_class, PROP_SESSION, pspec);
+
+ /**
+ * SpiceUsbDeviceWidget:device-format-string:
+ *
+ * Format string to pass to spice_usb_device_get_description() for getting
+ * the device USB descriptions.
+ */
+ pspec = g_param_spec_string("device-format-string",
+ "Device format string",
+ "Format string for device description",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property(gobject_class, PROP_DEVICE_FORMAT_STRING,
+ pspec);
+
+ /**
+ * SpiceUsbDeviceWidget::connect-failed:
+ * @widget: The #SpiceUsbDeviceWidget that emitted the signal
+ * @device: #SpiceUsbDevice boxed object corresponding to the added device
+ * @error: #GError describing the reason why the connect failed
+ *
+ * The #SpiceUsbDeviceWidget::connect-failed signal is emitted whenever
+ * the user has requested for a device to be redirected and this has
+ * failed.
+ **/
+ signals[CONNECT_FAILED] =
+ g_signal_new("connect-failed",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SpiceUsbDeviceWidgetClass, connect_failed),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__BOXED_BOXED,
+ G_TYPE_NONE,
+ 2,
+ SPICE_TYPE_USB_DEVICE,
+ G_TYPE_ERROR);
+}
+
+static void spice_usb_device_widget_init(SpiceUsbDeviceWidget *self)
+{
+ self->priv = SPICE_USB_DEVICE_WIDGET_GET_PRIVATE(self);
+}
+
+/* ------------------------------------------------------------------ */
+/* public api */
+
+/**
+ * spice_usb_device_widget_new:
+ * @session: #SpiceSession for which to widget will control USB redirection
+ * @device_format_string: (allow-none): String passed to
+ * spice_usb_device_get_description()
+ *
+ * Creates a new widget to control USB redirection.
+ *
+ * Returns: a new #SpiceUsbDeviceWidget instance
+ */
+GtkWidget *spice_usb_device_widget_new(SpiceSession *session,
+ const gchar *device_format_string)
+{
+ return g_object_new(SPICE_TYPE_USB_DEVICE_WIDGET,
+ "orientation", GTK_ORIENTATION_VERTICAL,
+ "session", session,
+ "device-format-string", device_format_string,
+ "spacing", 6,
+ NULL);
+}
+
+/* ------------------------------------------------------------------ */
+/* callbacks */
+
+static SpiceUsbDevice *get_usb_device(GtkWidget *widget)
+{
+ if (!GTK_IS_ALIGNMENT(widget))
+ return NULL;
+
+ widget = gtk_bin_get_child(GTK_BIN(widget));
+ return g_object_get_data(G_OBJECT(widget), "usb-device");
+}
+
+static void check_can_redirect(GtkWidget *widget, gpointer user_data)
+{
+ SpiceUsbDeviceWidget *self = SPICE_USB_DEVICE_WIDGET(user_data);
+ SpiceUsbDeviceWidgetPrivate *priv = self->priv;
+ SpiceUsbDevice *device;
+ gboolean can_redirect;
+ GError *err = NULL;
+
+ device = get_usb_device(widget);
+ if (!device)
+ return; /* Non device widget, ie the info_bar */
+
+ priv->device_count++;
+
+ if (spice_usb_device_manager_is_redirecting(priv->manager)) {
+ can_redirect = FALSE;
+ } else {
+ can_redirect = spice_usb_device_manager_can_redirect_device(priv->manager,
+ device, &err);
+ /* If we cannot redirect this device, append the error message to
+ err_msg, but only if it is *not* already there! */
+ if (!can_redirect) {
+ if (priv->err_msg) {
+ if (!strstr(priv->err_msg, err->message)) {
+ gchar *old_err_msg = priv->err_msg;
+ priv->err_msg = g_strdup_printf("%s\n%s", priv->err_msg,
+ err->message);
+ g_free(old_err_msg);
+ }
+ } else {
+ priv->err_msg = g_strdup(err->message);
+ }
+ }
+ g_clear_error(&err);
+ }
+ gtk_widget_set_sensitive(widget, can_redirect);
+}
+
+static gboolean spice_usb_device_widget_update_status(gpointer user_data)
+{
+ SpiceUsbDeviceWidget *self = SPICE_USB_DEVICE_WIDGET(user_data);
+ SpiceUsbDeviceWidgetPrivate *priv = self->priv;
+ gchar *str, *markup_str;
+ const gchar *free_channels_str;
+ int free_channels;
+ gboolean redirecting;
+
+ redirecting = spice_usb_device_manager_is_redirecting(priv->manager);
+
+ g_object_get(priv->manager, "free-channels", &free_channels, NULL);
+ free_channels_str = ngettext(_("Select USB devices to redirect (%d free channel)"),
+ _("Select USB devices to redirect (%d free channels)"),
+ free_channels);
+ str = g_strdup_printf(free_channels_str, free_channels);
+ markup_str = g_strdup_printf("<b>%s</b>", str);
+ gtk_label_set_markup(GTK_LABEL (priv->label), markup_str);
+ g_free(markup_str);
+ g_free(str);
+
+ priv->device_count = 0;
+ gtk_container_foreach(GTK_CONTAINER(self), check_can_redirect, self);
+
+ if (priv->err_msg) {
+ spice_usb_device_widget_show_info_bar(self, priv->err_msg,
+ GTK_MESSAGE_INFO,
+ "dialog-warning");
+ g_free(priv->err_msg);
+ priv->err_msg = NULL;
+ } else if (redirecting) {
+ spice_usb_device_widget_show_info_bar(self, _("Redirecting USB Device..."),
+ GTK_MESSAGE_INFO,
+ "dialog-information");
+ } else {
+ spice_usb_device_widget_hide_info_bar(self);
+ }
+
+ if (priv->device_count == 0)
+ spice_usb_device_widget_show_info_bar(self, _("No USB devices detected"),
+ GTK_MESSAGE_INFO,
+ "dialog-information");
+ return FALSE;
+}
+
+typedef struct _connect_cb_data {
+ GtkWidget *check;
+ SpiceUsbDeviceWidget *self;
+} connect_cb_data;
+
+static void connect_cb_data_free(connect_cb_data *data)
+{
+ spice_usb_device_widget_update_status(data->self);
+ g_object_unref(data->check);
+ g_object_unref(data->self);
+ g_free(data);
+}
+
+static void _disconnect_cb(GObject *gobject, GAsyncResult *res, gpointer user_data)
+{
+ SpiceUsbDeviceManager *manager = SPICE_USB_DEVICE_MANAGER(gobject);
+ connect_cb_data *data = user_data;
+ GError *err = NULL;
+
+ spice_usb_device_manager_disconnect_device_finish(manager, res, &err);
+ if (err) {
+ SPICE_DEBUG("Device disconnection failed");
+ g_error_free(err);
+ }
+
+ connect_cb_data_free(data);
+}
+
+static void checkbox_clicked_cb(GtkWidget *check, gpointer user_data);
+static void connect_cb(GObject *gobject, GAsyncResult *res, gpointer user_data)
+{
+ SpiceUsbDeviceManager *manager = SPICE_USB_DEVICE_MANAGER(gobject);
+ connect_cb_data *data = user_data;
+ SpiceUsbDeviceWidget *self = data->self;
+ SpiceUsbDeviceWidgetPrivate *priv = self->priv;
+ SpiceUsbDevice *device;
+ GError *err = NULL;
+ gchar *desc;
+
+ spice_usb_device_manager_connect_device_finish(manager, res, &err);
+ if (err) {
+ device = g_object_get_data(G_OBJECT(data->check), "usb-device");
+ desc = spice_usb_device_get_description(device,
+ priv->device_format_string);
+ g_prefix_error(&err, "Could not redirect %s: ", desc);
+ g_free(desc);
+
+ SPICE_DEBUG("%s", err->message);
+ g_signal_emit(self, signals[CONNECT_FAILED], 0, device, err);
+ g_error_free(err);
+
+ /* don't trigger a disconnect if connect failed */
+ g_signal_handlers_block_by_func(GTK_TOGGLE_BUTTON(data->check),
+ checkbox_clicked_cb, self);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->check), FALSE);
+ g_signal_handlers_unblock_by_func(GTK_TOGGLE_BUTTON(data->check),
+ checkbox_clicked_cb, self);
+ }
+
+ connect_cb_data_free(data);
+}
+
+static void checkbox_clicked_cb(GtkWidget *check, gpointer user_data)
+{
+ SpiceUsbDeviceWidget *self = SPICE_USB_DEVICE_WIDGET(user_data);
+ SpiceUsbDeviceWidgetPrivate *priv = self->priv;
+ SpiceUsbDevice *device;
+
+ device = g_object_get_data(G_OBJECT(check), "usb-device");
+ connect_cb_data *data = g_new(connect_cb_data, 1);
+ data->check = g_object_ref(check);
+ data->self = g_object_ref(self);
+
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check))) {
+ spice_usb_device_manager_connect_device_async(priv->manager,
+ device,
+ NULL,
+ connect_cb,
+ data);
+ } else {
+ spice_usb_device_manager_disconnect_device_async(priv->manager,
+ device,
+ NULL,
+ _disconnect_cb,
+ data);
+
+ }
+ spice_usb_device_widget_update_status(self);
+}
+
+static void checkbox_usb_device_destroy_notify(gpointer data)
+{
+ g_boxed_free(spice_usb_device_get_type(), data);
+}
+
+static void device_added_cb(SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device, gpointer user_data)
+{
+ SpiceUsbDeviceWidget *self = SPICE_USB_DEVICE_WIDGET(user_data);
+ SpiceUsbDeviceWidgetPrivate *priv = self->priv;
+ GtkWidget *align, *check;
+ gchar *desc;
+
+ desc = spice_usb_device_get_description(device,
+ priv->device_format_string);
+ check = gtk_check_button_new_with_label(desc);
+ g_free(desc);
+
+ if (spice_usb_device_manager_is_device_connected(priv->manager,
+ device))
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
+
+ g_object_set_data_full(
+ G_OBJECT(check), "usb-device",
+ g_boxed_copy(spice_usb_device_get_type(), device),
+ checkbox_usb_device_destroy_notify);
+ g_signal_connect(G_OBJECT(check), "clicked",
+ G_CALLBACK(checkbox_clicked_cb), self);
+
+ align = gtk_alignment_new(0, 0, 0, 0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(align), 0, 0, 12, 0);
+ gtk_container_add(GTK_CONTAINER(align), check);
+ gtk_box_pack_end(GTK_BOX(self), align, FALSE, FALSE, 0);
+ spice_usb_device_widget_update_status(self);
+ gtk_widget_show_all(align);
+}
+
+static void destroy_widget_by_usb_device(GtkWidget *widget, gpointer user_data)
+{
+ if (get_usb_device(widget) == user_data)
+ gtk_widget_destroy(widget);
+}
+
+static void device_removed_cb(SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device, gpointer user_data)
+{
+ SpiceUsbDeviceWidget *self = SPICE_USB_DEVICE_WIDGET(user_data);
+
+ gtk_container_foreach(GTK_CONTAINER(self),
+ destroy_widget_by_usb_device, device);
+
+ spice_usb_device_widget_update_status(self);
+}
+
+static void set_inactive_by_usb_device(GtkWidget *widget, gpointer user_data)
+{
+ if (get_usb_device(widget) == user_data) {
+ GtkWidget *check = gtk_bin_get_child(GTK_BIN(widget));
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), FALSE);
+ }
+}
+
+static void device_error_cb(SpiceUsbDeviceManager *manager,
+ SpiceUsbDevice *device, GError *err, gpointer user_data)
+{
+ SpiceUsbDeviceWidget *self = SPICE_USB_DEVICE_WIDGET(user_data);
+
+ gtk_container_foreach(GTK_CONTAINER(self),
+ set_inactive_by_usb_device, device);
+
+ spice_usb_device_widget_update_status(self);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_USB_DEVICE_WIDGET_H__
+#define __SPICE_USB_DEVICE_WIDGET_H__
+
+#if !defined(__SPICE_CLIENT_GTK_H_INSIDE__) && !defined(SPICE_COMPILATION)
+#warning "Only <spice-client-gtk.h> can be included directly"
+#endif
+
+#include <gtk/gtk.h>
+#include "spice-client.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_USB_DEVICE_WIDGET (spice_usb_device_widget_get_type ())
+#define SPICE_USB_DEVICE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_USB_DEVICE_WIDGET, SpiceUsbDeviceWidget))
+#define SPICE_USB_DEVICE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_USB_DEVICE_WIDGET, SpiceUsbDeviceWidgetClass))
+#define SPICE_IS_USB_DEVICE_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_USB_DEVICE_WIDGET))
+#define SPICE_IS_USB_DEVICE_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_USB_DEVICE_WIDGET))
+#define SPICE_USB_DEVICE_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_USB_DEVICE_WIDGET, SpiceUsbDeviceWidgetClass))
+
+typedef struct _SpiceUsbDeviceWidget SpiceUsbDeviceWidget;
+typedef struct _SpiceUsbDeviceWidgetClass SpiceUsbDeviceWidgetClass;
+typedef struct _SpiceUsbDeviceWidgetPrivate SpiceUsbDeviceWidgetPrivate;
+
+GType spice_usb_device_widget_get_type(void);
+GtkWidget *spice_usb_device_widget_new(SpiceSession *session,
+ const gchar *device_format_string);
+
+G_END_DECLS
+
+#endif /* __SPICE_USB_DEVICE_WIDGET_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2014-2015 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+ Authors:
+ Dmitry Fleytman <dmitry@daynix.com>
+ Kirill Moizik <kirill@daynix.com>
+*/
+#include <config.h>
+
+#include <windows.h>
+#include <glib-object.h>
+#include "usbdk_api.h"
+#include "channel-usbredir-priv.h"
+
+#define USB_DK_HIDE_RULE_MATCH_ALL ((ULONG64)(-1))
+typedef struct tag_USB_DK_HIDE_RULE
+{
+ ULONG64 Hide;
+ ULONG64 Class;
+ ULONG64 VID;
+ ULONG64 PID;
+ ULONG64 BCD;
+} USB_DK_HIDE_RULE, *PUSB_DK_HIDE_RULE;
+
+typedef HANDLE(__cdecl *USBDK_CREATEHIDERHANDLE)(void);
+typedef BOOL(__cdecl * USBDK_ADDHIDERULE)(HANDLE hider_handle, PUSB_DK_HIDE_RULE rule);
+typedef BOOL(__cdecl *USBDK_CLEARHIDERULES)(HANDLE hider_handle);
+typedef void(__cdecl *USBDK_CLOSEHIDERHANDLE)(HANDLE hider_handle);
+
+struct tag_usbdk_api_wrapper
+{
+ HMODULE module;
+ USBDK_CREATEHIDERHANDLE CreateHiderHandle;
+ USBDK_ADDHIDERULE AddRule;
+ USBDK_CLEARHIDERULES ClearRules;
+ USBDK_CLOSEHIDERHANDLE CloseHiderHandle;
+};
+
+BOOL usbdk_is_driver_installed(void)
+{
+ gboolean usbdk_installed = FALSE;
+ SC_HANDLE managerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+
+ if (managerHandle) {
+ SC_HANDLE serviceHandle = OpenService(managerHandle, TEXT("UsbDk"), GENERIC_READ);
+
+ if (serviceHandle) {
+ SPICE_DEBUG("UsbDk driver is installed.");
+ usbdk_installed = TRUE;
+ CloseServiceHandle(serviceHandle);
+ }
+ CloseServiceHandle(managerHandle);
+ }
+ return usbdk_installed;
+}
+
+void usbdk_api_unload(usbdk_api_wrapper *usbdk_api)
+{
+ if (usbdk_api != NULL) {
+ if (usbdk_api->module != NULL) {
+ SPICE_DEBUG("Unloading UsbDk API DLL");
+ FreeLibrary(usbdk_api->module);
+ }
+ g_free(usbdk_api);
+ }
+}
+
+usbdk_api_wrapper *usbdk_api_load(void)
+{
+ usbdk_api_wrapper *usbdk_api = g_new0(usbdk_api_wrapper, 1);
+
+ SPICE_DEBUG("Loading UsbDk API DLL");
+ usbdk_api->module = LoadLibraryA("UsbDkHelper");
+ if (usbdk_api->module == NULL) {
+ g_warning("Failed to load UsbDkHelper.dll, error %lu", GetLastError());
+ goto error_unload;
+ }
+
+ usbdk_api->CreateHiderHandle = (USBDK_CREATEHIDERHANDLE)
+ GetProcAddress(usbdk_api->module, "UsbDk_CreateHiderHandle");
+ if (usbdk_api->CreateHiderHandle == NULL) {
+ g_warning("Failed to find CreateHandle entry point");
+ goto error_unload;
+ }
+
+ usbdk_api->AddRule = (USBDK_ADDHIDERULE)
+ GetProcAddress(usbdk_api->module, "UsbDk_AddHideRule");
+ if (usbdk_api->AddRule == NULL) {
+ g_warning("Failed to find AddRule entry point");
+ goto error_unload;
+ }
+
+ usbdk_api->ClearRules = (USBDK_CLEARHIDERULES)
+ GetProcAddress(usbdk_api->module, "UsbDk_ClearHideRules");
+ if (usbdk_api->ClearRules == NULL) {
+ g_warning("Failed to find ClearRules entry point");
+ goto error_unload;
+ }
+
+ usbdk_api->CloseHiderHandle = (USBDK_CLOSEHIDERHANDLE)
+ GetProcAddress(usbdk_api->module, "UsbDk_CloseHiderHandle");
+ if (usbdk_api->CloseHiderHandle == NULL) {
+ g_warning("Failed to find CloseHiderHandle entry point");
+ goto error_unload;
+ }
+ return usbdk_api;
+
+error_unload:
+ usbdk_api_unload(usbdk_api);
+ return NULL;
+}
+
+static uint64_t usbdk_usbredir_field_to_usbdk(int value)
+{
+ if (value >= 0) {
+ return value;
+ }
+
+ g_warn_if_fail(value == -1);
+
+ return USB_DK_HIDE_RULE_MATCH_ALL;
+}
+
+static BOOL usbdk_add_hide_rule(usbdk_api_wrapper *usbdk_api,
+ HANDLE hider_handle,
+ PUSB_DK_HIDE_RULE rule)
+{
+ return usbdk_api->AddRule(hider_handle, rule);
+}
+
+void usbdk_api_set_hide_rules(usbdk_api_wrapper *usbdk_api, HANDLE hider_handle,
+ gchar *redirect_on_connect)
+{
+ struct usbredirfilter_rule *rules;
+ int r, count;
+
+ r = usbredirfilter_string_to_rules(redirect_on_connect, ",", "|",
+ &rules, &count);
+ if (r) {
+ g_warning("auto-connect rules parsing failed with error %d", r);
+ return;
+ }
+
+ for (int i = 0; i < count; i++) {
+ USB_DK_HIDE_RULE rule;
+ rule.Hide = usbdk_usbredir_field_to_usbdk(rules[i].allow);
+ rule.Class = usbdk_usbredir_field_to_usbdk(rules[i].device_class);
+ rule.VID = usbdk_usbredir_field_to_usbdk(rules[i].vendor_id);
+ rule.PID = usbdk_usbredir_field_to_usbdk(rules[i].product_id);
+ rule.BCD = usbdk_usbredir_field_to_usbdk(rules[i].device_version_bcd);
+ if (!usbdk_add_hide_rule(usbdk_api, hider_handle, &rule)) {
+ SPICE_DEBUG("UsbDk add hide rule API failed");
+ }
+ }
+
+ free(rules);
+}
+
+HANDLE usbdk_create_hider_handle(usbdk_api_wrapper *usbdk_api)
+{
+ HANDLE handle = usbdk_api->CreateHiderHandle();
+ return (handle == INVALID_HANDLE_VALUE) ? NULL : handle;
+}
+
+BOOL usbdk_clear_hide_rules(usbdk_api_wrapper *usbdk_api, HANDLE hider_handle)
+{
+ return usbdk_api->ClearRules(hider_handle);
+}
+
+void usbdk_close_hider_handle(usbdk_api_wrapper *usbdk_api, HANDLE hider_handle)
+{
+ return usbdk_api->CloseHiderHandle(hider_handle);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2014-2015 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+
+ Authors:
+ Dmitry Fleytman <dmitry@daynix.com>
+ Kirill Moizik <kirill@daynix.com>
+*/
+#ifndef USBDK_HEADER
+#define USBDK_HEADER
+
+typedef struct tag_usbdk_api_wrapper usbdk_api_wrapper;
+
+usbdk_api_wrapper *usbdk_api_load(void);
+void usbdk_api_unload(usbdk_api_wrapper *usbdk_api);
+BOOL usbdk_is_driver_installed(void);
+HANDLE usbdk_create_hider_handle(usbdk_api_wrapper *usbdk_api);
+void usbdk_api_set_hide_rules(usbdk_api_wrapper *usbdk_api, HANDLE hider_handle, gchar *redirect_on_connect);
+BOOL usbdk_clear_hide_rules(usbdk_api_wrapper *usbdk_api, HANDLE hider_handle);
+void usbdk_close_hider_handle(usbdk_api_wrapper *usbdk_api, HANDLE hider_handle);
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include <glib-object.h>
+#include <glib/gi18n-lib.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#ifdef USE_USBREDIR
+#ifdef __linux__
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+#include "usbutil.h"
+#include "spice-util-priv.h"
+
+#define VENDOR_NAME_LEN (122 - sizeof(void *))
+#define PRODUCT_NAME_LEN 126
+
+typedef struct _usb_product_info {
+ guint16 product_id;
+ char name[PRODUCT_NAME_LEN];
+} usb_product_info;
+
+typedef struct _usb_vendor_info {
+ usb_product_info *product_info;
+ int product_count;
+ guint16 vendor_id;
+ char name[VENDOR_NAME_LEN];
+} usb_vendor_info;
+
+static GMutex usbids_load_mutex;
+static int usbids_vendor_count = 0; /* < 0: failed, 0: empty, > 0: loaded */
+static usb_vendor_info *usbids_vendor_info = NULL;
+
+G_GNUC_INTERNAL
+const char *spice_usbutil_libusb_strerror(enum libusb_error error_code)
+{
+ switch (error_code) {
+ case LIBUSB_SUCCESS:
+ return "Success";
+ case LIBUSB_ERROR_IO:
+ return "Input/output error";
+ case LIBUSB_ERROR_INVALID_PARAM:
+ return "Invalid parameter";
+ case LIBUSB_ERROR_ACCESS:
+ return "Access denied (insufficient permissions)";
+ case LIBUSB_ERROR_NO_DEVICE:
+ return "No such device (it may have been disconnected)";
+ case LIBUSB_ERROR_NOT_FOUND:
+ return "Entity not found";
+ case LIBUSB_ERROR_BUSY:
+ return "Resource busy";
+ case LIBUSB_ERROR_TIMEOUT:
+ return "Operation timed out";
+ case LIBUSB_ERROR_OVERFLOW:
+ return "Overflow";
+ case LIBUSB_ERROR_PIPE:
+ return "Pipe error";
+ case LIBUSB_ERROR_INTERRUPTED:
+ return "System call interrupted (perhaps due to signal)";
+ case LIBUSB_ERROR_NO_MEM:
+ return "Insufficient memory";
+ case LIBUSB_ERROR_NOT_SUPPORTED:
+ return "Operation not supported or unimplemented on this platform";
+ case LIBUSB_ERROR_OTHER:
+ return "Other error";
+ }
+ return "Unknown error";
+}
+
+#ifdef __linux__
+/* <Sigh> libusb does not allow getting the manufacturer and product strings
+ without opening the device, so grab them directly from sysfs */
+static gchar *spice_usbutil_get_sysfs_attribute(int bus, int address,
+ const char *attribute)
+{
+ struct stat stat_buf;
+ char filename[256];
+ gchar *contents;
+
+ snprintf(filename, sizeof(filename), "/dev/bus/usb/%03d/%03d",
+ bus, address);
+ if (stat(filename, &stat_buf) != 0)
+ return NULL;
+
+ snprintf(filename, sizeof(filename), "/sys/dev/char/%u:%u/%s",
+ major(stat_buf.st_rdev), minor(stat_buf.st_rdev), attribute);
+ if (!g_file_get_contents(filename, &contents, NULL, NULL))
+ return NULL;
+
+ /* Remove the newline at the end */
+ contents[strlen(contents) - 1] = '\0';
+
+ return contents;
+}
+#endif
+
+static gboolean spice_usbutil_parse_usbids(gchar *path)
+{
+ gchar *contents, *line, **lines;
+ usb_product_info *product_info;
+ int i, j, id, product_count = 0;
+
+ usbids_vendor_count = 0;
+ if (!g_file_get_contents(path, &contents, NULL, NULL)) {
+ usbids_vendor_count = -1;
+ return FALSE;
+ }
+
+ lines = g_strsplit(contents, "\n", -1);
+
+ for (i = 0; lines[i]; i++) {
+ if (!isxdigit(lines[i][0]) || !isxdigit(lines[i][1]))
+ continue;
+
+ for (j = 1; lines[i + j] &&
+ (lines[i + j][0] == '\t' ||
+ lines[i + j][0] == '#' ||
+ lines[i + j][0] == '\0'); j++) {
+ if (lines[i + j][0] == '\t' && isxdigit(lines[i + j][1]))
+ product_count++;
+ }
+ i += j - 1;
+
+ usbids_vendor_count++;
+ }
+
+ usbids_vendor_info = g_new(usb_vendor_info, usbids_vendor_count);
+ product_info = g_new(usb_product_info, product_count);
+
+ usbids_vendor_count = 0;
+ for (i = 0; lines[i]; i++) {
+ line = lines[i];
+
+ if (!isxdigit(line[0]) || !isxdigit(line[1]))
+ continue;
+
+ id = strtoul(line, &line, 16);
+ while (isspace(line[0]))
+ line++;
+
+ usbids_vendor_info[usbids_vendor_count].vendor_id = id;
+ snprintf(usbids_vendor_info[usbids_vendor_count].name,
+ VENDOR_NAME_LEN, "%s", line);
+
+ product_count = 0;
+ for (j = 1; lines[i + j] &&
+ (lines[i + j][0] == '\t' ||
+ lines[i + j][0] == '#' ||
+ lines[i + j][0] == '\0'); j++) {
+ line = lines[i + j];
+
+ if (line[0] != '\t' || !isxdigit(line[1]))
+ continue;
+
+ id = strtoul(line + 1, &line, 16);
+ while (isspace(line[0]))
+ line++;
+ product_info[product_count].product_id = id;
+ snprintf(product_info[product_count].name,
+ PRODUCT_NAME_LEN, "%s", line);
+
+ product_count++;
+ }
+ i += j - 1;
+
+ usbids_vendor_info[usbids_vendor_count].product_count = product_count;
+ usbids_vendor_info[usbids_vendor_count].product_info = product_info;
+ product_info += product_count;
+ usbids_vendor_count++;
+ }
+
+ g_strfreev(lines);
+ g_free(contents);
+
+#if 0 /* Testing only */
+ for (i = 0; i < usbids_vendor_count; i++) {
+ printf("%04x %s\n", usbids_vendor_info[i].vendor_id,
+ usbids_vendor_info[i].name);
+ product_info = usbids_vendor_info[i].product_info;
+ for (j = 0; j < usbids_vendor_info[i].product_count; j++) {
+ printf("\t%04x %s\n", product_info[j].product_id,
+ product_info[j].name);
+ }
+ }
+#endif
+
+ return TRUE;
+}
+
+static gboolean spice_usbutil_load_usbids(void)
+{
+ gboolean success = FALSE;
+
+ g_mutex_lock(&usbids_load_mutex);
+ if (usbids_vendor_count) {
+ success = usbids_vendor_count > 0;
+ goto leave;
+ }
+
+#ifdef WITH_USBIDS
+ success = spice_usbutil_parse_usbids(USB_IDS);
+#else
+ {
+ const gchar * const *dirs = g_get_system_data_dirs();
+ gchar *path = NULL;
+ int i;
+
+ for (i = 0; dirs[i]; ++i) {
+ path = g_build_filename(dirs[i], "hwdata", "usb.ids", NULL);
+ success = spice_usbutil_parse_usbids(path);
+ SPICE_DEBUG("loading %s success: %s", path, spice_yes_no(success));
+ g_free(path);
+
+ if (success)
+ goto leave;
+ }
+ }
+#endif
+
+leave:
+ g_mutex_unlock(&usbids_load_mutex);
+ return success;
+}
+
+G_GNUC_INTERNAL
+void spice_usb_util_get_device_strings(int bus, int address,
+ int vendor_id, int product_id,
+ gchar **manufacturer, gchar **product)
+{
+ usb_product_info *product_info;
+ int i, j;
+
+ g_return_if_fail(manufacturer != NULL);
+ g_return_if_fail(product != NULL);
+
+ *manufacturer = NULL;
+ *product = NULL;
+
+#if __linux__
+ *manufacturer = spice_usbutil_get_sysfs_attribute(bus, address, "manufacturer");
+ *product = spice_usbutil_get_sysfs_attribute(bus, address, "product");
+#endif
+
+ if ((!*manufacturer || !*product) &&
+ spice_usbutil_load_usbids()) {
+
+ for (i = 0; i < usbids_vendor_count; i++) {
+ if ((int)usbids_vendor_info[i].vendor_id != vendor_id)
+ continue;
+
+ if (!*manufacturer && usbids_vendor_info[i].name[0])
+ *manufacturer = g_strdup(usbids_vendor_info[i].name);
+
+ product_info = usbids_vendor_info[i].product_info;
+ for (j = 0; j < usbids_vendor_info[i].product_count; j++) {
+ if ((int)product_info[j].product_id != product_id)
+ continue;
+
+ if (!*product && product_info[j].name[0])
+ *product = g_strdup(product_info[j].name);
+
+ break;
+ }
+ break;
+ }
+ }
+
+ if (!*manufacturer)
+ *manufacturer = g_strdup(_("USB"));
+ if (!*product)
+ *product = g_strdup(_("Device"));
+
+ /* Some devices have unwanted whitespace in their strings */
+ g_strstrip(*manufacturer);
+ g_strstrip(*product);
+
+ /* Some devices repeat the manufacturer at the beginning of product */
+ if (g_str_has_prefix(*product, *manufacturer) &&
+ strlen(*product) > strlen(*manufacturer)) {
+ gchar *tmp = g_strdup(*product + strlen(*manufacturer));
+ g_free(*product);
+ *product = tmp;
+ g_strstrip(*product);
+ }
+}
+
+#endif
+
+#ifdef USBUTIL_TEST
+int main()
+{
+ if (spice_usbutil_load_usbids())
+ exit(0);
+
+ exit(1);
+}
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Hans de Goede <hdegoede@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_USBUTIL_H__
+#define __SPICE_USBUTIL_H__
+
+#include <glib.h>
+
+#ifdef USE_USBREDIR
+#include <libusb.h>
+
+G_BEGIN_DECLS
+
+const char *spice_usbutil_libusb_strerror(enum libusb_error error_code);
+void spice_usb_util_get_device_strings(int bus, int address,
+ int vendor_id, int product_id,
+ gchar **manufacturer, gchar **product);
+
+G_END_DECLS
+
+#endif /* USE_USBREDIR */
+#endif /* __SPICE_USBUTIL_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include "config.h"
+
+#include <string.h>
+
+#include "vmcstream.h"
+#include "spice-channel-priv.h"
+#include "gio-coroutine.h"
+
+struct _SpiceVmcInputStream
+{
+ GInputStream parent_instance;
+ GTask *task;
+ struct coroutine *coroutine;
+
+ SpiceChannel *channel;
+ gboolean all;
+ guint8 *buffer;
+ gsize count;
+ gsize pos;
+
+ gulong cancel_id;
+};
+
+struct _SpiceVmcInputStreamClass
+{
+ GInputStreamClass parent_class;
+};
+
+static gssize spice_vmc_input_stream_read (GInputStream *stream,
+ void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error);
+static void spice_vmc_input_stream_read_async (GInputStream *stream,
+ void *buffer,
+ gsize count,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+static gssize spice_vmc_input_stream_read_finish (GInputStream *stream,
+ GAsyncResult *result,
+ GError **error);
+static gssize spice_vmc_input_stream_skip (GInputStream *stream,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error);
+static gboolean spice_vmc_input_stream_close (GInputStream *stream,
+ GCancellable *cancellable,
+ GError **error);
+
+G_DEFINE_TYPE(SpiceVmcInputStream, spice_vmc_input_stream, G_TYPE_INPUT_STREAM)
+
+
+static void
+spice_vmc_input_stream_class_init(SpiceVmcInputStreamClass *klass)
+{
+ GInputStreamClass *istream_class;
+
+ istream_class = G_INPUT_STREAM_CLASS(klass);
+ istream_class->read_fn = spice_vmc_input_stream_read;
+ istream_class->read_async = spice_vmc_input_stream_read_async;
+ istream_class->read_finish = spice_vmc_input_stream_read_finish;
+ istream_class->skip = spice_vmc_input_stream_skip;
+ istream_class->close_fn = spice_vmc_input_stream_close;
+}
+
+static void
+spice_vmc_input_stream_init(SpiceVmcInputStream *self)
+{
+}
+
+static SpiceVmcInputStream *
+spice_vmc_input_stream_new(void)
+{
+ SpiceVmcInputStream *self;
+
+ self = g_object_new(SPICE_TYPE_VMC_INPUT_STREAM, NULL);
+
+ return self;
+}
+
+typedef struct _complete_in_idle_cb_data {
+ GTask *task;
+ gssize pos;
+} complete_in_idle_cb_data;
+
+static gboolean
+complete_in_idle_cb(gpointer user_data)
+{
+ complete_in_idle_cb_data *data = user_data;
+
+ g_task_return_int(data->task, data->pos);
+
+ g_object_unref (data->task);
+ g_free (data);
+
+ return FALSE;
+}
+
+/* coroutine */
+/*
+ * Feed a SpiceVmc stream with new data from a coroutine
+ *
+ * The other end will be waiting on read_async() until data is fed
+ * here.
+ */
+G_GNUC_INTERNAL void
+spice_vmc_input_stream_co_data(SpiceVmcInputStream *self,
+ const gpointer d, gsize size)
+{
+ guint8 *data = d;
+
+ g_return_if_fail(SPICE_IS_VMC_INPUT_STREAM(self));
+ g_return_if_fail(self->coroutine == NULL);
+
+ self->coroutine = coroutine_self();
+
+ while (size > 0) {
+ complete_in_idle_cb_data *cb_data;
+
+ SPICE_DEBUG("spicevmc co_data %p", self->task);
+ if (!self->task)
+ coroutine_yield(NULL);
+
+ g_return_if_fail(self->task != NULL);
+
+ gsize min = MIN(self->count, size);
+ memcpy(self->buffer, data, min);
+
+ size -= min;
+ data += min;
+
+ SPICE_DEBUG("spicevmc co_data complete: %" G_GSIZE_FORMAT
+ "/%" G_GSIZE_FORMAT, min, self->count);
+
+ self->pos += min;
+ self->buffer += min;
+
+ if (self->all && min > 0 && self->pos != self->count)
+ continue;
+
+ /* Let's deal with the task complete in idle by ourselves, as GTask
+ * heuristic only makes sense in a non-coroutine case.
+ */
+ cb_data = g_new(complete_in_idle_cb_data , 1);
+ cb_data->task = g_object_ref(self->task);
+ cb_data->pos = self->pos;
+ g_idle_add(complete_in_idle_cb, cb_data);
+
+ g_clear_object(&self->task);
+ }
+
+ self->coroutine = NULL;
+}
+
+static void
+read_cancelled(GCancellable *cancellable,
+ gpointer user_data)
+{
+ SpiceVmcInputStream *self = SPICE_VMC_INPUT_STREAM(user_data);
+
+ SPICE_DEBUG("read cancelled, %p", self->task);
+ g_task_return_new_error(self->task,
+ G_IO_ERROR, G_IO_ERROR_CANCELLED,
+ "read cancelled");
+
+ /* With GTask, we don't need to disconnect GCancellable when task is
+ * cancelled within cancellable callback as it could lead to deadlocks
+ * e.g: https://bugzilla.gnome.org/show_bug.cgi?id=705395 */
+ g_clear_object(&self->task);
+}
+
+G_GNUC_INTERNAL void
+spice_vmc_input_stream_read_all_async(GInputStream *stream,
+ void *buffer,
+ gsize count,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SpiceVmcInputStream *self = SPICE_VMC_INPUT_STREAM(stream);
+ GTask *task;
+
+ /* no concurrent read permitted by ginputstream */
+ g_return_if_fail(self->task == NULL);
+ self->all = TRUE;
+ self->buffer = buffer;
+ self->count = count;
+ self->pos = 0;
+ task = g_task_new(self,
+ cancellable,
+ callback,
+ user_data);
+ self->task = task;
+ if (cancellable)
+ self->cancel_id =
+ g_cancellable_connect(cancellable, G_CALLBACK(read_cancelled), self, NULL);
+
+ if (self->coroutine)
+ coroutine_yieldto(self->coroutine, NULL);
+}
+
+G_GNUC_INTERNAL gssize
+spice_vmc_input_stream_read_all_finish(GInputStream *stream,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = G_TASK(result);
+ SpiceVmcInputStream *self = SPICE_VMC_INPUT_STREAM(stream);
+ GCancellable *cancel;
+
+ g_return_val_if_fail(g_task_is_valid(task, self), -1);
+ cancel = g_task_get_cancellable(task);
+ if (!g_cancellable_is_cancelled(cancel)) {
+ g_cancellable_disconnect(cancel, self->cancel_id);
+ self->cancel_id = 0;
+ }
+ return g_task_propagate_int(task, error);
+}
+
+static void
+spice_vmc_input_stream_read_async(GInputStream *stream,
+ void *buffer,
+ gsize count,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SpiceVmcInputStream *self = SPICE_VMC_INPUT_STREAM(stream);
+ GTask *task;
+
+ /* no concurrent read permitted by ginputstream */
+ g_return_if_fail(self->task == NULL);
+ self->all = FALSE;
+ self->buffer = buffer;
+ self->count = count;
+ self->pos = 0;
+
+ task = g_task_new(self, cancellable, callback, user_data);
+ self->task = task;
+ if (cancellable)
+ self->cancel_id =
+ g_cancellable_connect(cancellable, G_CALLBACK(read_cancelled), self, NULL);
+
+ if (self->coroutine)
+ coroutine_yieldto(self->coroutine, NULL);
+}
+
+static gssize
+spice_vmc_input_stream_read_finish(GInputStream *stream,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = G_TASK(result);
+ SpiceVmcInputStream *self = SPICE_VMC_INPUT_STREAM(stream);
+ GCancellable *cancel;
+
+ g_return_val_if_fail(g_task_is_valid(task, self), -1);
+
+ cancel = g_task_get_cancellable(task);
+ if (!g_cancellable_is_cancelled(cancel)) {
+ g_cancellable_disconnect(cancel, self->cancel_id);
+ self->cancel_id = 0;
+ }
+ return g_task_propagate_int(task, error);
+}
+
+static gssize
+spice_vmc_input_stream_read(GInputStream *stream,
+ void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_reached(-1);
+}
+
+static gssize
+spice_vmc_input_stream_skip(GInputStream *stream,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_reached(-1);
+}
+
+static gboolean
+spice_vmc_input_stream_close(GInputStream *stream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SPICE_DEBUG("fake close");
+ return TRUE;
+}
+
+/* OUTPUT */
+
+struct _SpiceVmcOutputStream
+{
+ GOutputStream parent_instance;
+
+ SpiceChannel *channel; /* weak */
+};
+
+struct _SpiceVmcOutputStreamClass
+{
+ GOutputStreamClass parent_class;
+};
+
+static gssize spice_vmc_output_stream_write_fn (GOutputStream *stream,
+ const void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error);
+static gssize spice_vmc_output_stream_write_finish (GOutputStream *stream,
+ GAsyncResult *result,
+ GError **error);
+static void spice_vmc_output_stream_write_async (GOutputStream *stream,
+ const void *buffer,
+ gsize count,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+G_DEFINE_TYPE(SpiceVmcOutputStream, spice_vmc_output_stream, G_TYPE_OUTPUT_STREAM)
+
+
+static void
+spice_vmc_output_stream_class_init(SpiceVmcOutputStreamClass *klass)
+{
+ GOutputStreamClass *ostream_class;
+
+ ostream_class = G_OUTPUT_STREAM_CLASS(klass);
+ ostream_class->write_fn = spice_vmc_output_stream_write_fn;
+ ostream_class->write_async = spice_vmc_output_stream_write_async;
+ ostream_class->write_finish = spice_vmc_output_stream_write_finish;
+}
+
+static void
+spice_vmc_output_stream_init(SpiceVmcOutputStream *self)
+{
+}
+
+static SpiceVmcOutputStream *
+spice_vmc_output_stream_new(SpiceChannel *channel)
+{
+ SpiceVmcOutputStream *self;
+
+ self = g_object_new(SPICE_TYPE_VMC_OUTPUT_STREAM, NULL);
+ self->channel = channel;
+
+ return self;
+}
+
+static gssize
+spice_vmc_output_stream_write_fn(GOutputStream *stream,
+ const void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ SpiceVmcOutputStream *self = SPICE_VMC_OUTPUT_STREAM(stream);
+ SpiceMsgOut *msg_out;
+
+ msg_out = spice_msg_out_new(SPICE_CHANNEL(self->channel),
+ SPICE_MSGC_SPICEVMC_DATA);
+ spice_marshaller_add(msg_out->marshaller, buffer, count);
+ spice_msg_out_send(msg_out);
+
+ return count;
+}
+
+static gssize
+spice_vmc_output_stream_write_finish(GOutputStream *stream,
+ GAsyncResult *simple,
+ GError **error)
+{
+ SpiceVmcOutputStream *self = SPICE_VMC_OUTPUT_STREAM(stream);
+ GAsyncResult *res = g_task_propagate_pointer(G_TASK(simple), error);
+ gssize bytes_written;
+
+ SPICE_DEBUG("spicevmc write finish");
+ bytes_written = spice_vmc_write_finish(self->channel, res, error);
+ g_object_unref(res);
+
+ return bytes_written;
+}
+
+static void
+write_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GTask *task = user_data;
+
+ g_task_return_pointer(task, g_object_ref(res), g_object_unref);
+
+ g_object_unref(task);
+}
+
+static void
+spice_vmc_output_stream_write_async(GOutputStream *stream,
+ const void *buffer,
+ gsize count,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SpiceVmcOutputStream *self = SPICE_VMC_OUTPUT_STREAM(stream);
+ GTask *task;
+
+ SPICE_DEBUG("spicevmc write async");
+ /* an AsyncResult to forward async op to channel */
+ task = g_task_new(self, cancellable, callback, user_data);
+
+ spice_vmc_write_async(self->channel, buffer, count,
+ cancellable, write_cb,
+ task);
+}
+
+/* STREAM */
+
+struct _SpiceVmcStream
+{
+ GIOStream parent_instance;
+
+ SpiceChannel *channel; /* weak */
+ SpiceVmcInputStream *in;
+ SpiceVmcOutputStream *out;
+};
+
+struct _SpiceVmcStreamClass
+{
+ GIOStreamClass parent_class;
+};
+
+static void spice_vmc_stream_finalize (GObject *object);
+static GInputStream * spice_vmc_stream_get_input_stream (GIOStream *stream);
+static GOutputStream * spice_vmc_stream_get_output_stream (GIOStream *stream);
+
+G_DEFINE_TYPE(SpiceVmcStream, spice_vmc_stream, G_TYPE_IO_STREAM)
+
+static void
+spice_vmc_stream_class_init(SpiceVmcStreamClass *klass)
+{
+ GObjectClass *object_class;
+ GIOStreamClass *iostream_class;
+
+ object_class = G_OBJECT_CLASS(klass);
+ object_class->finalize = spice_vmc_stream_finalize;
+
+ iostream_class = G_IO_STREAM_CLASS(klass);
+ iostream_class->get_input_stream = spice_vmc_stream_get_input_stream;
+ iostream_class->get_output_stream = spice_vmc_stream_get_output_stream;
+}
+
+static void
+spice_vmc_stream_finalize(GObject *object)
+{
+ SpiceVmcStream *self = SPICE_VMC_STREAM(object);
+
+ g_clear_object(&self->in);
+ g_clear_object(&self->out);
+
+ G_OBJECT_CLASS(spice_vmc_stream_parent_class)->finalize(object);
+}
+
+static void
+spice_vmc_stream_init(SpiceVmcStream *self)
+{
+}
+
+G_GNUC_INTERNAL SpiceVmcStream *
+spice_vmc_stream_new(SpiceChannel *channel)
+{
+ SpiceVmcStream *self;
+
+ self = g_object_new(SPICE_TYPE_VMC_STREAM, NULL);
+ self->channel = channel;
+
+ return self;
+}
+
+static GInputStream *
+spice_vmc_stream_get_input_stream(GIOStream *stream)
+{
+ SpiceVmcStream *self = SPICE_VMC_STREAM(stream);
+
+ if (!self->in)
+ self->in = spice_vmc_input_stream_new();
+
+ return G_INPUT_STREAM(self->in);
+}
+
+static GOutputStream *
+spice_vmc_stream_get_output_stream(GIOStream *stream)
+{
+ SpiceVmcStream *self = SPICE_VMC_STREAM(stream);
+
+ if (!self->out)
+ self->out = spice_vmc_output_stream_new(self->channel);
+
+ return G_OUTPUT_STREAM(self->out);
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_VMC_STREAM_H__
+#define __SPICE_VMC_STREAM_H__
+
+#include <gio/gio.h>
+
+#include "spice-types.h"
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_VMC_INPUT_STREAM (spice_vmc_input_stream_get_type ())
+#define SPICE_VMC_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SPICE_TYPE_VMC_INPUT_STREAM, SpiceVmcInputStream))
+#define SPICE_VMC_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SPICE_TYPE_VMC_INPUT_STREAM, SpiceVmcInputStreamClass))
+#define SPICE_IS_VMC_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPICE_TYPE_VMC_INPUT_STREAM))
+#define SPICE_IS_VMC_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPICE_TYPE_VMC_INPUT_STREAM))
+#define SPICE_VMC_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SPICE_TYPE_VMC_INPUT_STREAM, SpiceVmcInputStreamClass))
+
+typedef struct _SpiceVmcInputStreamClass SpiceVmcInputStreamClass;
+typedef struct _SpiceVmcInputStream SpiceVmcInputStream;
+
+GType spice_vmc_input_stream_get_type (void) G_GNUC_CONST;
+void spice_vmc_input_stream_co_data (SpiceVmcInputStream *input,
+ const gpointer data,
+ gsize size);
+
+void spice_vmc_input_stream_read_all_async(GInputStream *stream,
+ void *buffer,
+ gsize count,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gssize spice_vmc_input_stream_read_all_finish(GInputStream *stream,
+ GAsyncResult *result,
+ GError **error);
+
+
+#define SPICE_TYPE_VMC_OUTPUT_STREAM (spice_vmc_output_stream_get_type ())
+#define SPICE_VMC_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SPICE_TYPE_VMC_OUTPUT_STREAM, SpiceVmcOutputStream))
+#define SPICE_VMC_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SPICE_TYPE_VMC_OUTPUT_STREAM, SpiceVmcOutputStreamClass))
+#define SPICE_IS_VMC_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPICE_TYPE_VMC_OUTPUT_STREAM))
+#define SPICE_IS_VMC_OUTPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPICE_TYPE_VMC_OUTPUT_STREAM))
+#define SPICE_VMC_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SPICE_TYPE_VMC_OUTPUT_STREAM, SpiceVmcOutputStreamClass))
+
+typedef struct _SpiceVmcOutputStreamClass SpiceVmcOutputStreamClass;
+typedef struct _SpiceVmcOutputStream SpiceVmcOutputStream;
+
+GType spice_vmc_output_stream_get_type (void) G_GNUC_CONST;
+
+#define SPICE_TYPE_VMC_STREAM (spice_vmc_stream_get_type ())
+#define SPICE_VMC_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SPICE_TYPE_VMC_STREAM, SpiceVmcStream))
+#define SPICE_VMC_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SPICE_TYPE_VMC_STREAM, SpiceVmcStreamClass))
+#define SPICE_IS_VMC_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPICE_TYPE_VMC_STREAM))
+#define SPICE_IS_VMC_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SPICE_TYPE_VMC_STREAM))
+#define SPICE_VMC_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SPICE_TYPE_VMC_STREAM, SpiceVmcStreamClass))
+
+typedef struct _SpiceVmcStreamClass SpiceVmcStreamClass;
+typedef struct _SpiceVmcStream SpiceVmcStream;
+
+GType spice_vmc_stream_get_type (void) G_GNUC_CONST;
+SpiceVmcStream* spice_vmc_stream_new (SpiceChannel *channel);
+
+G_END_DECLS
+
+#endif /* __SPICE_VMC_STREAM_H__ */
--- /dev/null
+/*
+ * Copyright (C) 2008 Anthony Liguori <anthony@codemonkey.ws>
+ * Copyright (C) 2009-2010 Daniel P. Berrange <dan@berrange.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include "vncdisplaykeymap.h"
+
+#include "spice-util.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "vnc-keymap"
+#define VNC_DEBUG(message) SPICE_DEBUG(message);
+
+/*
+ * This table is taken from QEMU x_keymap.c, under the terms:
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+/* Compatability code to allow build on Gtk2 and Gtk3 */
+#ifndef GDK_Tab
+#define GDK_Tab GDK_KEY_Tab
+#endif
+
+/* keycode translation for sending ISO_Left_Send
+ * to vncserver
+ */
+static struct {
+ GdkKeymapKey *keys;
+ gint n_keys;
+ guint keyval;
+} untranslated_keys[] = {{NULL, 0, GDK_Tab}};
+
+static unsigned int ref_count_for_untranslated_keys = 0;
+
+#ifdef GDK_WINDOWING_WAYLAND
+#include <gdk/gdkwayland.h>
+#endif
+
+#ifdef GDK_WINDOWING_BROADWAY
+#include <gdk/gdkbroadway.h>
+#endif
+
+#if defined(GDK_WINDOWING_X11) || defined(GDK_WINDOWING_WAYLAND)
+/* Xorg Linux + evdev (offset evdev keycodes) */
+#include "vncdisplaykeymap_xorgevdev2xtkbd.c"
+#endif
+
+#ifdef GDK_WINDOWING_X11
+#include <gdk/gdkx.h>
+#include <X11/XKBlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+/* Xorg Linux + kbd (offset + mangled XT keycodes) */
+#include "vncdisplaykeymap_xorgkbd2xtkbd.c"
+/* Xorg OS-X aka XQuartz (offset OS-X keycodes) */
+#include "vncdisplaykeymap_xorgxquartz2xtkbd.c"
+/* Xorg Cygwin aka XWin (offset + mangled XT keycodes) */
+#include "vncdisplaykeymap_xorgxwin2xtkbd.c"
+
+/* Gtk2 compat */
+#ifndef GDK_IS_X11_WINDOW
+#define GDK_IS_X11_WINDOW(win) (1)
+#endif
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+/* Win32 native virtual keycodes */
+#include "vncdisplaykeymap_win322xtkbd.c"
+
+/* Gtk2 compat */
+#ifndef GDK_IS_WIN32_WINDOW
+#define GDK_IS_WIN32_WINDOW(win) (1)
+#endif
+#endif
+
+#ifdef GDK_WINDOWING_QUARTZ
+/* OS-X native keycodes */
+#include "vncdisplaykeymap_osx2xtkbd.c"
+
+/* Gtk2 compat */
+#ifndef GDK_IS_QUARTZ_WINDOW
+#define GDK_IS_QUARTZ_WINDOW(win) (1)
+#endif
+#endif
+
+#ifdef GDK_WINDOWING_BROADWAY
+/* X11 keysyms */
+#include "vncdisplaykeymap_x112xtkbd.c"
+
+/* Gtk2 compat */
+#ifndef GDK_IS_BROADWAY_WINDOW
+#define GDK_IS_BROADWAY_WINDOW(win) (1)
+#endif
+
+#endif
+
+#ifdef GDK_WINDOWING_X11
+
+#define STRPREFIX(a,b) (strncmp((a),(b),strlen((b))) == 0)
+
+static gboolean check_for_xwin(GdkDisplay *dpy)
+{
+ char *vendor = ServerVendor(gdk_x11_display_get_xdisplay(dpy));
+
+ if (strstr(vendor, "Cygwin/X"))
+ return TRUE;
+
+ return FALSE;
+}
+
+static gboolean check_for_xquartz(GdkDisplay *dpy)
+{
+ int nextensions;
+ int i;
+ gboolean match = FALSE;
+ char **extensions = XListExtensions(gdk_x11_display_get_xdisplay(dpy),
+ &nextensions);
+ for (i = 0 ; extensions != NULL && i < nextensions ; i++) {
+ if (strcmp(extensions[i], "Apple-WM") == 0 ||
+ strcmp(extensions[i], "Apple-DRI") == 0)
+ match = TRUE;
+ }
+ if (extensions)
+ XFreeExtensionList(extensions);
+
+ return match;
+}
+#endif
+
+const guint16 *vnc_display_keymap_gdk2xtkbd_table(GdkWindow *window,
+ size_t *maplen)
+{
+#ifdef GDK_WINDOWING_X11
+ if (GDK_IS_X11_WINDOW(window)) {
+ XkbDescPtr desc;
+ const gchar *keycodes = NULL;
+ GdkDisplay *dpy = gdk_window_get_display(window);
+
+ /* There is no easy way to determine what X11 server
+ * and platform & keyboard driver is in use. Thus we
+ * do best guess heuristics.
+ *
+ * This will need more work for people with other
+ * X servers..... patches welcomed.
+ */
+
+ Display *xdisplay = gdk_x11_display_get_xdisplay(dpy);
+ desc = XkbGetMap(xdisplay,
+ XkbGBN_AllComponentsMask,
+ XkbUseCoreKbd);
+ if (desc) {
+ if (XkbGetNames(xdisplay, XkbKeycodesNameMask, desc) == Success) {
+ keycodes = gdk_x11_get_xatom_name(desc->names->keycodes);
+ if (!keycodes)
+ g_warning("could not lookup keycode name");
+ }
+ XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True);
+ }
+
+ if (check_for_xwin(dpy)) {
+ VNC_DEBUG("Using xwin keycode mapping");
+ *maplen = G_N_ELEMENTS(keymap_xorgxwin2xtkbd);
+ return keymap_xorgxwin2xtkbd;
+ } else if (check_for_xquartz(dpy)) {
+ VNC_DEBUG("Using xquartz keycode mapping");
+ *maplen = G_N_ELEMENTS(keymap_xorgxquartz2xtkbd);
+ return keymap_xorgxquartz2xtkbd;
+ } else if (keycodes && STRPREFIX(keycodes, "evdev")) {
+ VNC_DEBUG("Using evdev keycode mapping");
+ *maplen = G_N_ELEMENTS(keymap_xorgevdev2xtkbd);
+ return keymap_xorgevdev2xtkbd;
+ } else if (keycodes && STRPREFIX(keycodes, "xfree86")) {
+ VNC_DEBUG("Using xfree86 keycode mapping");
+ *maplen = G_N_ELEMENTS(keymap_xorgkbd2xtkbd);
+ return keymap_xorgkbd2xtkbd;
+ } else {
+ g_warning("Unknown keycode mapping '%s'.\n"
+ "Please report to gtk-vnc-list@gnome.org\n"
+ "including the following information:\n"
+ "\n"
+ " - Operating system\n"
+ " - GDK build\n"
+ " - X11 Server\n"
+ " - xprop -root\n"
+ " - xdpyinfo\n",
+ keycodes);
+ return NULL;
+ }
+ }
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+ if (GDK_IS_WIN32_WINDOW(window)) {
+ VNC_DEBUG("Using Win32 virtual keycode mapping");
+ *maplen = G_N_ELEMENTS(keymap_win322xtkbd);
+ return keymap_win322xtkbd;
+ }
+#endif
+
+#ifdef GDK_WINDOWING_QUARTZ
+ if (GDK_IS_QUARTZ_WINDOW(window)) {
+ VNC_DEBUG("Using OS-X virtual keycode mapping");
+ *maplen = G_N_ELEMENTS(keymap_osx2xtkbd);
+ return keymap_osx2xtkbd;
+ }
+#endif
+
+#ifdef GDK_WINDOWING_WAYLAND
+ if (GDK_IS_WAYLAND_WINDOW(window)) {
+ VNC_DEBUG("Using Wayland Xorg/evdev virtual keycode mapping");
+ *maplen = G_N_ELEMENTS(keymap_xorgevdev2xtkbd);
+ return keymap_xorgevdev2xtkbd;
+ }
+#endif
+
+#ifdef GDK_WINDOWING_BROADWAY
+ if (GDK_IS_BROADWAY_WINDOW(window)) {
+ g_warning("experimental: using broadway, x11 virtual keysym mapping - with very limited support. See also https://bugzilla.gnome.org/show_bug.cgi?id=700105");
+
+ *maplen = G_N_ELEMENTS(keymap_x112xtkbd);
+ return keymap_x112xtkbd;
+ }
+#endif
+
+ g_warning("Unsupported GDK Windowing platform.\n"
+ "Disabling extended keycode tables.\n"
+ "Please report to gtk-vnc-list@gnome.org\n"
+ "including the following information:\n"
+ "\n"
+ " - Operating system\n"
+ " - GDK Windowing system build\n");
+ return NULL;
+}
+
+guint16 vnc_display_keymap_gdk2xtkbd(const guint16 *keycode_map,
+ size_t keycode_maplen,
+ guint16 keycode)
+{
+ if (!keycode_map)
+ return 0;
+ if (keycode >= keycode_maplen)
+ return 0;
+ return keycode_map[keycode];
+}
+
+/* Set the keymap entries */
+void vnc_display_keyval_set_entries(void)
+{
+ size_t i;
+ if (ref_count_for_untranslated_keys == 0)
+ for (i = 0; i < sizeof(untranslated_keys) / sizeof(untranslated_keys[0]); i++)
+ gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(),
+ untranslated_keys[i].keyval,
+ &untranslated_keys[i].keys,
+ &untranslated_keys[i].n_keys);
+ ref_count_for_untranslated_keys++;
+}
+
+/* Free the keymap entries */
+void vnc_display_keyval_free_entries(void)
+{
+ size_t i;
+
+ if (ref_count_for_untranslated_keys == 0)
+ return;
+
+ ref_count_for_untranslated_keys--;
+ if (ref_count_for_untranslated_keys == 0)
+ for (i = 0; i < sizeof(untranslated_keys) / sizeof(untranslated_keys[0]); i++)
+ g_free(untranslated_keys[i].keys);
+
+}
+
+/* Get the keyval from the keycode without the level. */
+guint vnc_display_keyval_from_keycode(guint keycode, guint keyval)
+{
+ size_t i;
+ for (i = 0; i < sizeof(untranslated_keys) / sizeof(untranslated_keys[0]); i++) {
+ if (keycode == untranslated_keys[i].keys[0].keycode) {
+ return untranslated_keys[i].keyval;
+ }
+ }
+
+ return keyval;
+}
+/*
+ * Local variables:
+ * c-indent-level: 8
+ * c-basic-offset: 8
+ * tab-width: 8
+ * End:
+ */
--- /dev/null
+/*
+ * GTK VNC Widget
+ *
+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
+ * Copyright (C) 2009-2010 Daniel P. Berrange <dan@berrange.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.0 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef VNC_DISPLAY_KEYMAP_H
+#define VNC_DISPLAY_KEYMAP_H
+
+#include <glib.h>
+
+const guint16 *vnc_display_keymap_gdk2xtkbd_table(GdkWindow *window,
+ size_t *maplen);
+guint16 vnc_display_keymap_gdk2xtkbd(const guint16 *keycode_map,
+ size_t keycode_maplen,
+ guint16 keycode);
+void vnc_display_keyval_set_entries(void);
+void vnc_display_keyval_free_entries(void);
+guint vnc_display_keyval_from_keycode(guint keycode, guint keyval);
+
+#endif /* VNC_DISPLAY_KEYMAP_H */
--- /dev/null
+static const guint16 keymap_osx2xtkbd[] = {
+ [0x0] = 0x1e, /* 0 (ANSI_A) => 30 via 30 (KEY_A) */
+ [0x1] = 0x1f, /* 1 (ANSI_S) => 31 via 31 (KEY_S) */
+ [0x2] = 0x20, /* 2 (ANSI_D) => 32 via 32 (KEY_D) */
+ [0x3] = 0x21, /* 3 (ANSI_F) => 33 via 33 (KEY_F) */
+ [0x4] = 0x23, /* 4 (ANSI_H) => 35 via 35 (KEY_H) */
+ [0x5] = 0x22, /* 5 (ANSI_G) => 34 via 34 (KEY_G) */
+ [0x6] = 0x2c, /* 6 (ANSI_Z) => 44 via 44 (KEY_Z) */
+ [0x7] = 0x2d, /* 7 (ANSI_X) => 45 via 45 (KEY_X) */
+ [0x8] = 0x2e, /* 8 (ANSI_C) => 46 via 46 (KEY_C) */
+ [0x9] = 0x2f, /* 9 (ANSI_V) => 47 via 47 (KEY_V) */
+ [0xa] = 0x70, /* 10 (ISO_Section) => 112 via 170 (KEY_ISO) */
+ [0xb] = 0x30, /* 11 (ANSI_B) => 48 via 48 (KEY_B) */
+ [0xc] = 0x10, /* 12 (ANSI_Q) => 16 via 16 (KEY_Q) */
+ [0xd] = 0x11, /* 13 (ANSI_W) => 17 via 17 (KEY_W) */
+ [0xe] = 0x12, /* 14 (ANSI_E) => 18 via 18 (KEY_E) */
+ [0xf] = 0x13, /* 15 (ANSI_R) => 19 via 19 (KEY_R) */
+ [0x10] = 0x15, /* 16 (ANSI_Y) => 21 via 21 (KEY_Y) */
+ [0x11] = 0x14, /* 17 (ANSI_T) => 20 via 20 (KEY_T) */
+ [0x12] = 0x2, /* 18 (ANSI_1) => 2 via 2 (KEY_1) */
+ [0x13] = 0x3, /* 19 (ANSI_2) => 3 via 3 (KEY_2) */
+ [0x14] = 0x4, /* 20 (ANSI_3) => 4 via 4 (KEY_3) */
+ [0x15] = 0x5, /* 21 (ANSI_4) => 5 via 5 (KEY_4) */
+ [0x16] = 0x7, /* 22 (ANSI_6) => 7 via 7 (KEY_6) */
+ [0x17] = 0x6, /* 23 (ANSI_5) => 6 via 6 (KEY_5) */
+ [0x18] = 0xd, /* 24 (ANSI_Equal) => 13 via 13 (KEY_EQUAL) */
+ [0x19] = 0xa, /* 25 (ANSI_9) => 10 via 10 (KEY_9) */
+ [0x1a] = 0x8, /* 26 (ANSI_7) => 8 via 8 (KEY_7) */
+ [0x1b] = 0xc, /* 27 (ANSI_Minus) => 12 via 12 (KEY_MINUS) */
+ [0x1c] = 0x9, /* 28 (ANSI_8) => 9 via 9 (KEY_8) */
+ [0x1d] = 0xb, /* 29 (ANSI_0) => 11 via 11 (KEY_0) */
+ [0x1e] = 0x1b, /* 30 (ANSI_RightBracket) => 27 via 27 (KEY_RIGHTBRACE) */
+ [0x1f] = 0x18, /* 31 (ANSI_O) => 24 via 24 (KEY_O) */
+ [0x20] = 0x16, /* 32 (ANSI_U) => 22 via 22 (KEY_U) */
+ [0x21] = 0x1a, /* 33 (ANSI_LeftBracket) => 26 via 26 (KEY_LEFTBRACE) */
+ [0x22] = 0x17, /* 34 (ANSI_I) => 23 via 23 (KEY_I) */
+ [0x23] = 0x19, /* 35 (ANSI_P) => 25 via 25 (KEY_P) */
+ [0x24] = 0x1c, /* 36 (Return) => 28 via 28 (KEY_ENTER) */
+ [0x25] = 0x26, /* 37 (ANSI_L) => 38 via 38 (KEY_L) */
+ [0x26] = 0x24, /* 38 (ANSI_J) => 36 via 36 (KEY_J) */
+ [0x27] = 0x28, /* 39 (ANSI_Quote) => 40 via 40 (KEY_APOSTROPHE) */
+ [0x28] = 0x25, /* 40 (ANSI_K) => 37 via 37 (KEY_K) */
+ [0x29] = 0x27, /* 41 (ANSI_Semicolon) => 39 via 39 (KEY_SEMICOLON) */
+ [0x2a] = 0x2b, /* 42 (ANSI_Backslash) => 43 via 43 (KEY_BACKSLASH) */
+ [0x2b] = 0x33, /* 43 (ANSI_Comma) => 51 via 51 (KEY_COMMA) */
+ [0x2c] = 0x35, /* 44 (ANSI_Slash) => 53 via 53 (KEY_SLASH) */
+ [0x2d] = 0x31, /* 45 (ANSI_N) => 49 via 49 (KEY_N) */
+ [0x2e] = 0x32, /* 46 (ANSI_M) => 50 via 50 (KEY_M) */
+ [0x2f] = 0x34, /* 47 (ANSI_Period) => 52 via 52 (KEY_DOT) */
+ [0x30] = 0xf, /* 48 (Tab) => 15 via 15 (KEY_TAB) */
+ [0x31] = 0x39, /* 49 (Space) => 57 via 57 (KEY_SPACE) */
+ [0x32] = 0x29, /* 50 (ANSI_Grave) => 41 via 41 (KEY_GRAVE) */
+ [0x33] = 0xe, /* 51 (Delete) => 14 via 14 (KEY_BACKSPACE) */
+ [0x35] = 0x1, /* 53 (Escape) => 1 via 1 (KEY_ESC) */
+ [0x37] = 0x15b, /* 55 (Command) => 347 via 125 (KEY_LEFTMETA) */
+ [0x38] = 0x2a, /* 56 (Shift) => 42 via 42 (KEY_LEFTSHIFT) */
+ [0x39] = 0x3a, /* 57 (CapsLock) => 58 via 58 (KEY_CAPSLOCK) */
+ [0x3a] = 0x38, /* 58 (Option) => 56 via 56 (KEY_LEFTALT) */
+ [0x3b] = 0x1d, /* 59 (Control) => 29 via 29 (KEY_LEFTCTRL) */
+ [0x3c] = 0x36, /* 60 (RightShift) => 54 via 54 (KEY_RIGHTSHIFT) */
+ [0x3d] = 0x138, /* 61 (RightOption) => 312 via 100 (KEY_RIGHTALT) */
+ [0x3e] = 0x11d, /* 62 (RightControl) => 285 via 97 (KEY_RIGHTCTRL) */
+ [0x3f] = 0x15d, /* 63 (Function) => 349 via 127 (KEY_COMPOSE) */
+ [0x40] = 0x103, /* 64 (F17) => 259 via 187 (KEY_F17) */
+ [0x41] = 0x53, /* 65 (ANSI_KeypadDecimal) => 83 via 83 (KEY_KPDOT) */
+ [0x43] = 0x37, /* 67 (ANSI_KeypadMultiply) => 55 via 55 (KEY_KPASTERISK) */
+ [0x45] = 0x4e, /* 69 (ANSI_KeypadPlus) => 78 via 78 (KEY_KPPLUS) */
+ [0x47] = 0x7e, /* 71 (ANSI_KeypadClear????) => 126 via 121 (KEY_KPCOMMA) */
+ [0x48] = 0x130, /* 72 (VolumeUp) => 304 via 115 (KEY_VOLUMEUP) */
+ [0x49] = 0x12e, /* 73 (VolumeDown) => 302 via 114 (KEY_VOLUMEDOWN) */
+ [0x4a] = 0x120, /* 74 (Mute) => 288 via 113 (KEY_MUTE) */
+ [0x4b] = 0x135, /* 75 (ANSI_KeypadDivide) => 309 via 98 (KEY_KPSLASH) */
+ [0x4c] = 0x11c, /* 76 (ANSI_KeypadEnter) => 284 via 96 (KEY_KPENTER) */
+ [0x4e] = 0x4a, /* 78 (ANSI_KeypadMinus) => 74 via 74 (KEY_KPMINUS) */
+ [0x4f] = 0x177, /* 79 (F18) => 375 via 188 (KEY_F18) */
+ [0x50] = 0x104, /* 80 (F19) => 260 via 189 (KEY_F19) */
+ [0x51] = 0x59, /* 81 (ANSI_KeypadEquals) => 89 via 117 (KEY_KPEQUAL) */
+ [0x52] = 0x52, /* 82 (ANSI_Keypad0) => 82 via 82 (KEY_KP0) */
+ [0x53] = 0x4f, /* 83 (ANSI_Keypad1) => 79 via 79 (KEY_KP1) */
+ [0x54] = 0x50, /* 84 (ANSI_Keypad2) => 80 via 80 (KEY_KP2) */
+ [0x55] = 0x51, /* 85 (ANSI_Keypad3) => 81 via 81 (KEY_KP3) */
+ [0x56] = 0x4b, /* 86 (ANSI_Keypad4) => 75 via 75 (KEY_KP4) */
+ [0x57] = 0x4c, /* 87 (ANSI_Keypad5) => 76 via 76 (KEY_KP5) */
+ [0x58] = 0x4d, /* 88 (ANSI_Keypad6) => 77 via 77 (KEY_KP6) */
+ [0x59] = 0x47, /* 89 (ANSI_Keypad7) => 71 via 71 (KEY_KP7) */
+ [0x5a] = 0x5a, /* 90 (F20) => 90 via 190 (KEY_F20) */
+ [0x5b] = 0x48, /* 91 (ANSI_Keypad8) => 72 via 72 (KEY_KP8) */
+ [0x5c] = 0x49, /* 92 (ANSI_Keypad9) => 73 via 73 (KEY_KP9) */
+ [0x5d] = 0x7d, /* 93 (JIS_Yen) => 125 via 124 (KEY_YEN) */
+ [0x5f] = 0x5c, /* 95 (JIS_KeypadComma) => 92 via 95 (KEY_KPJPCOMMA) */
+ [0x60] = 0x3f, /* 96 (F5) => 63 via 63 (KEY_F5) */
+ [0x61] = 0x40, /* 97 (F6) => 64 via 64 (KEY_F6) */
+ [0x62] = 0x41, /* 98 (F7) => 65 via 65 (KEY_F7) */
+ [0x63] = 0x3d, /* 99 (F3) => 61 via 61 (KEY_F3) */
+ [0x64] = 0x42, /* 100 (F8) => 66 via 66 (KEY_F8) */
+ [0x65] = 0x43, /* 101 (F9) => 67 via 67 (KEY_F9) */
+ [0x67] = 0x57, /* 103 (F11) => 87 via 87 (KEY_F11) */
+ [0x68] = 0x78, /* 104 (JIS_Kana????) => 120 via 90 (KEY_KATAKANA) */
+ [0x69] = 0x5d, /* 105 (F13) => 93 via 183 (KEY_F13) */
+ [0x6a] = 0x55, /* 106 (F16) => 85 via 186 (KEY_F16) */
+ [0x6b] = 0x5e, /* 107 (F14) => 94 via 184 (KEY_F14) */
+ [0x6d] = 0x44, /* 109 (F10) => 68 via 68 (KEY_F10) */
+ [0x6f] = 0x58, /* 111 (F12) => 88 via 88 (KEY_F12) */
+ [0x71] = 0x5f, /* 113 (F15) => 95 via 185 (KEY_F15) */
+ [0x73] = 0x147, /* 115 (Home) => 327 via 102 (KEY_HOME) */
+ [0x74] = 0x149, /* 116 (PageUp) => 329 via 104 (KEY_PAGEUP) */
+ [0x75] = 0x153, /* 117 (ForwardDelete) => 339 via 111 (KEY_DELETE) */
+ [0x76] = 0x3e, /* 118 (F4) => 62 via 62 (KEY_F4) */
+ [0x77] = 0x14f, /* 119 (End) => 335 via 107 (KEY_END) */
+ [0x78] = 0x3c, /* 120 (F2) => 60 via 60 (KEY_F2) */
+ [0x79] = 0x151, /* 121 (PageDown) => 337 via 109 (KEY_PAGEDOWN) */
+ [0x7a] = 0x3b, /* 122 (F1) => 59 via 59 (KEY_F1) */
+ [0x7b] = 0x14b, /* 123 (LeftArrow) => 331 via 105 (KEY_LEFT) */
+ [0x7c] = 0x14d, /* 124 (RightArrow) => 333 via 106 (KEY_RIGHT) */
+ [0x7d] = 0x150, /* 125 (DownArrow) => 336 via 108 (KEY_DOWN) */
+ [0x7e] = 0x148, /* 126 (UpArrow) => 328 via 103 (KEY_UP) */
+};
--- /dev/null
+static const guint16 keymap_win322xtkbd[] = {
+ [0x8] = 0xe, /* 8 (VK_BACK) => 14 via 14 (KEY_BACKSPACE) */
+ [0x9] = 0xf, /* 9 (VK_TAB) => 15 via 15 (KEY_TAB) */
+ [0xd] = 0x1c, /* 13 (VK_RETURN) => 28 via 28 (KEY_ENTER) */
+ [0x10] = 0x2a, /* 16 (VK_LSHIFT) => 42 via 42 (KEY_LEFTSHIFT) */
+ [0x11] = 0x1d, /* 17 (VK_CONTROL) => 29 via 29 (KEY_LEFTCTRL) */
+ [0x12] = 0x38, /* 18 (VK_MENU) => 56 via 56 (KEY_LEFTALT) */
+ [0x13] = 0x146, /* 19 (VK_PAUSE) => 326 via 119 (KEY_PAUSE) */
+ [0x14] = 0x3a, /* 20 (VK_CAPITAL) => 58 via 58 (KEY_CAPSLOCK) */
+ [0x19] = 0x10d, /* 25 (VK_HANJA) => 269 via 123 (KEY_HANJA) */
+ [0x1b] = 0x1, /* 27 (VK_ESCAPE) => 1 via 1 (KEY_ESC) */
+ [0x20] = 0x39, /* 32 (VK_SPACE) => 57 via 57 (KEY_SPACE) */
+ [0x21] = 0x149, /* 33 (VK_PRIOR) => 329 via 104 (KEY_PAGEUP) */
+ [0x22] = 0x151, /* 34 (VK_NEXT) => 337 via 109 (KEY_PAGEDOWN) */
+ [0x23] = 0x14f, /* 35 (VK_END) => 335 via 107 (KEY_END) */
+ [0x24] = 0x147, /* 36 (VK_HOME) => 327 via 102 (KEY_HOME) */
+ [0x25] = 0x14b, /* 37 (VK_LEFT) => 331 via 105 (KEY_LEFT) */
+ [0x26] = 0x148, /* 38 (VK_UP) => 328 via 103 (KEY_UP) */
+ [0x27] = 0x14d, /* 39 (VK_RIGHT) => 333 via 106 (KEY_RIGHT) */
+ [0x28] = 0x150, /* 40 (VK_DOWN) => 336 via 108 (KEY_DOWN) */
+ [0x2a] = 0x139, /* 42 (VK_PRINT) => 313 via 210 (KEY_PRINT) */
+ [0x2c] = 0x54, /* 44 (VK_SNAPSHOT ???) => 84 via 99 (KEY_SYSRQ) */
+ [0x2d] = 0x152, /* 45 (VK_INSERT) => 338 via 110 (KEY_INSERT) */
+ [0x2e] = 0x153, /* 46 (VK_DELETE) => 339 via 111 (KEY_DELETE) */
+ [0x2f] = 0x175, /* 47 (VK_HELP) => 373 via 138 (KEY_HELP) */
+ [0x30] = 0xb, /* 48 (VK_0) => 11 via 11 (KEY_0) */
+ [0x31] = 0x2, /* 49 (VK_1) => 2 via 2 (KEY_1) */
+ [0x32] = 0x3, /* 50 (VK_2) => 3 via 3 (KEY_2) */
+ [0x33] = 0x4, /* 51 (VK_3) => 4 via 4 (KEY_3) */
+ [0x34] = 0x5, /* 52 (VK_4) => 5 via 5 (KEY_4) */
+ [0x35] = 0x6, /* 53 (VK_5) => 6 via 6 (KEY_5) */
+ [0x36] = 0x7, /* 54 (VK_6) => 7 via 7 (KEY_6) */
+ [0x37] = 0x8, /* 55 (VK_7) => 8 via 8 (KEY_7) */
+ [0x38] = 0x9, /* 56 (VK_8) => 9 via 9 (KEY_8) */
+ [0x39] = 0xa, /* 57 (VK_9) => 10 via 10 (KEY_9) */
+ [0x41] = 0x1e, /* 65 (VK_A) => 30 via 30 (KEY_A) */
+ [0x42] = 0x30, /* 66 (VK_B) => 48 via 48 (KEY_B) */
+ [0x43] = 0x2e, /* 67 (VK_C) => 46 via 46 (KEY_C) */
+ [0x44] = 0x20, /* 68 (VK_D) => 32 via 32 (KEY_D) */
+ [0x45] = 0x12, /* 69 (VK_E) => 18 via 18 (KEY_E) */
+ [0x46] = 0x21, /* 70 (VK_F) => 33 via 33 (KEY_F) */
+ [0x47] = 0x22, /* 71 (VK_G) => 34 via 34 (KEY_G) */
+ [0x48] = 0x23, /* 72 (VK_H) => 35 via 35 (KEY_H) */
+ [0x49] = 0x17, /* 73 (VK_I) => 23 via 23 (KEY_I) */
+ [0x4a] = 0x24, /* 74 (VK_J) => 36 via 36 (KEY_J) */
+ [0x4b] = 0x25, /* 75 (VK_K) => 37 via 37 (KEY_K) */
+ [0x4c] = 0x26, /* 76 (VK_L) => 38 via 38 (KEY_L) */
+ [0x4d] = 0x32, /* 77 (VK_M) => 50 via 50 (KEY_M) */
+ [0x4e] = 0x31, /* 78 (VK_N) => 49 via 49 (KEY_N) */
+ [0x4f] = 0x18, /* 79 (VK_O) => 24 via 24 (KEY_O) */
+ [0x50] = 0x19, /* 80 (VK_P) => 25 via 25 (KEY_P) */
+ [0x51] = 0x10, /* 81 (VK_Q) => 16 via 16 (KEY_Q) */
+ [0x52] = 0x13, /* 82 (VK_R) => 19 via 19 (KEY_R) */
+ [0x53] = 0x1f, /* 83 (VK_S) => 31 via 31 (KEY_S) */
+ [0x54] = 0x14, /* 84 (VK_T) => 20 via 20 (KEY_T) */
+ [0x55] = 0x16, /* 85 (VK_U) => 22 via 22 (KEY_U) */
+ [0x56] = 0x2f, /* 86 (VK_V) => 47 via 47 (KEY_V) */
+ [0x57] = 0x11, /* 87 (VK_W) => 17 via 17 (KEY_W) */
+ [0x58] = 0x2d, /* 88 (VK_X) => 45 via 45 (KEY_X) */
+ [0x59] = 0x15, /* 89 (VK_Y) => 21 via 21 (KEY_Y) */
+ [0x5a] = 0x2c, /* 90 (VK_Z) => 44 via 44 (KEY_Z) */
+ [0x5b] = 0x15b, /* 91 (VK_LWIN) => 347 via 125 (KEY_LEFTMETA) */
+ [0x5c] = 0x15c, /* 92 (VK_RWIN) => 348 via 126 (KEY_RIGHTMETA) */
+ [0x5d] = 0x15d, /* 93 (VK_APPS) => 349 via 127 (KEY_COMPOSE) */
+ [0x5f] = 0x15f, /* 95 (VK_SLEEP) => 351 via 142 (KEY_SLEEP) */
+ [0x60] = 0x52, /* 96 (VK_NUMPAD0) => 82 via 82 (KEY_KP0) */
+ [0x61] = 0x4f, /* 97 (VK_NUMPAD1) => 79 via 79 (KEY_KP1) */
+ [0x62] = 0x50, /* 98 (VK_NUMPAD2) => 80 via 80 (KEY_KP2) */
+ [0x63] = 0x51, /* 99 (VK_NUMPAD3) => 81 via 81 (KEY_KP3) */
+ [0x64] = 0x4b, /* 100 (VK_NUMPAD4) => 75 via 75 (KEY_KP4) */
+ [0x65] = 0x4c, /* 101 (VK_NUMPAD5) => 76 via 76 (KEY_KP5) */
+ [0x66] = 0x4d, /* 102 (VK_NUMPAD6) => 77 via 77 (KEY_KP6) */
+ [0x67] = 0x47, /* 103 (VK_NUMPAD7) => 71 via 71 (KEY_KP7) */
+ [0x68] = 0x48, /* 104 (VK_NUMPAD8) => 72 via 72 (KEY_KP8) */
+ [0x69] = 0x49, /* 105 (VK_NUMPAD9) => 73 via 73 (KEY_KP9) */
+ [0x6a] = 0x37, /* 106 (VK_MULTIPLY) => 55 via 55 (KEY_KPASTERISK) */
+ [0x6b] = 0x4e, /* 107 (VK_ADD) => 78 via 78 (KEY_KPPLUS) */
+ [0x6c] = 0x7e, /* 108 (VK_SEPARATOR??) => 126 via 121 (KEY_KPCOMMA) */
+ [0x6d] = 0x4a, /* 109 (VK_SUBTRACT) => 74 via 74 (KEY_KPMINUS) */
+ [0x6e] = 0x53, /* 110 (VK_DECIMAL) => 83 via 83 (KEY_KPDOT) */
+ [0x6f] = 0x135, /* 111 (VK_DIVIDE) => 309 via 98 (KEY_KPSLASH) */
+ [0x70] = 0x3b, /* 112 (VK_F1) => 59 via 59 (KEY_F1) */
+ [0x71] = 0x3c, /* 113 (VK_F2) => 60 via 60 (KEY_F2) */
+ [0x72] = 0x3d, /* 114 (VK_F3) => 61 via 61 (KEY_F3) */
+ [0x73] = 0x3e, /* 115 (VK_F4) => 62 via 62 (KEY_F4) */
+ [0x74] = 0x3f, /* 116 (VK_F5) => 63 via 63 (KEY_F5) */
+ [0x75] = 0x40, /* 117 (VK_F6) => 64 via 64 (KEY_F6) */
+ [0x76] = 0x41, /* 118 (VK_F7) => 65 via 65 (KEY_F7) */
+ [0x77] = 0x42, /* 119 (VK_F8) => 66 via 66 (KEY_F8) */
+ [0x78] = 0x43, /* 120 (VK_F9) => 67 via 67 (KEY_F9) */
+ [0x79] = 0x44, /* 121 (VK_F10) => 68 via 68 (KEY_F10) */
+ [0x7a] = 0x57, /* 122 (VK_F11) => 87 via 87 (KEY_F11) */
+ [0x7b] = 0x58, /* 123 (VK_F12) => 88 via 88 (KEY_F12) */
+ [0x7c] = 0x5d, /* 124 (VK_F13) => 93 via 183 (KEY_F13) */
+ [0x7d] = 0x5e, /* 125 (VK_F14) => 94 via 184 (KEY_F14) */
+ [0x7e] = 0x5f, /* 126 (VK_F15) => 95 via 185 (KEY_F15) */
+ [0x7f] = 0x55, /* 127 (VK_F16) => 85 via 186 (KEY_F16) */
+ [0x80] = 0x103, /* 128 (VK_F17) => 259 via 187 (KEY_F17) */
+ [0x81] = 0x177, /* 129 (VK_F18) => 375 via 188 (KEY_F18) */
+ [0x82] = 0x104, /* 130 (VK_F19) => 260 via 189 (KEY_F19) */
+ [0x83] = 0x5a, /* 131 (VK_F20) => 90 via 190 (KEY_F20) */
+ [0x84] = 0x74, /* 132 (VK_F21) => 116 via 191 (KEY_F21) */
+ [0x85] = 0x179, /* 133 (VK_F22) => 377 via 192 (KEY_F22) */
+ [0x86] = 0x6d, /* 134 (VK_F23) => 109 via 193 (KEY_F23) */
+ [0x87] = 0x6f, /* 135 (VK_F24) => 111 via 194 (KEY_F24) */
+ [0x90] = 0x45, /* 144 (VK_NUMLOCK) => 69 via 69 (KEY_NUMLOCK) */
+ [0x91] = 0x46, /* 145 (VK_SCROLL) => 70 via 70 (KEY_SCROLLLOCK) */
+ [0xa0] = 0x2a, /* 160 (VK_LSHIFT) => 42 via 42 (KEY_LEFTSHIFT) */
+ [0xa1] = 0x36, /* 161 (VK_RSHIFT) => 54 via 54 (KEY_RIGHTSHIFT) */
+ [0xa2] = 0x1d, /* 162 (VK_CONTROL) => 29 via 29 (KEY_LEFTCTRL) */
+ [0xa3] = 0x11d, /* 163 (VK_RCONTROL) => 285 via 97 (KEY_RIGHTCTRL) */
+ [0xa4] = 0x38, /* 164 (VK_MENU) => 56 via 56 (KEY_LEFTALT) */
+ [0xa5] = 0x138, /* 165 (VK_RMENU) => 312 via 100 (KEY_RIGHTALT) */
+ [0xa6] = 0x16a, /* 166 (VK_BROWSER_BACK) => 362 via 158 (KEY_BACK) */
+ [0xa7] = 0x169, /* 167 (VK_BROWSER_FORWARD) => 361 via 159 (KEY_FORWARD) */
+ [0xa8] = 0x167, /* 168 (VK_BROWSER_REFRESH) => 359 via 173 (KEY_REFRESH) */
+ [0xa9] = 0x168, /* 169 (VK_BROWSER_STOP) => 360 via 128 (KEY_STOP) */
+ [0xaa] = 0x165, /* 170 (VK_BROWSER_SEARCH) => 357 via 217 (KEY_SEARCH) */
+ [0xac] = 0x132, /* 172 (VK_BROWSER_HOME) => 306 via 172 (KEY_HOMEPAGE) */
+ [0xad] = 0x120, /* 173 (VK_VOLUME_MUTE) => 288 via 113 (KEY_MUTE) */
+ [0xae] = 0x12e, /* 174 (VK_VOLUME_DOWN) => 302 via 114 (KEY_VOLUMEDOWN) */
+ [0xaf] = 0x130, /* 175 (VK_VOLUME_UP) => 304 via 115 (KEY_VOLUMEUP) */
+ [0xb0] = 0x119, /* 176 (VK_MEDIA_NEXT_TRACK) => 281 via 163 (KEY_NEXTSONG) */
+ [0xb1] = 0x110, /* 177 (VK_MEDIA_PREV_TRACK) => 272 via 165 (KEY_PREVIOUSSONG) */
+ [0xb2] = 0x124, /* 178 (VK_MEDIA_STOP) => 292 via 166 (KEY_STOPCD) */
+ [0xb3] = 0x122, /* 179 (VK_MEDIA_PLAY_PAUSE) => 290 via 164 (KEY_PLAYPAUSE) */
+ [0xb4] = 0x13f, /* 180 (VK_LAUNCH_MAIL) => 319 via 215 (KEY_EMAIL) */
+ [0xba] = 0x27, /* 186 (VK_OEM_1) => 39 via 39 (KEY_SEMICOLON) */
+ [0xbb] = 0xd, /* 187 (VK_OEM_PLUS) => 13 via 13 (KEY_EQUAL) */
+ [0xbc] = 0x33, /* 188 (VK_OEM_COMMA) => 51 via 51 (KEY_COMMA) */
+ [0xbd] = 0xc, /* 189 (VK_OEM_MINUS) => 12 via 12 (KEY_MINUS) */
+ [0xbe] = 0x34, /* 190 (VK_OEM_PERIOD) => 52 via 52 (KEY_DOT) */
+ [0xbf] = 0x35, /* 191 (VK_OEM_2) => 53 via 53 (KEY_SLASH) */
+ [0xc0] = 0x29, /* 192 (VK_OEM_3) => 41 via 41 (KEY_GRAVE) */
+ [0xdb] = 0x1a, /* 219 (VK_OEM_4) => 26 via 26 (KEY_LEFTBRACE) */
+ [0xdc] = 0x2b, /* 220 (VK_OEM_5) => 43 via 43 (KEY_BACKSLASH) */
+ [0xdd] = 0x1b, /* 221 (VK_OEM_6) => 27 via 27 (KEY_RIGHTBRACE) */
+ [0xde] = 0x28, /* 222 (VK_OEM_7) => 40 via 40 (KEY_APOSTROPHE) */
+ [0xe1] = 0x56, /* 225 (VK_OEM_102) => 86 via 86 (KEY_102ND) */
+ [0xfa] = 0x133, /* 250 (VK_PLAY) => 307 via 207 (KEY_PLAY) */
+};
--- /dev/null
+static const guint16 keymap_x112xtkbd[] = {
+ [0x20] = 0x39, /* 32 (XK_space) => 57 via 57 (KEY_SPACE) */
+ [0x27] = 0x28, /* 39 (XK_apostrophe) => 40 via 40 (KEY_APOSTROPHE) */
+ [0x2c] = 0x33, /* 44 (XK_comma) => 51 via 51 (KEY_COMMA) */
+ [0x2d] = 0xc, /* 45 (XK_minus) => 12 via 12 (KEY_MINUS) */
+ [0x2e] = 0x34, /* 46 (XK_period) => 52 via 52 (KEY_DOT) */
+ [0x2f] = 0x35, /* 47 (XK_slash) => 53 via 53 (KEY_SLASH) */
+ [0x30] = 0xb, /* 48 (XK_0) => 11 via 11 (KEY_0) */
+ [0x31] = 0x2, /* 49 (XK_1) => 2 via 2 (KEY_1) */
+ [0x32] = 0x3, /* 50 (XK_2) => 3 via 3 (KEY_2) */
+ [0x33] = 0x4, /* 51 (XK_3) => 4 via 4 (KEY_3) */
+ [0x34] = 0x5, /* 52 (XK_4) => 5 via 5 (KEY_4) */
+ [0x35] = 0x6, /* 53 (XK_5) => 6 via 6 (KEY_5) */
+ [0x36] = 0x7, /* 54 (XK_6) => 7 via 7 (KEY_6) */
+ [0x37] = 0x8, /* 55 (XK_7) => 8 via 8 (KEY_7) */
+ [0x38] = 0x9, /* 56 (XK_8) => 9 via 9 (KEY_8) */
+ [0x39] = 0xa, /* 57 (XK_9) => 10 via 10 (KEY_9) */
+ [0x3b] = 0x27, /* 59 (XK_semicolon) => 39 via 39 (KEY_SEMICOLON) */
+ [0x3d] = 0xd, /* 61 (XK_equal) => 13 via 13 (KEY_EQUAL) */
+ [0x41] = 0x1e, /* 65 (XK_a) => 30 via 30 (KEY_A) */
+ [0x42] = 0x30, /* 66 (XK_b) => 48 via 48 (KEY_B) */
+ [0x43] = 0x2e, /* 67 (XK_c) => 46 via 46 (KEY_C) */
+ [0x44] = 0x20, /* 68 (XK_d) => 32 via 32 (KEY_D) */
+ [0x45] = 0x12, /* 69 (XK_e) => 18 via 18 (KEY_E) */
+ [0x46] = 0x21, /* 70 (XK_f) => 33 via 33 (KEY_F) */
+ [0x47] = 0x22, /* 71 (XK_g) => 34 via 34 (KEY_G) */
+ [0x48] = 0x23, /* 72 (XK_h) => 35 via 35 (KEY_H) */
+ [0x49] = 0x17, /* 73 (XK_i) => 23 via 23 (KEY_I) */
+ [0x4a] = 0x24, /* 74 (XK_j) => 36 via 36 (KEY_J) */
+ [0x4b] = 0x25, /* 75 (XK_K) => 37 via 37 (KEY_K) */
+ [0x4c] = 0x26, /* 76 (XK_l) => 38 via 38 (KEY_L) */
+ [0x4d] = 0x32, /* 77 (XK_m) => 50 via 50 (KEY_M) */
+ [0x4e] = 0x31, /* 78 (XK_n) => 49 via 49 (KEY_N) */
+ [0x4f] = 0x18, /* 79 (XK_o) => 24 via 24 (KEY_O) */
+ [0x50] = 0x19, /* 80 (XK_p) => 25 via 25 (KEY_P) */
+ [0x51] = 0x10, /* 81 (XK_q) => 16 via 16 (KEY_Q) */
+ [0x52] = 0x13, /* 82 (XK_r) => 19 via 19 (KEY_R) */
+ [0x53] = 0x1f, /* 83 (XK_s) => 31 via 31 (KEY_S) */
+ [0x54] = 0x14, /* 84 (XK_t) => 20 via 20 (KEY_T) */
+ [0x55] = 0x16, /* 85 (XK_u) => 22 via 22 (KEY_U) */
+ [0x56] = 0x2f, /* 86 (XK_v) => 47 via 47 (KEY_V) */
+ [0x57] = 0x11, /* 87 (XK_w) => 17 via 17 (KEY_W) */
+ [0x58] = 0x2d, /* 88 (XK_x) => 45 via 45 (KEY_X) */
+ [0x59] = 0x15, /* 89 (XK_y) => 21 via 21 (KEY_Y) */
+ [0x5a] = 0x2c, /* 90 (XK_z) => 44 via 44 (KEY_Z) */
+ [0x5b] = 0x1a, /* 91 (XK_bracketleft) => 26 via 26 (KEY_LEFTBRACE) */
+ [0x5c] = 0x2b, /* 92 (XK_backslash) => 43 via 43 (KEY_BACKSLASH) */
+ [0x5d] = 0x1b, /* 93 (XK_bracketright) => 27 via 27 (KEY_RIGHTBRACE) */
+ [0x60] = 0x29, /* 96 (XK_grave) => 41 via 41 (KEY_GRAVE) */
+ [0x61] = 0x1e, /* 97 (XK_a) => 30 via 30 (KEY_A) */
+ [0x62] = 0x30, /* 98 (XK_b) => 48 via 48 (KEY_B) */
+ [0x63] = 0x2e, /* 99 (XK_c) => 46 via 46 (KEY_C) */
+ [0x64] = 0x20, /* 100 (XK_d) => 32 via 32 (KEY_D) */
+ [0x65] = 0x12, /* 101 (XK_e) => 18 via 18 (KEY_E) */
+ [0x66] = 0x21, /* 102 (XK_f) => 33 via 33 (KEY_F) */
+ [0x67] = 0x22, /* 103 (XK_g) => 34 via 34 (KEY_G) */
+ [0x68] = 0x23, /* 104 (XK_h) => 35 via 35 (KEY_H) */
+ [0x69] = 0x17, /* 105 (XK_i) => 23 via 23 (KEY_I) */
+ [0x6a] = 0x24, /* 106 (XK_j) => 36 via 36 (KEY_J) */
+ [0x6b] = 0x25, /* 107 (XK_K) => 37 via 37 (KEY_K) */
+ [0x6c] = 0x26, /* 108 (XK_l) => 38 via 38 (KEY_L) */
+ [0x6d] = 0x32, /* 109 (XK_m) => 50 via 50 (KEY_M) */
+ [0x6e] = 0x31, /* 110 (XK_n) => 49 via 49 (KEY_N) */
+ [0x6f] = 0x18, /* 111 (XK_o) => 24 via 24 (KEY_O) */
+ [0x70] = 0x19, /* 112 (XK_p) => 25 via 25 (KEY_P) */
+ [0x71] = 0x10, /* 113 (XK_q) => 16 via 16 (KEY_Q) */
+ [0x72] = 0x13, /* 114 (XK_r) => 19 via 19 (KEY_R) */
+ [0x73] = 0x1f, /* 115 (XK_s) => 31 via 31 (KEY_S) */
+ [0x74] = 0x14, /* 116 (XK_t) => 20 via 20 (KEY_T) */
+ [0x75] = 0x16, /* 117 (XK_u) => 22 via 22 (KEY_U) */
+ [0x76] = 0x2f, /* 118 (XK_v) => 47 via 47 (KEY_V) */
+ [0x77] = 0x11, /* 119 (XK_w) => 17 via 17 (KEY_W) */
+ [0x78] = 0x2d, /* 120 (XK_x) => 45 via 45 (KEY_X) */
+ [0x79] = 0x15, /* 121 (XK_y) => 21 via 21 (KEY_Y) */
+ [0x7a] = 0x2c, /* 122 (XK_z) => 44 via 44 (KEY_Z) */
+ [0xd7] = 0x37, /* 215 (XK_multiply) => 55 via 55 (KEY_KPASTERISK) */
+ [0xff08] = 0xe, /* 65288 (XK_BackSpace) => 14 via 14 (KEY_BACKSPACE) */
+ [0xff09] = 0xf, /* 65289 (XK_Tab) => 15 via 15 (KEY_TAB) */
+ [0xff0d] = 0x1c, /* 65293 (XK_Return) => 28 via 28 (KEY_ENTER) */
+ [0xff13] = 0x146, /* 65299 (XK_Pause) => 326 via 119 (KEY_PAUSE) */
+ [0xff14] = 0x46, /* 65300 (XK_Scroll_Lock) => 70 via 70 (KEY_SCROLLLOCK) */
+ [0xff15] = 0x54, /* 65301 (XK_Sys_Req) => 84 via 99 (KEY_SYSRQ) */
+ [0xff1b] = 0x1, /* 65307 (XK_Escape) => 1 via 1 (KEY_ESC) */
+ [0xff50] = 0x147, /* 65360 (XK_Home) => 327 via 102 (KEY_HOME) */
+ [0xff51] = 0x14b, /* 65361 (XK_Left) => 331 via 105 (KEY_LEFT) */
+ [0xff52] = 0x148, /* 65362 (XK_Up) => 328 via 103 (KEY_UP) */
+ [0xff53] = 0x14d, /* 65363 (XK_Right) => 333 via 106 (KEY_RIGHT) */
+ [0xff54] = 0x150, /* 65364 (XK_Down) => 336 via 108 (KEY_DOWN) */
+ [0xff55] = 0x149, /* 65365 (XK_Page_Up) => 329 via 104 (KEY_PAGEUP) */
+ [0xff56] = 0x151, /* 65366 (XK_Page_Down) => 337 via 109 (KEY_PAGEDOWN) */
+ [0xff57] = 0x14f, /* 65367 (XK_End) => 335 via 107 (KEY_END) */
+ [0xff63] = 0x152, /* 65379 (XK_Insert) => 338 via 110 (KEY_INSERT) */
+ [0xff6a] = 0x175, /* 65386 (XK_Help) => 373 via 138 (KEY_HELP) */
+ [0xff7f] = 0x45, /* 65407 (XK_Num_Lock) => 69 via 69 (KEY_NUMLOCK) */
+ [0xff8d] = 0x11c, /* 65421 (XK_KP_Enter) => 284 via 96 (KEY_KPENTER) */
+ [0xffab] = 0x4e, /* 65451 (XK_KP_Add) => 78 via 78 (KEY_KPPLUS) */
+ [0xffac] = 0x5c, /* 65452 (XK_KP_Separator) => 92 via 95 (KEY_KPJPCOMMA) */
+ [0xffad] = 0x4a, /* 65453 (XK_KP_Subtract) => 74 via 74 (KEY_KPMINUS) */
+ [0xffae] = 0x53, /* 65454 (XK_KP_Decimal) => 83 via 83 (KEY_KPDOT) */
+ [0xffaf] = 0x135, /* 65455 (XK_KP_Divide) => 309 via 98 (KEY_KPSLASH) */
+ [0xffb0] = 0x52, /* 65456 (XK_KP_0) => 82 via 82 (KEY_KP0) */
+ [0xffb1] = 0x4f, /* 65457 (XK_KP_1) => 79 via 79 (KEY_KP1) */
+ [0xffb2] = 0x50, /* 65458 (XK_KP_2) => 80 via 80 (KEY_KP2) */
+ [0xffb3] = 0x51, /* 65459 (XK_KP_3) => 81 via 81 (KEY_KP3) */
+ [0xffb4] = 0x4b, /* 65460 (XK_KP_4) => 75 via 75 (KEY_KP4) */
+ [0xffb5] = 0x4c, /* 65461 (XK_KP_5) => 76 via 76 (KEY_KP5) */
+ [0xffb6] = 0x4d, /* 65462 (XK_KP_6) => 77 via 77 (KEY_KP6) */
+ [0xffb7] = 0x47, /* 65463 (XK_KP_7) => 71 via 71 (KEY_KP7) */
+ [0xffb8] = 0x48, /* 65464 (XK_KP_8) => 72 via 72 (KEY_KP8) */
+ [0xffb9] = 0x49, /* 65465 (XK_KP_9) => 73 via 73 (KEY_KP9) */
+ [0xffbd] = 0x59, /* 65469 (XK_KP_Equal) => 89 via 117 (KEY_KPEQUAL) */
+ [0xffbe] = 0x3b, /* 65470 (XK_F1) => 59 via 59 (KEY_F1) */
+ [0xffbf] = 0x3c, /* 65471 (XK_F2) => 60 via 60 (KEY_F2) */
+ [0xffc0] = 0x3d, /* 65472 (XK_F3) => 61 via 61 (KEY_F3) */
+ [0xffc1] = 0x3e, /* 65473 (XK_F4) => 62 via 62 (KEY_F4) */
+ [0xffc2] = 0x3f, /* 65474 (XK_F5) => 63 via 63 (KEY_F5) */
+ [0xffc3] = 0x40, /* 65475 (XK_F6) => 64 via 64 (KEY_F6) */
+ [0xffc4] = 0x41, /* 65476 (XK_F7) => 65 via 65 (KEY_F7) */
+ [0xffc5] = 0x42, /* 65477 (XK_F8) => 66 via 66 (KEY_F8) */
+ [0xffc6] = 0x43, /* 65478 (XK_F9) => 67 via 67 (KEY_F9) */
+ [0xffc7] = 0x44, /* 65479 (XK_F10) => 68 via 68 (KEY_F10) */
+ [0xffe1] = 0x2a, /* 65505 (XK_Shift_L) => 42 via 42 (KEY_LEFTSHIFT) */
+ [0xffe2] = 0x36, /* 65506 (XK_Shift_R) => 54 via 54 (KEY_RIGHTSHIFT) */
+ [0xffe3] = 0x1d, /* 65507 (XK_Control_L) => 29 via 29 (KEY_LEFTCTRL) */
+ [0xffe4] = 0x11d, /* 65508 (XK_Control_R) => 285 via 97 (KEY_RIGHTCTRL) */
+ [0xffe5] = 0x3a, /* 65509 (XK_Caps_Lock) => 58 via 58 (KEY_CAPSLOCK) */
+ [0xffe7] = 0x15b, /* 65511 (XK_Meta_L) => 347 via 125 (KEY_LEFTMETA) */
+ [0xffe8] = 0x15c, /* 65512 (XK_Meta_R) => 348 via 126 (KEY_RIGHTMETA) */
+ [0xffe9] = 0x38, /* 65513 (XK_Alt_L) => 56 via 56 (KEY_LEFTALT) */
+ [0xffea] = 0x138, /* 65514 (XK_Alt_R) => 312 via 100 (KEY_RIGHTALT) */
+ [0xffff] = 0x153, /* 65535 (XK_Delete) => 339 via 111 (KEY_DELETE) */
+};
--- /dev/null
+static const guint16 keymap_xorgevdev2xtkbd[] = {
+ [0x9] = 0x1, /* 9 => 1 via 1 (KEY_ESC) */
+ [0xa] = 0x2, /* 10 => 2 via 2 (KEY_1) */
+ [0xb] = 0x3, /* 11 => 3 via 3 (KEY_2) */
+ [0xc] = 0x4, /* 12 => 4 via 4 (KEY_3) */
+ [0xd] = 0x5, /* 13 => 5 via 5 (KEY_4) */
+ [0xe] = 0x6, /* 14 => 6 via 6 (KEY_5) */
+ [0xf] = 0x7, /* 15 => 7 via 7 (KEY_6) */
+ [0x10] = 0x8, /* 16 => 8 via 8 (KEY_7) */
+ [0x11] = 0x9, /* 17 => 9 via 9 (KEY_8) */
+ [0x12] = 0xa, /* 18 => 10 via 10 (KEY_9) */
+ [0x13] = 0xb, /* 19 => 11 via 11 (KEY_0) */
+ [0x14] = 0xc, /* 20 => 12 via 12 (KEY_MINUS) */
+ [0x15] = 0xd, /* 21 => 13 via 13 (KEY_EQUAL) */
+ [0x16] = 0xe, /* 22 => 14 via 14 (KEY_BACKSPACE) */
+ [0x17] = 0xf, /* 23 => 15 via 15 (KEY_TAB) */
+ [0x18] = 0x10, /* 24 => 16 via 16 (KEY_Q) */
+ [0x19] = 0x11, /* 25 => 17 via 17 (KEY_W) */
+ [0x1a] = 0x12, /* 26 => 18 via 18 (KEY_E) */
+ [0x1b] = 0x13, /* 27 => 19 via 19 (KEY_R) */
+ [0x1c] = 0x14, /* 28 => 20 via 20 (KEY_T) */
+ [0x1d] = 0x15, /* 29 => 21 via 21 (KEY_Y) */
+ [0x1e] = 0x16, /* 30 => 22 via 22 (KEY_U) */
+ [0x1f] = 0x17, /* 31 => 23 via 23 (KEY_I) */
+ [0x20] = 0x18, /* 32 => 24 via 24 (KEY_O) */
+ [0x21] = 0x19, /* 33 => 25 via 25 (KEY_P) */
+ [0x22] = 0x1a, /* 34 => 26 via 26 (KEY_LEFTBRACE) */
+ [0x23] = 0x1b, /* 35 => 27 via 27 (KEY_RIGHTBRACE) */
+ [0x24] = 0x1c, /* 36 => 28 via 28 (KEY_ENTER) */
+ [0x25] = 0x1d, /* 37 => 29 via 29 (KEY_LEFTCTRL) */
+ [0x26] = 0x1e, /* 38 => 30 via 30 (KEY_A) */
+ [0x27] = 0x1f, /* 39 => 31 via 31 (KEY_S) */
+ [0x28] = 0x20, /* 40 => 32 via 32 (KEY_D) */
+ [0x29] = 0x21, /* 41 => 33 via 33 (KEY_F) */
+ [0x2a] = 0x22, /* 42 => 34 via 34 (KEY_G) */
+ [0x2b] = 0x23, /* 43 => 35 via 35 (KEY_H) */
+ [0x2c] = 0x24, /* 44 => 36 via 36 (KEY_J) */
+ [0x2d] = 0x25, /* 45 => 37 via 37 (KEY_K) */
+ [0x2e] = 0x26, /* 46 => 38 via 38 (KEY_L) */
+ [0x2f] = 0x27, /* 47 => 39 via 39 (KEY_SEMICOLON) */
+ [0x30] = 0x28, /* 48 => 40 via 40 (KEY_APOSTROPHE) */
+ [0x31] = 0x29, /* 49 => 41 via 41 (KEY_GRAVE) */
+ [0x32] = 0x2a, /* 50 => 42 via 42 (KEY_LEFTSHIFT) */
+ [0x33] = 0x2b, /* 51 => 43 via 43 (KEY_BACKSLASH) */
+ [0x34] = 0x2c, /* 52 => 44 via 44 (KEY_Z) */
+ [0x35] = 0x2d, /* 53 => 45 via 45 (KEY_X) */
+ [0x36] = 0x2e, /* 54 => 46 via 46 (KEY_C) */
+ [0x37] = 0x2f, /* 55 => 47 via 47 (KEY_V) */
+ [0x38] = 0x30, /* 56 => 48 via 48 (KEY_B) */
+ [0x39] = 0x31, /* 57 => 49 via 49 (KEY_N) */
+ [0x3a] = 0x32, /* 58 => 50 via 50 (KEY_M) */
+ [0x3b] = 0x33, /* 59 => 51 via 51 (KEY_COMMA) */
+ [0x3c] = 0x34, /* 60 => 52 via 52 (KEY_DOT) */
+ [0x3d] = 0x35, /* 61 => 53 via 53 (KEY_SLASH) */
+ [0x3e] = 0x36, /* 62 => 54 via 54 (KEY_RIGHTSHIFT) */
+ [0x3f] = 0x37, /* 63 => 55 via 55 (KEY_KPASTERISK) */
+ [0x40] = 0x38, /* 64 => 56 via 56 (KEY_LEFTALT) */
+ [0x41] = 0x39, /* 65 => 57 via 57 (KEY_SPACE) */
+ [0x42] = 0x3a, /* 66 => 58 via 58 (KEY_CAPSLOCK) */
+ [0x43] = 0x3b, /* 67 => 59 via 59 (KEY_F1) */
+ [0x44] = 0x3c, /* 68 => 60 via 60 (KEY_F2) */
+ [0x45] = 0x3d, /* 69 => 61 via 61 (KEY_F3) */
+ [0x46] = 0x3e, /* 70 => 62 via 62 (KEY_F4) */
+ [0x47] = 0x3f, /* 71 => 63 via 63 (KEY_F5) */
+ [0x48] = 0x40, /* 72 => 64 via 64 (KEY_F6) */
+ [0x49] = 0x41, /* 73 => 65 via 65 (KEY_F7) */
+ [0x4a] = 0x42, /* 74 => 66 via 66 (KEY_F8) */
+ [0x4b] = 0x43, /* 75 => 67 via 67 (KEY_F9) */
+ [0x4c] = 0x44, /* 76 => 68 via 68 (KEY_F10) */
+ [0x4d] = 0x45, /* 77 => 69 via 69 (KEY_NUMLOCK) */
+ [0x4e] = 0x46, /* 78 => 70 via 70 (KEY_SCROLLLOCK) */
+ [0x4f] = 0x47, /* 79 => 71 via 71 (KEY_KP7) */
+ [0x50] = 0x48, /* 80 => 72 via 72 (KEY_KP8) */
+ [0x51] = 0x49, /* 81 => 73 via 73 (KEY_KP9) */
+ [0x52] = 0x4a, /* 82 => 74 via 74 (KEY_KPMINUS) */
+ [0x53] = 0x4b, /* 83 => 75 via 75 (KEY_KP4) */
+ [0x54] = 0x4c, /* 84 => 76 via 76 (KEY_KP5) */
+ [0x55] = 0x4d, /* 85 => 77 via 77 (KEY_KP6) */
+ [0x56] = 0x4e, /* 86 => 78 via 78 (KEY_KPPLUS) */
+ [0x57] = 0x4f, /* 87 => 79 via 79 (KEY_KP1) */
+ [0x58] = 0x50, /* 88 => 80 via 80 (KEY_KP2) */
+ [0x59] = 0x51, /* 89 => 81 via 81 (KEY_KP3) */
+ [0x5a] = 0x52, /* 90 => 82 via 82 (KEY_KP0) */
+ [0x5b] = 0x53, /* 91 => 83 via 83 (KEY_KPDOT) */
+ [0x5c] = 0x54, /* 92 => 84 via 84 */
+ [0x5d] = 0x76, /* 93 => 118 via 85 (KEY_ZENKAKUHANKAKU) */
+ [0x5e] = 0x56, /* 94 => 86 via 86 (KEY_102ND) */
+ [0x5f] = 0x57, /* 95 => 87 via 87 (KEY_F11) */
+ [0x60] = 0x58, /* 96 => 88 via 88 (KEY_F12) */
+ [0x61] = 0x73, /* 97 => 115 via 89 (KEY_RO) */
+ [0x62] = 0x78, /* 98 => 120 via 90 (KEY_KATAKANA) */
+ [0x63] = 0x77, /* 99 => 119 via 91 (KEY_HIRAGANA) */
+ [0x64] = 0x79, /* 100 => 121 via 92 (KEY_HENKAN) */
+ [0x65] = 0x70, /* 101 => 112 via 93 (KEY_KATAKANAHIRAGANA) */
+ [0x66] = 0x7b, /* 102 => 123 via 94 (KEY_MUHENKAN) */
+ [0x67] = 0x5c, /* 103 => 92 via 95 (KEY_KPJPCOMMA) */
+ [0x68] = 0x11c, /* 104 => 284 via 96 (KEY_KPENTER) */
+ [0x69] = 0x11d, /* 105 => 285 via 97 (KEY_RIGHTCTRL) */
+ [0x6a] = 0x135, /* 106 => 309 via 98 (KEY_KPSLASH) */
+ [0x6b] = 0x54, /* 107 => 84 via 99 (KEY_SYSRQ) */
+ [0x6c] = 0x138, /* 108 => 312 via 100 (KEY_RIGHTALT) */
+ [0x6d] = 0x5b, /* 109 => 91 via 101 (KEY_LINEFEED) */
+ [0x6e] = 0x147, /* 110 => 327 via 102 (KEY_HOME) */
+ [0x6f] = 0x148, /* 111 => 328 via 103 (KEY_UP) */
+ [0x70] = 0x149, /* 112 => 329 via 104 (KEY_PAGEUP) */
+ [0x71] = 0x14b, /* 113 => 331 via 105 (KEY_LEFT) */
+ [0x72] = 0x14d, /* 114 => 333 via 106 (KEY_RIGHT) */
+ [0x73] = 0x14f, /* 115 => 335 via 107 (KEY_END) */
+ [0x74] = 0x150, /* 116 => 336 via 108 (KEY_DOWN) */
+ [0x75] = 0x151, /* 117 => 337 via 109 (KEY_PAGEDOWN) */
+ [0x76] = 0x152, /* 118 => 338 via 110 (KEY_INSERT) */
+ [0x77] = 0x153, /* 119 => 339 via 111 (KEY_DELETE) */
+ [0x78] = 0x16f, /* 120 => 367 via 112 (KEY_MACRO) */
+ [0x79] = 0x120, /* 121 => 288 via 113 (KEY_MUTE) */
+ [0x7a] = 0x12e, /* 122 => 302 via 114 (KEY_VOLUMEDOWN) */
+ [0x7b] = 0x130, /* 123 => 304 via 115 (KEY_VOLUMEUP) */
+ [0x7c] = 0x15e, /* 124 => 350 via 116 (KEY_POWER) */
+ [0x7d] = 0x59, /* 125 => 89 via 117 (KEY_KPEQUAL) */
+ [0x7e] = 0x14e, /* 126 => 334 via 118 (KEY_KPPLUSMINUS) */
+ [0x7f] = 0x146, /* 127 => 326 via 119 (KEY_PAUSE) */
+ [0x80] = 0x10b, /* 128 => 267 via 120 (KEY_SCALE) */
+ [0x81] = 0x7e, /* 129 => 126 via 121 (KEY_KPCOMMA) */
+ [0x83] = 0x10d, /* 131 => 269 via 123 (KEY_HANJA) */
+ [0x84] = 0x7d, /* 132 => 125 via 124 (KEY_YEN) */
+ [0x85] = 0x15b, /* 133 => 347 via 125 (KEY_LEFTMETA) */
+ [0x86] = 0x15c, /* 134 => 348 via 126 (KEY_RIGHTMETA) */
+ [0x87] = 0x15d, /* 135 => 349 via 127 (KEY_COMPOSE) */
+ [0x88] = 0x168, /* 136 => 360 via 128 (KEY_STOP) */
+ [0x89] = 0x105, /* 137 => 261 via 129 (KEY_AGAIN) */
+ [0x8a] = 0x106, /* 138 => 262 via 130 (KEY_PROPS) */
+ [0x8b] = 0x107, /* 139 => 263 via 131 (KEY_UNDO) */
+ [0x8c] = 0x10c, /* 140 => 268 via 132 (KEY_FRONT) */
+ [0x8d] = 0x178, /* 141 => 376 via 133 (KEY_COPY) */
+ [0x8e] = 0x64, /* 142 => 100 via 134 (KEY_OPEN) */
+ [0x8f] = 0x65, /* 143 => 101 via 135 (KEY_PASTE) */
+ [0x90] = 0x141, /* 144 => 321 via 136 (KEY_FIND) */
+ [0x91] = 0x13c, /* 145 => 316 via 137 (KEY_CUT) */
+ [0x92] = 0x175, /* 146 => 373 via 138 (KEY_HELP) */
+ [0x93] = 0x11e, /* 147 => 286 via 139 (KEY_MENU) */
+ [0x94] = 0x121, /* 148 => 289 via 140 (KEY_CALC) */
+ [0x95] = 0x66, /* 149 => 102 via 141 (KEY_SETUP) */
+ [0x96] = 0x15f, /* 150 => 351 via 142 (KEY_SLEEP) */
+ [0x97] = 0x163, /* 151 => 355 via 143 (KEY_WAKEUP) */
+ [0x98] = 0x67, /* 152 => 103 via 144 (KEY_FILE) */
+ [0x99] = 0x68, /* 153 => 104 via 145 (KEY_SENDFILE) */
+ [0x9a] = 0x69, /* 154 => 105 via 146 (KEY_DELETEFILE) */
+ [0x9b] = 0x113, /* 155 => 275 via 147 (KEY_XFER) */
+ [0x9c] = 0x11f, /* 156 => 287 via 148 (KEY_PROG1) */
+ [0x9d] = 0x117, /* 157 => 279 via 149 (KEY_PROG2) */
+ [0x9e] = 0x102, /* 158 => 258 via 150 (KEY_WWW) */
+ [0x9f] = 0x6a, /* 159 => 106 via 151 (KEY_MSDOS) */
+ [0xa0] = 0x112, /* 160 => 274 via 152 (KEY_SCREENLOCK) */
+ [0xa1] = 0x6b, /* 161 => 107 via 153 (KEY_DIRECTION) */
+ [0xa2] = 0x126, /* 162 => 294 via 154 (KEY_CYCLEWINDOWS) */
+ [0xa3] = 0x16c, /* 163 => 364 via 155 (KEY_MAIL) */
+ [0xa4] = 0x166, /* 164 => 358 via 156 (KEY_BOOKMARKS) */
+ [0xa5] = 0x16b, /* 165 => 363 via 157 (KEY_COMPUTER) */
+ [0xa6] = 0x16a, /* 166 => 362 via 158 (KEY_BACK) */
+ [0xa7] = 0x169, /* 167 => 361 via 159 (KEY_FORWARD) */
+ [0xa8] = 0x123, /* 168 => 291 via 160 (KEY_CLOSECD) */
+ [0xa9] = 0x6c, /* 169 => 108 via 161 (KEY_EJECTCD) */
+ [0xaa] = 0x17d, /* 170 => 381 via 162 (KEY_EJECTCLOSECD) */
+ [0xab] = 0x119, /* 171 => 281 via 163 (KEY_NEXTSONG) */
+ [0xac] = 0x122, /* 172 => 290 via 164 (KEY_PLAYPAUSE) */
+ [0xad] = 0x110, /* 173 => 272 via 165 (KEY_PREVIOUSSONG) */
+ [0xae] = 0x124, /* 174 => 292 via 166 (KEY_STOPCD) */
+ [0xaf] = 0x131, /* 175 => 305 via 167 (KEY_RECORD) */
+ [0xb0] = 0x118, /* 176 => 280 via 168 (KEY_REWIND) */
+ [0xb1] = 0x63, /* 177 => 99 via 169 (KEY_PHONE) */
+ [0xb2] = 0x70, /* 178 => 112 via 170 (KEY_ISO) */
+ [0xb3] = 0x101, /* 179 => 257 via 171 (KEY_CONFIG) */
+ [0xb4] = 0x132, /* 180 => 306 via 172 (KEY_HOMEPAGE) */
+ [0xb5] = 0x167, /* 181 => 359 via 173 (KEY_REFRESH) */
+ [0xb6] = 0x71, /* 182 => 113 via 174 (KEY_EXIT) */
+ [0xb7] = 0x72, /* 183 => 114 via 175 (KEY_MOVE) */
+ [0xb8] = 0x108, /* 184 => 264 via 176 (KEY_EDIT) */
+ [0xb9] = 0x75, /* 185 => 117 via 177 (KEY_SCROLLUP) */
+ [0xba] = 0x10f, /* 186 => 271 via 178 (KEY_SCROLLDOWN) */
+ [0xbb] = 0x176, /* 187 => 374 via 179 (KEY_KPLEFTPAREN) */
+ [0xbc] = 0x17b, /* 188 => 379 via 180 (KEY_KPRIGHTPAREN) */
+ [0xbd] = 0x109, /* 189 => 265 via 181 (KEY_NEW) */
+ [0xbe] = 0x10a, /* 190 => 266 via 182 (KEY_REDO) */
+ [0xbf] = 0x5d, /* 191 => 93 via 183 (KEY_F13) */
+ [0xc0] = 0x5e, /* 192 => 94 via 184 (KEY_F14) */
+ [0xc1] = 0x5f, /* 193 => 95 via 185 (KEY_F15) */
+ [0xc2] = 0x55, /* 194 => 85 via 186 (KEY_F16) */
+ [0xc3] = 0x103, /* 195 => 259 via 187 (KEY_F17) */
+ [0xc4] = 0x177, /* 196 => 375 via 188 (KEY_F18) */
+ [0xc5] = 0x104, /* 197 => 260 via 189 (KEY_F19) */
+ [0xc6] = 0x5a, /* 198 => 90 via 190 (KEY_F20) */
+ [0xc7] = 0x74, /* 199 => 116 via 191 (KEY_F21) */
+ [0xc8] = 0x179, /* 200 => 377 via 192 (KEY_F22) */
+ [0xc9] = 0x6d, /* 201 => 109 via 193 (KEY_F23) */
+ [0xca] = 0x6f, /* 202 => 111 via 194 (KEY_F24) */
+ [0xcb] = 0x115, /* 203 => 277 via 195 */
+ [0xcc] = 0x116, /* 204 => 278 via 196 */
+ [0xcd] = 0x11a, /* 205 => 282 via 197 */
+ [0xce] = 0x11b, /* 206 => 283 via 198 */
+ [0xcf] = 0x127, /* 207 => 295 via 199 */
+ [0xd0] = 0x128, /* 208 => 296 via 200 (KEY_PLAYCD) */
+ [0xd1] = 0x129, /* 209 => 297 via 201 (KEY_PAUSECD) */
+ [0xd2] = 0x12b, /* 210 => 299 via 202 (KEY_PROG3) */
+ [0xd3] = 0x12c, /* 211 => 300 via 203 (KEY_PROG4) */
+ [0xd4] = 0x12d, /* 212 => 301 via 204 (KEY_DASHBOARD) */
+ [0xd5] = 0x125, /* 213 => 293 via 205 (KEY_SUSPEND) */
+ [0xd6] = 0x12f, /* 214 => 303 via 206 (KEY_CLOSE) */
+ [0xd7] = 0x133, /* 215 => 307 via 207 (KEY_PLAY) */
+ [0xd8] = 0x134, /* 216 => 308 via 208 (KEY_FASTFORWARD) */
+ [0xd9] = 0x136, /* 217 => 310 via 209 (KEY_BASSBOOST) */
+ [0xda] = 0x139, /* 218 => 313 via 210 (KEY_PRINT) */
+ [0xdb] = 0x13a, /* 219 => 314 via 211 (KEY_HP) */
+ [0xdc] = 0x13b, /* 220 => 315 via 212 (KEY_CAMERA) */
+ [0xdd] = 0x13d, /* 221 => 317 via 213 (KEY_SOUND) */
+ [0xde] = 0x13e, /* 222 => 318 via 214 (KEY_QUESTION) */
+ [0xdf] = 0x13f, /* 223 => 319 via 215 (KEY_EMAIL) */
+ [0xe0] = 0x140, /* 224 => 320 via 216 (KEY_CHAT) */
+ [0xe1] = 0x165, /* 225 => 357 via 217 (KEY_SEARCH) */
+ [0xe2] = 0x142, /* 226 => 322 via 218 (KEY_CONNECT) */
+ [0xe3] = 0x143, /* 227 => 323 via 219 (KEY_FINANCE) */
+ [0xe4] = 0x144, /* 228 => 324 via 220 (KEY_SPORT) */
+ [0xe5] = 0x145, /* 229 => 325 via 221 (KEY_SHOP) */
+ [0xe6] = 0x114, /* 230 => 276 via 222 (KEY_ALTERASE) */
+ [0xe7] = 0x14a, /* 231 => 330 via 223 (KEY_CANCEL) */
+ [0xe8] = 0x14c, /* 232 => 332 via 224 (KEY_BRIGHTNESSDOWN) */
+ [0xe9] = 0x154, /* 233 => 340 via 225 (KEY_BRIGHTNESSUP) */
+ [0xea] = 0x16d, /* 234 => 365 via 226 (KEY_MEDIA) */
+ [0xeb] = 0x156, /* 235 => 342 via 227 (KEY_SWITCHVIDEOMODE) */
+ [0xec] = 0x157, /* 236 => 343 via 228 (KEY_KBDILLUMTOGGLE) */
+ [0xed] = 0x158, /* 237 => 344 via 229 (KEY_KBDILLUMDOWN) */
+ [0xee] = 0x159, /* 238 => 345 via 230 (KEY_KBDILLUMUP) */
+ [0xef] = 0x15a, /* 239 => 346 via 231 (KEY_SEND) */
+ [0xf0] = 0x164, /* 240 => 356 via 232 (KEY_REPLY) */
+ [0xf1] = 0x10e, /* 241 => 270 via 233 (KEY_FORWARDMAIL) */
+ [0xf2] = 0x155, /* 242 => 341 via 234 (KEY_SAVE) */
+ [0xf3] = 0x170, /* 243 => 368 via 235 (KEY_DOCUMENTS) */
+ [0xf4] = 0x171, /* 244 => 369 via 236 (KEY_BATTERY) */
+ [0xf5] = 0x172, /* 245 => 370 via 237 (KEY_BLUETOOTH) */
+ [0xf6] = 0x173, /* 246 => 371 via 238 (KEY_WLAN) */
+ [0xf7] = 0x174, /* 247 => 372 via 239 (KEY_UWB) */
+};
--- /dev/null
+static const guint16 keymap_xorgkbd2xtkbd[] = {
+ [0x9] = 0x1, /* 9 => 1 via 1 (KEY_ESC) */
+ [0xa] = 0x2, /* 10 => 2 via 2 (KEY_1) */
+ [0xb] = 0x3, /* 11 => 3 via 3 (KEY_2) */
+ [0xc] = 0x4, /* 12 => 4 via 4 (KEY_3) */
+ [0xd] = 0x5, /* 13 => 5 via 5 (KEY_4) */
+ [0xe] = 0x6, /* 14 => 6 via 6 (KEY_5) */
+ [0xf] = 0x7, /* 15 => 7 via 7 (KEY_6) */
+ [0x10] = 0x8, /* 16 => 8 via 8 (KEY_7) */
+ [0x11] = 0x9, /* 17 => 9 via 9 (KEY_8) */
+ [0x12] = 0xa, /* 18 => 10 via 10 (KEY_9) */
+ [0x13] = 0xb, /* 19 => 11 via 11 (KEY_0) */
+ [0x14] = 0xc, /* 20 => 12 via 12 (KEY_MINUS) */
+ [0x15] = 0xd, /* 21 => 13 via 13 (KEY_EQUAL) */
+ [0x16] = 0xe, /* 22 => 14 via 14 (KEY_BACKSPACE) */
+ [0x17] = 0xf, /* 23 => 15 via 15 (KEY_TAB) */
+ [0x18] = 0x10, /* 24 => 16 via 16 (KEY_Q) */
+ [0x19] = 0x11, /* 25 => 17 via 17 (KEY_W) */
+ [0x1a] = 0x12, /* 26 => 18 via 18 (KEY_E) */
+ [0x1b] = 0x13, /* 27 => 19 via 19 (KEY_R) */
+ [0x1c] = 0x14, /* 28 => 20 via 20 (KEY_T) */
+ [0x1d] = 0x15, /* 29 => 21 via 21 (KEY_Y) */
+ [0x1e] = 0x16, /* 30 => 22 via 22 (KEY_U) */
+ [0x1f] = 0x17, /* 31 => 23 via 23 (KEY_I) */
+ [0x20] = 0x18, /* 32 => 24 via 24 (KEY_O) */
+ [0x21] = 0x19, /* 33 => 25 via 25 (KEY_P) */
+ [0x22] = 0x1a, /* 34 => 26 via 26 (KEY_LEFTBRACE) */
+ [0x23] = 0x1b, /* 35 => 27 via 27 (KEY_RIGHTBRACE) */
+ [0x24] = 0x1c, /* 36 => 28 via 28 (KEY_ENTER) */
+ [0x25] = 0x1d, /* 37 => 29 via 29 (KEY_LEFTCTRL) */
+ [0x26] = 0x1e, /* 38 => 30 via 30 (KEY_A) */
+ [0x27] = 0x1f, /* 39 => 31 via 31 (KEY_S) */
+ [0x28] = 0x20, /* 40 => 32 via 32 (KEY_D) */
+ [0x29] = 0x21, /* 41 => 33 via 33 (KEY_F) */
+ [0x2a] = 0x22, /* 42 => 34 via 34 (KEY_G) */
+ [0x2b] = 0x23, /* 43 => 35 via 35 (KEY_H) */
+ [0x2c] = 0x24, /* 44 => 36 via 36 (KEY_J) */
+ [0x2d] = 0x25, /* 45 => 37 via 37 (KEY_K) */
+ [0x2e] = 0x26, /* 46 => 38 via 38 (KEY_L) */
+ [0x2f] = 0x27, /* 47 => 39 via 39 (KEY_SEMICOLON) */
+ [0x30] = 0x28, /* 48 => 40 via 40 (KEY_APOSTROPHE) */
+ [0x31] = 0x29, /* 49 => 41 via 41 (KEY_GRAVE) */
+ [0x32] = 0x2a, /* 50 => 42 via 42 (KEY_LEFTSHIFT) */
+ [0x33] = 0x2b, /* 51 => 43 via 43 (KEY_BACKSLASH) */
+ [0x34] = 0x2c, /* 52 => 44 via 44 (KEY_Z) */
+ [0x35] = 0x2d, /* 53 => 45 via 45 (KEY_X) */
+ [0x36] = 0x2e, /* 54 => 46 via 46 (KEY_C) */
+ [0x37] = 0x2f, /* 55 => 47 via 47 (KEY_V) */
+ [0x38] = 0x30, /* 56 => 48 via 48 (KEY_B) */
+ [0x39] = 0x31, /* 57 => 49 via 49 (KEY_N) */
+ [0x3a] = 0x32, /* 58 => 50 via 50 (KEY_M) */
+ [0x3b] = 0x33, /* 59 => 51 via 51 (KEY_COMMA) */
+ [0x3c] = 0x34, /* 60 => 52 via 52 (KEY_DOT) */
+ [0x3d] = 0x35, /* 61 => 53 via 53 (KEY_SLASH) */
+ [0x3e] = 0x36, /* 62 => 54 via 54 (KEY_RIGHTSHIFT) */
+ [0x3f] = 0x37, /* 63 => 55 via 55 (KEY_KPASTERISK) */
+ [0x40] = 0x38, /* 64 => 56 via 56 (KEY_LEFTALT) */
+ [0x41] = 0x39, /* 65 => 57 via 57 (KEY_SPACE) */
+ [0x42] = 0x3a, /* 66 => 58 via 58 (KEY_CAPSLOCK) */
+ [0x43] = 0x3b, /* 67 => 59 via 59 (KEY_F1) */
+ [0x44] = 0x3c, /* 68 => 60 via 60 (KEY_F2) */
+ [0x45] = 0x3d, /* 69 => 61 via 61 (KEY_F3) */
+ [0x46] = 0x3e, /* 70 => 62 via 62 (KEY_F4) */
+ [0x47] = 0x3f, /* 71 => 63 via 63 (KEY_F5) */
+ [0x48] = 0x40, /* 72 => 64 via 64 (KEY_F6) */
+ [0x49] = 0x41, /* 73 => 65 via 65 (KEY_F7) */
+ [0x4a] = 0x42, /* 74 => 66 via 66 (KEY_F8) */
+ [0x4b] = 0x43, /* 75 => 67 via 67 (KEY_F9) */
+ [0x4c] = 0x44, /* 76 => 68 via 68 (KEY_F10) */
+ [0x4d] = 0x45, /* 77 => 69 via 69 (KEY_NUMLOCK) */
+ [0x4e] = 0x46, /* 78 => 70 via 70 (KEY_SCROLLLOCK) */
+ [0x4f] = 0x47, /* 79 => 71 via 71 (KEY_KP7) */
+ [0x50] = 0x48, /* 80 => 72 via 72 (KEY_KP8) */
+ [0x51] = 0x49, /* 81 => 73 via 73 (KEY_KP9) */
+ [0x52] = 0x4a, /* 82 => 74 via 74 (KEY_KPMINUS) */
+ [0x53] = 0x4b, /* 83 => 75 via 75 (KEY_KP4) */
+ [0x54] = 0x4c, /* 84 => 76 via 76 (KEY_KP5) */
+ [0x55] = 0x4d, /* 85 => 77 via 77 (KEY_KP6) */
+ [0x56] = 0x4e, /* 86 => 78 via 78 (KEY_KPPLUS) */
+ [0x57] = 0x4f, /* 87 => 79 via 79 (KEY_KP1) */
+ [0x58] = 0x50, /* 88 => 80 via 80 (KEY_KP2) */
+ [0x59] = 0x51, /* 89 => 81 via 81 (KEY_KP3) */
+ [0x5a] = 0x52, /* 90 => 82 via 82 (KEY_KP0) */
+ [0x5b] = 0x53, /* 91 => 83 via 83 (KEY_KPDOT) */
+ [0x61] = 0x147, /* 97 => 327 via 102 (KEY_HOME) */
+ [0x62] = 0x148, /* 98 => 328 via 103 (KEY_UP) */
+ [0x63] = 0x149, /* 99 => 329 via 104 (KEY_PAGEUP) */
+ [0x64] = 0x14b, /* 100 => 331 via 105 (KEY_LEFT) */
+ [0x66] = 0x14d, /* 102 => 333 via 106 (KEY_RIGHT) */
+ [0x67] = 0x14f, /* 103 => 335 via 107 (KEY_END) */
+ [0x68] = 0x150, /* 104 => 336 via 108 (KEY_DOWN) */
+ [0x69] = 0x151, /* 105 => 337 via 109 (KEY_PAGEDOWN) */
+ [0x6a] = 0x152, /* 106 => 338 via 110 (KEY_INSERT) */
+ [0x6b] = 0x153, /* 107 => 339 via 111 (KEY_DELETE) */
+ [0x6c] = 0x11c, /* 108 => 284 via 96 (KEY_KPENTER) */
+ [0x6d] = 0x11d, /* 109 => 285 via 97 (KEY_RIGHTCTRL) */
+ [0x6e] = 0x146, /* 110 => 326 via 119 (KEY_PAUSE) */
+ [0x6f] = 0x54, /* 111 => 84 via 99 (KEY_SYSRQ) */
+ [0x70] = 0x135, /* 112 => 309 via 98 (KEY_KPSLASH) */
+ [0x71] = 0x138, /* 113 => 312 via 100 (KEY_RIGHTALT) */
+ [0x73] = 0x15b, /* 115 => 347 via 125 (KEY_LEFTMETA) */
+ [0x74] = 0x15c, /* 116 => 348 via 126 (KEY_RIGHTMETA) */
+ [0x75] = 0x15d, /* 117 => 349 via 127 (KEY_COMPOSE) */
+ [0x76] = 0x5d, /* 118 => 93 via 183 (KEY_F13) */
+ [0x77] = 0x5e, /* 119 => 94 via 184 (KEY_F14) */
+ [0x78] = 0x5f, /* 120 => 95 via 185 (KEY_F15) */
+ [0x79] = 0x55, /* 121 => 85 via 186 (KEY_F16) */
+ [0x7a] = 0x103, /* 122 => 259 via 187 (KEY_F17) */
+ [0x7e] = 0x59, /* 126 => 89 via 117 (KEY_KPEQUAL) */
+ [0x85] = 0x7d, /* 133 => 125 via 124 (KEY_YEN) */
+ [0xd0] = 0x70, /* 208 => 112 via 93 (KEY_KATAKANAHIRAGANA) */
+};
--- /dev/null
+static const guint16 keymap_xorgxquartz2xtkbd[] = {
+ [0x8] = 0x1e, /* 8 => 30 via 30 (KEY_A) */
+ [0x9] = 0x1f, /* 9 => 31 via 31 (KEY_S) */
+ [0xa] = 0x20, /* 10 => 32 via 32 (KEY_D) */
+ [0xb] = 0x21, /* 11 => 33 via 33 (KEY_F) */
+ [0xc] = 0x23, /* 12 => 35 via 35 (KEY_H) */
+ [0xd] = 0x22, /* 13 => 34 via 34 (KEY_G) */
+ [0xe] = 0x2c, /* 14 => 44 via 44 (KEY_Z) */
+ [0xf] = 0x2d, /* 15 => 45 via 45 (KEY_X) */
+ [0x10] = 0x2e, /* 16 => 46 via 46 (KEY_C) */
+ [0x11] = 0x2f, /* 17 => 47 via 47 (KEY_V) */
+ [0x12] = 0x70, /* 18 => 112 via 170 (KEY_ISO) */
+ [0x13] = 0x30, /* 19 => 48 via 48 (KEY_B) */
+ [0x14] = 0x10, /* 20 => 16 via 16 (KEY_Q) */
+ [0x15] = 0x11, /* 21 => 17 via 17 (KEY_W) */
+ [0x16] = 0x12, /* 22 => 18 via 18 (KEY_E) */
+ [0x17] = 0x13, /* 23 => 19 via 19 (KEY_R) */
+ [0x18] = 0x15, /* 24 => 21 via 21 (KEY_Y) */
+ [0x19] = 0x14, /* 25 => 20 via 20 (KEY_T) */
+ [0x1a] = 0x2, /* 26 => 2 via 2 (KEY_1) */
+ [0x1b] = 0x3, /* 27 => 3 via 3 (KEY_2) */
+ [0x1c] = 0x4, /* 28 => 4 via 4 (KEY_3) */
+ [0x1d] = 0x5, /* 29 => 5 via 5 (KEY_4) */
+ [0x1e] = 0x7, /* 30 => 7 via 7 (KEY_6) */
+ [0x1f] = 0x6, /* 31 => 6 via 6 (KEY_5) */
+ [0x20] = 0xd, /* 32 => 13 via 13 (KEY_EQUAL) */
+ [0x21] = 0xa, /* 33 => 10 via 10 (KEY_9) */
+ [0x22] = 0x8, /* 34 => 8 via 8 (KEY_7) */
+ [0x23] = 0xc, /* 35 => 12 via 12 (KEY_MINUS) */
+ [0x24] = 0x9, /* 36 => 9 via 9 (KEY_8) */
+ [0x25] = 0xb, /* 37 => 11 via 11 (KEY_0) */
+ [0x26] = 0x1b, /* 38 => 27 via 27 (KEY_RIGHTBRACE) */
+ [0x27] = 0x18, /* 39 => 24 via 24 (KEY_O) */
+ [0x28] = 0x16, /* 40 => 22 via 22 (KEY_U) */
+ [0x29] = 0x1a, /* 41 => 26 via 26 (KEY_LEFTBRACE) */
+ [0x2a] = 0x17, /* 42 => 23 via 23 (KEY_I) */
+ [0x2b] = 0x19, /* 43 => 25 via 25 (KEY_P) */
+ [0x2c] = 0x1c, /* 44 => 28 via 28 (KEY_ENTER) */
+ [0x2d] = 0x26, /* 45 => 38 via 38 (KEY_L) */
+ [0x2e] = 0x24, /* 46 => 36 via 36 (KEY_J) */
+ [0x2f] = 0x28, /* 47 => 40 via 40 (KEY_APOSTROPHE) */
+ [0x30] = 0x25, /* 48 => 37 via 37 (KEY_K) */
+ [0x31] = 0x27, /* 49 => 39 via 39 (KEY_SEMICOLON) */
+ [0x32] = 0x2b, /* 50 => 43 via 43 (KEY_BACKSLASH) */
+ [0x33] = 0x33, /* 51 => 51 via 51 (KEY_COMMA) */
+ [0x34] = 0x35, /* 52 => 53 via 53 (KEY_SLASH) */
+ [0x35] = 0x31, /* 53 => 49 via 49 (KEY_N) */
+ [0x36] = 0x32, /* 54 => 50 via 50 (KEY_M) */
+ [0x37] = 0x34, /* 55 => 52 via 52 (KEY_DOT) */
+ [0x38] = 0xf, /* 56 => 15 via 15 (KEY_TAB) */
+ [0x39] = 0x39, /* 57 => 57 via 57 (KEY_SPACE) */
+ [0x3a] = 0x29, /* 58 => 41 via 41 (KEY_GRAVE) */
+ [0x3b] = 0xe, /* 59 => 14 via 14 (KEY_BACKSPACE) */
+ [0x3d] = 0x1, /* 61 => 1 via 1 (KEY_ESC) */
+ [0x3f] = 0x15b, /* 63 => 347 via 125 (KEY_LEFTMETA) */
+ [0x40] = 0x2a, /* 64 => 42 via 42 (KEY_LEFTSHIFT) */
+ [0x41] = 0x3a, /* 65 => 58 via 58 (KEY_CAPSLOCK) */
+ [0x42] = 0x38, /* 66 => 56 via 56 (KEY_LEFTALT) */
+ [0x43] = 0x1d, /* 67 => 29 via 29 (KEY_LEFTCTRL) */
+ [0x44] = 0x36, /* 68 => 54 via 54 (KEY_RIGHTSHIFT) */
+ [0x45] = 0x138, /* 69 => 312 via 100 (KEY_RIGHTALT) */
+ [0x46] = 0x11d, /* 70 => 285 via 97 (KEY_RIGHTCTRL) */
+ [0x47] = 0x15d, /* 71 => 349 via 127 (KEY_COMPOSE) */
+ [0x48] = 0x103, /* 72 => 259 via 187 (KEY_F17) */
+ [0x49] = 0x53, /* 73 => 83 via 83 (KEY_KPDOT) */
+ [0x4b] = 0x37, /* 75 => 55 via 55 (KEY_KPASTERISK) */
+ [0x4d] = 0x4e, /* 77 => 78 via 78 (KEY_KPPLUS) */
+ [0x4f] = 0x7e, /* 79 => 126 via 121 (KEY_KPCOMMA) */
+ [0x50] = 0x130, /* 80 => 304 via 115 (KEY_VOLUMEUP) */
+ [0x51] = 0x12e, /* 81 => 302 via 114 (KEY_VOLUMEDOWN) */
+ [0x52] = 0x120, /* 82 => 288 via 113 (KEY_MUTE) */
+ [0x53] = 0x135, /* 83 => 309 via 98 (KEY_KPSLASH) */
+ [0x54] = 0x11c, /* 84 => 284 via 96 (KEY_KPENTER) */
+ [0x56] = 0x4a, /* 86 => 74 via 74 (KEY_KPMINUS) */
+ [0x57] = 0x177, /* 87 => 375 via 188 (KEY_F18) */
+ [0x58] = 0x104, /* 88 => 260 via 189 (KEY_F19) */
+ [0x59] = 0x59, /* 89 => 89 via 117 (KEY_KPEQUAL) */
+ [0x5a] = 0x52, /* 90 => 82 via 82 (KEY_KP0) */
+ [0x5b] = 0x4f, /* 91 => 79 via 79 (KEY_KP1) */
+ [0x5c] = 0x50, /* 92 => 80 via 80 (KEY_KP2) */
+ [0x5d] = 0x51, /* 93 => 81 via 81 (KEY_KP3) */
+ [0x5e] = 0x4b, /* 94 => 75 via 75 (KEY_KP4) */
+ [0x5f] = 0x4c, /* 95 => 76 via 76 (KEY_KP5) */
+ [0x60] = 0x4d, /* 96 => 77 via 77 (KEY_KP6) */
+ [0x61] = 0x47, /* 97 => 71 via 71 (KEY_KP7) */
+ [0x62] = 0x5a, /* 98 => 90 via 190 (KEY_F20) */
+ [0x63] = 0x48, /* 99 => 72 via 72 (KEY_KP8) */
+ [0x64] = 0x49, /* 100 => 73 via 73 (KEY_KP9) */
+ [0x65] = 0x7d, /* 101 => 125 via 124 (KEY_YEN) */
+ [0x67] = 0x5c, /* 103 => 92 via 95 (KEY_KPJPCOMMA) */
+ [0x68] = 0x3f, /* 104 => 63 via 63 (KEY_F5) */
+ [0x69] = 0x40, /* 105 => 64 via 64 (KEY_F6) */
+ [0x6a] = 0x41, /* 106 => 65 via 65 (KEY_F7) */
+ [0x6b] = 0x3d, /* 107 => 61 via 61 (KEY_F3) */
+ [0x6c] = 0x42, /* 108 => 66 via 66 (KEY_F8) */
+ [0x6d] = 0x43, /* 109 => 67 via 67 (KEY_F9) */
+ [0x6f] = 0x57, /* 111 => 87 via 87 (KEY_F11) */
+ [0x70] = 0x78, /* 112 => 120 via 90 (KEY_KATAKANA) */
+ [0x71] = 0x5d, /* 113 => 93 via 183 (KEY_F13) */
+ [0x72] = 0x55, /* 114 => 85 via 186 (KEY_F16) */
+ [0x73] = 0x5e, /* 115 => 94 via 184 (KEY_F14) */
+ [0x75] = 0x44, /* 117 => 68 via 68 (KEY_F10) */
+ [0x77] = 0x58, /* 119 => 88 via 88 (KEY_F12) */
+ [0x79] = 0x5f, /* 121 => 95 via 185 (KEY_F15) */
+ [0x7b] = 0x147, /* 123 => 327 via 102 (KEY_HOME) */
+ [0x7c] = 0x149, /* 124 => 329 via 104 (KEY_PAGEUP) */
+ [0x7d] = 0x153, /* 125 => 339 via 111 (KEY_DELETE) */
+ [0x7e] = 0x3e, /* 126 => 62 via 62 (KEY_F4) */
+ [0x7f] = 0x14f, /* 127 => 335 via 107 (KEY_END) */
+ [0x80] = 0x3c, /* 128 => 60 via 60 (KEY_F2) */
+ [0x81] = 0x151, /* 129 => 337 via 109 (KEY_PAGEDOWN) */
+ [0x82] = 0x3b, /* 130 => 59 via 59 (KEY_F1) */
+ [0x83] = 0x14b, /* 131 => 331 via 105 (KEY_LEFT) */
+ [0x84] = 0x14d, /* 132 => 333 via 106 (KEY_RIGHT) */
+ [0x85] = 0x150, /* 133 => 336 via 108 (KEY_DOWN) */
+ [0x86] = 0x148, /* 134 => 328 via 103 (KEY_UP) */
+};
--- /dev/null
+static const guint16 keymap_xorgxwin2xtkbd[] = {
+ [0x9] = 0x1, /* 9 => 1 via 1 (KEY_ESC) */
+ [0xa] = 0x2, /* 10 => 2 via 2 (KEY_1) */
+ [0xb] = 0x3, /* 11 => 3 via 3 (KEY_2) */
+ [0xc] = 0x4, /* 12 => 4 via 4 (KEY_3) */
+ [0xd] = 0x5, /* 13 => 5 via 5 (KEY_4) */
+ [0xe] = 0x6, /* 14 => 6 via 6 (KEY_5) */
+ [0xf] = 0x7, /* 15 => 7 via 7 (KEY_6) */
+ [0x10] = 0x8, /* 16 => 8 via 8 (KEY_7) */
+ [0x11] = 0x9, /* 17 => 9 via 9 (KEY_8) */
+ [0x12] = 0xa, /* 18 => 10 via 10 (KEY_9) */
+ [0x13] = 0xb, /* 19 => 11 via 11 (KEY_0) */
+ [0x14] = 0xc, /* 20 => 12 via 12 (KEY_MINUS) */
+ [0x15] = 0xd, /* 21 => 13 via 13 (KEY_EQUAL) */
+ [0x16] = 0xe, /* 22 => 14 via 14 (KEY_BACKSPACE) */
+ [0x17] = 0xf, /* 23 => 15 via 15 (KEY_TAB) */
+ [0x18] = 0x10, /* 24 => 16 via 16 (KEY_Q) */
+ [0x19] = 0x11, /* 25 => 17 via 17 (KEY_W) */
+ [0x1a] = 0x12, /* 26 => 18 via 18 (KEY_E) */
+ [0x1b] = 0x13, /* 27 => 19 via 19 (KEY_R) */
+ [0x1c] = 0x14, /* 28 => 20 via 20 (KEY_T) */
+ [0x1d] = 0x15, /* 29 => 21 via 21 (KEY_Y) */
+ [0x1e] = 0x16, /* 30 => 22 via 22 (KEY_U) */
+ [0x1f] = 0x17, /* 31 => 23 via 23 (KEY_I) */
+ [0x20] = 0x18, /* 32 => 24 via 24 (KEY_O) */
+ [0x21] = 0x19, /* 33 => 25 via 25 (KEY_P) */
+ [0x22] = 0x1a, /* 34 => 26 via 26 (KEY_LEFTBRACE) */
+ [0x23] = 0x1b, /* 35 => 27 via 27 (KEY_RIGHTBRACE) */
+ [0x24] = 0x1c, /* 36 => 28 via 28 (KEY_ENTER) */
+ [0x25] = 0x1d, /* 37 => 29 via 29 (KEY_LEFTCTRL) */
+ [0x26] = 0x1e, /* 38 => 30 via 30 (KEY_A) */
+ [0x27] = 0x1f, /* 39 => 31 via 31 (KEY_S) */
+ [0x28] = 0x20, /* 40 => 32 via 32 (KEY_D) */
+ [0x29] = 0x21, /* 41 => 33 via 33 (KEY_F) */
+ [0x2a] = 0x22, /* 42 => 34 via 34 (KEY_G) */
+ [0x2b] = 0x23, /* 43 => 35 via 35 (KEY_H) */
+ [0x2c] = 0x24, /* 44 => 36 via 36 (KEY_J) */
+ [0x2d] = 0x25, /* 45 => 37 via 37 (KEY_K) */
+ [0x2e] = 0x26, /* 46 => 38 via 38 (KEY_L) */
+ [0x2f] = 0x27, /* 47 => 39 via 39 (KEY_SEMICOLON) */
+ [0x30] = 0x28, /* 48 => 40 via 40 (KEY_APOSTROPHE) */
+ [0x31] = 0x29, /* 49 => 41 via 41 (KEY_GRAVE) */
+ [0x32] = 0x2a, /* 50 => 42 via 42 (KEY_LEFTSHIFT) */
+ [0x33] = 0x2b, /* 51 => 43 via 43 (KEY_BACKSLASH) */
+ [0x34] = 0x2c, /* 52 => 44 via 44 (KEY_Z) */
+ [0x35] = 0x2d, /* 53 => 45 via 45 (KEY_X) */
+ [0x36] = 0x2e, /* 54 => 46 via 46 (KEY_C) */
+ [0x37] = 0x2f, /* 55 => 47 via 47 (KEY_V) */
+ [0x38] = 0x30, /* 56 => 48 via 48 (KEY_B) */
+ [0x39] = 0x31, /* 57 => 49 via 49 (KEY_N) */
+ [0x3a] = 0x32, /* 58 => 50 via 50 (KEY_M) */
+ [0x3b] = 0x33, /* 59 => 51 via 51 (KEY_COMMA) */
+ [0x3c] = 0x34, /* 60 => 52 via 52 (KEY_DOT) */
+ [0x3d] = 0x35, /* 61 => 53 via 53 (KEY_SLASH) */
+ [0x3e] = 0x36, /* 62 => 54 via 54 (KEY_RIGHTSHIFT) */
+ [0x3f] = 0x37, /* 63 => 55 via 55 (KEY_KPASTERISK) */
+ [0x40] = 0x38, /* 64 => 56 via 56 (KEY_LEFTALT) */
+ [0x41] = 0x39, /* 65 => 57 via 57 (KEY_SPACE) */
+ [0x42] = 0x3a, /* 66 => 58 via 58 (KEY_CAPSLOCK) */
+ [0x43] = 0x3b, /* 67 => 59 via 59 (KEY_F1) */
+ [0x44] = 0x3c, /* 68 => 60 via 60 (KEY_F2) */
+ [0x45] = 0x3d, /* 69 => 61 via 61 (KEY_F3) */
+ [0x46] = 0x3e, /* 70 => 62 via 62 (KEY_F4) */
+ [0x47] = 0x3f, /* 71 => 63 via 63 (KEY_F5) */
+ [0x48] = 0x40, /* 72 => 64 via 64 (KEY_F6) */
+ [0x49] = 0x41, /* 73 => 65 via 65 (KEY_F7) */
+ [0x4a] = 0x42, /* 74 => 66 via 66 (KEY_F8) */
+ [0x4b] = 0x43, /* 75 => 67 via 67 (KEY_F9) */
+ [0x4c] = 0x44, /* 76 => 68 via 68 (KEY_F10) */
+ [0x4d] = 0x45, /* 77 => 69 via 69 (KEY_NUMLOCK) */
+ [0x4e] = 0x46, /* 78 => 70 via 70 (KEY_SCROLLLOCK) */
+ [0x4f] = 0x47, /* 79 => 71 via 71 (KEY_KP7) */
+ [0x50] = 0x48, /* 80 => 72 via 72 (KEY_KP8) */
+ [0x51] = 0x49, /* 81 => 73 via 73 (KEY_KP9) */
+ [0x52] = 0x4a, /* 82 => 74 via 74 (KEY_KPMINUS) */
+ [0x53] = 0x4b, /* 83 => 75 via 75 (KEY_KP4) */
+ [0x54] = 0x4c, /* 84 => 76 via 76 (KEY_KP5) */
+ [0x55] = 0x4d, /* 85 => 77 via 77 (KEY_KP6) */
+ [0x56] = 0x4e, /* 86 => 78 via 78 (KEY_KPPLUS) */
+ [0x57] = 0x4f, /* 87 => 79 via 79 (KEY_KP1) */
+ [0x58] = 0x50, /* 88 => 80 via 80 (KEY_KP2) */
+ [0x59] = 0x51, /* 89 => 81 via 81 (KEY_KP3) */
+ [0x5a] = 0x52, /* 90 => 82 via 82 (KEY_KP0) */
+ [0x5b] = 0x53, /* 91 => 83 via 83 (KEY_KPDOT) */
+ [0x61] = 0x147, /* 97 => 327 via 102 (KEY_HOME) */
+ [0x62] = 0x148, /* 98 => 328 via 103 (KEY_UP) */
+ [0x63] = 0x149, /* 99 => 329 via 104 (KEY_PAGEUP) */
+ [0x64] = 0x14b, /* 100 => 331 via 105 (KEY_LEFT) */
+ [0x66] = 0x14d, /* 102 => 333 via 106 (KEY_RIGHT) */
+ [0x67] = 0x14f, /* 103 => 335 via 107 (KEY_END) */
+ [0x68] = 0x150, /* 104 => 336 via 108 (KEY_DOWN) */
+ [0x69] = 0x151, /* 105 => 337 via 109 (KEY_PAGEDOWN) */
+ [0x6a] = 0x152, /* 106 => 338 via 110 (KEY_INSERT) */
+ [0x6b] = 0x153, /* 107 => 339 via 111 (KEY_DELETE) */
+ [0x6c] = 0x11c, /* 108 => 284 via 96 (KEY_KPENTER) */
+ [0x6d] = 0x11d, /* 109 => 285 via 97 (KEY_RIGHTCTRL) */
+ [0x6e] = 0x146, /* 110 => 326 via 119 (KEY_PAUSE) */
+ [0x6f] = 0x54, /* 111 => 84 via 99 (KEY_SYSRQ) */
+ [0x70] = 0x135, /* 112 => 309 via 98 (KEY_KPSLASH) */
+ [0x71] = 0x138, /* 113 => 312 via 100 (KEY_RIGHTALT) */
+ [0x73] = 0x15b, /* 115 => 347 via 125 (KEY_LEFTMETA) */
+ [0x74] = 0x15c, /* 116 => 348 via 126 (KEY_RIGHTMETA) */
+ [0x75] = 0x15d, /* 117 => 349 via 127 (KEY_COMPOSE) */
+ [0x76] = 0x5d, /* 118 => 93 via 183 (KEY_F13) */
+ [0x77] = 0x5e, /* 119 => 94 via 184 (KEY_F14) */
+ [0x78] = 0x5f, /* 120 => 95 via 185 (KEY_F15) */
+ [0x79] = 0x55, /* 121 => 85 via 186 (KEY_F16) */
+ [0x7a] = 0x103, /* 122 => 259 via 187 (KEY_F17) */
+ [0x7e] = 0x59, /* 126 => 89 via 117 (KEY_KPEQUAL) */
+ [0x85] = 0x7d, /* 133 => 125 via 124 (KEY_YEN) */
+ [0xd0] = 0x70, /* 208 => 112 via 93 (KEY_KATAKANAHIRAGANA) */
+};
--- /dev/null
+#ifndef _H_USBCLERK
+#define _H_USBCLERK
+
+#include <windows.h>
+
+#define USB_CLERK_PIPE_NAME TEXT("\\\\.\\pipe\\usbclerkpipe")
+#define USB_CLERK_MAGIC 0xDADAu
+#define USB_CLERK_VERSION 0x0003u
+
+typedef struct USBClerkHeader {
+ UINT16 magic;
+ UINT16 version;
+ UINT16 type;
+ UINT16 size;
+} USBClerkHeader;
+
+enum {
+ USB_CLERK_DRIVER_INSTALL = 1,
+ USB_CLERK_DRIVER_REMOVE,
+ USB_CLERK_REPLY,
+ USB_CLERK_DRIVER_SESSION_INSTALL,
+ USB_CLERK_END_MESSAGE,
+};
+
+typedef struct USBClerkDriverOp {
+ USBClerkHeader hdr;
+ UINT16 vid;
+ UINT16 pid;
+} USBClerkDriverOp;
+
+typedef struct USBClerkReply {
+ USBClerkHeader hdr;
+ UINT32 status;
+} USBClerkReply;
+
+#endif
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Arnon Gilboa <agilboa@redhat.com>
+ Uri Lublin <uril@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include <windows.h>
+#include <libusb.h>
+#include "win-usb-dev.h"
+#include "spice-marshal.h"
+#include "spice-util.h"
+#include "usbutil.h"
+
+#define G_UDEV_CLIENT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), G_UDEV_TYPE_CLIENT, GUdevClientPrivate))
+
+enum {
+ PROP_0,
+ PROP_REDIRECTING
+};
+
+struct _GUdevClientPrivate {
+ libusb_context *ctx;
+ GList *udev_list;
+ HWND hwnd;
+ gboolean redirecting;
+};
+
+#define G_UDEV_CLIENT_WINCLASS_NAME TEXT("G_UDEV_CLIENT")
+
+static void g_udev_client_initable_iface_init(GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(GUdevClient, g_udev_client, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(G_TYPE_INITABLE, g_udev_client_initable_iface_init));
+
+
+typedef struct _GUdevDeviceInfo GUdevDeviceInfo;
+
+struct _GUdevDeviceInfo {
+ guint16 bus;
+ guint16 addr;
+ guint16 vid;
+ guint16 pid;
+ guint16 class;
+ gchar sclass[4];
+ gchar sbus[4];
+ gchar saddr[4];
+ gchar svid[8];
+ gchar spid[8];
+};
+
+struct _GUdevDevicePrivate
+{
+ /* FixMe: move above fields to this structure and access them directly */
+ GUdevDeviceInfo *udevinfo;
+};
+
+G_DEFINE_TYPE(GUdevDevice, g_udev_device, G_TYPE_OBJECT)
+
+
+enum
+{
+ UEVENT_SIGNAL,
+ LAST_SIGNAL,
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+static GUdevClient *singleton = NULL;
+
+static GUdevDevice *g_udev_device_new(GUdevDeviceInfo *udevinfo);
+static LRESULT CALLBACK wnd_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
+static gboolean get_usb_dev_info(libusb_device *dev, GUdevDeviceInfo *udevinfo);
+
+//uncomment to debug gudev device lists.
+//#define DEBUG_GUDEV_DEVICE_LISTS
+
+#ifdef DEBUG_GUDEV_DEVICE_LISTS
+static void g_udev_device_print_list(GList *l, const gchar *msg);
+#else
+static void g_udev_device_print_list(GList *l, const gchar *msg) {}
+#endif
+static void g_udev_device_print(GUdevDevice *udev, const gchar *msg);
+
+static gboolean g_udev_skip_search(GUdevDevice *udev);
+
+GQuark g_udev_client_error_quark(void)
+{
+ return g_quark_from_static_string("win-gudev-client-error-quark");
+}
+
+GUdevClient *g_udev_client_new(const gchar* const *subsystems)
+{
+ if (!singleton) {
+ singleton = g_initable_new(G_UDEV_TYPE_CLIENT, NULL, NULL, NULL);
+ return singleton;
+ } else {
+ return g_object_ref(singleton);
+ }
+}
+
+
+/*
+ * devs [in,out] an empty devs list in, full devs list out
+ * Returns: number-of-devices, or a negative value on error.
+ */
+static ssize_t
+g_udev_client_list_devices(GUdevClient *self, GList **devs,
+ GError **err, const gchar *name)
+{
+ gssize rc;
+ libusb_device **lusb_list, **dev;
+ GUdevClientPrivate *priv;
+ GUdevDeviceInfo *udevinfo;
+ GUdevDevice *udevice;
+ ssize_t n;
+
+ g_return_val_if_fail(G_UDEV_IS_CLIENT(self), -1);
+ g_return_val_if_fail(devs != NULL, -2);
+
+ priv = self->priv;
+
+ g_return_val_if_fail(self->priv->ctx != NULL, -3);
+
+ rc = libusb_get_device_list(priv->ctx, &lusb_list);
+ if (rc < 0) {
+ const char *errstr = spice_usbutil_libusb_strerror(rc);
+ g_warning("%s: libusb_get_device_list failed", name);
+ g_set_error(err, G_UDEV_CLIENT_ERROR, G_UDEV_CLIENT_LIBUSB_FAILED,
+ "%s: Error getting device list from libusb: %s [%"G_GSSIZE_FORMAT"]",
+ name, errstr, rc);
+ return -4;
+ }
+
+ n = 0;
+ for (dev = lusb_list; *dev; dev++) {
+ udevinfo = g_new0(GUdevDeviceInfo, 1);
+ get_usb_dev_info(*dev, udevinfo);
+ udevice = g_udev_device_new(udevinfo);
+ if (g_udev_skip_search(udevice)) {
+ g_object_unref(udevice);
+ continue;
+ }
+ *devs = g_list_prepend(*devs, udevice);
+ n++;
+ }
+ libusb_free_device_list(lusb_list, 1);
+
+ return n;
+}
+
+static void g_udev_client_free_device_list(GList **devs)
+{
+ g_return_if_fail(devs != NULL);
+ if (*devs) {
+ g_list_free_full(*devs, g_object_unref);
+ *devs = NULL;
+ }
+}
+
+
+static gboolean
+g_udev_client_initable_init(GInitable *initable, GCancellable *cancellable,
+ GError **err)
+{
+ GUdevClient *self;
+ GUdevClientPrivate *priv;
+ WNDCLASS wcls;
+ int rc;
+
+ g_return_val_if_fail(G_UDEV_IS_CLIENT(initable), FALSE);
+ g_return_val_if_fail(cancellable == NULL, FALSE);
+
+ self = G_UDEV_CLIENT(initable);
+ priv = self->priv;
+
+ rc = libusb_init(&priv->ctx);
+ if (rc < 0) {
+ const char *errstr = spice_usbutil_libusb_strerror(rc);
+ g_warning("Error initializing USB support: %s [%i]", errstr, rc);
+ g_set_error(err, G_UDEV_CLIENT_ERROR, G_UDEV_CLIENT_LIBUSB_FAILED,
+ "Error initializing USB support: %s [%i]", errstr, rc);
+ return FALSE;
+ }
+
+ /* get initial device list */
+ if (g_udev_client_list_devices(self, &priv->udev_list, err, __FUNCTION__) < 0) {
+ goto g_udev_client_init_failed;
+ }
+
+ g_udev_device_print_list(priv->udev_list, "init: first list is: ");
+
+ /* create a hidden window */
+ memset(&wcls, 0, sizeof(wcls));
+ wcls.lpfnWndProc = wnd_proc;
+ wcls.lpszClassName = G_UDEV_CLIENT_WINCLASS_NAME;
+ if (!RegisterClass(&wcls)) {
+ DWORD e = GetLastError();
+ g_warning("RegisterClass failed , %ld", (long)e);
+ g_set_error(err, G_UDEV_CLIENT_ERROR, G_UDEV_CLIENT_WINAPI_FAILED,
+ "RegisterClass failed: %ld", (long)e);
+ goto g_udev_client_init_failed;
+ }
+ priv->hwnd = CreateWindow(G_UDEV_CLIENT_WINCLASS_NAME,
+ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
+ if (!priv->hwnd) {
+ DWORD e = GetLastError();
+ g_warning("CreateWindow failed: %ld", (long)e);
+ g_set_error(err, G_UDEV_CLIENT_ERROR, G_UDEV_CLIENT_LIBUSB_FAILED,
+ "CreateWindow failed: %ld", (long)e);
+ goto g_udev_client_init_failed_unreg;
+ }
+
+ return TRUE;
+
+ g_udev_client_init_failed_unreg:
+ UnregisterClass(G_UDEV_CLIENT_WINCLASS_NAME, NULL);
+ g_udev_client_init_failed:
+ libusb_exit(priv->ctx);
+ priv->ctx = NULL;
+
+ return FALSE;
+}
+
+static void g_udev_client_initable_iface_init(GInitableIface *iface)
+{
+ iface->init = g_udev_client_initable_init;
+}
+
+GList *g_udev_client_query_by_subsystem(GUdevClient *self, const gchar *subsystem)
+{
+ GList *l = g_list_copy(self->priv->udev_list);
+ g_list_foreach(l, (GFunc)g_object_ref, NULL);
+ return l;
+}
+
+static void g_udev_client_init(GUdevClient *self)
+{
+ self->priv = G_UDEV_CLIENT_GET_PRIVATE(self);
+}
+
+static void g_udev_client_finalize(GObject *gobject)
+{
+ GUdevClient *self = G_UDEV_CLIENT(gobject);
+ GUdevClientPrivate *priv = self->priv;
+
+ singleton = NULL;
+ DestroyWindow(priv->hwnd);
+ UnregisterClass(G_UDEV_CLIENT_WINCLASS_NAME, NULL);
+ g_udev_client_free_device_list(&priv->udev_list);
+
+ /* free libusb context initializing by libusb_init() */
+ g_warn_if_fail(priv->ctx != NULL);
+ libusb_exit(priv->ctx);
+
+ /* Chain up to the parent class */
+ if (G_OBJECT_CLASS(g_udev_client_parent_class)->finalize)
+ G_OBJECT_CLASS(g_udev_client_parent_class)->finalize(gobject);
+}
+
+static void g_udev_client_get_property(GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GUdevClient *self = G_UDEV_CLIENT(gobject);
+ GUdevClientPrivate *priv = self->priv;
+
+ switch (prop_id) {
+ case PROP_REDIRECTING:
+ g_value_set_boolean(value, priv->redirecting);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void handle_dev_change(GUdevClient *self);
+
+static void g_udev_client_set_property(GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GUdevClient *self = G_UDEV_CLIENT(gobject);
+ GUdevClientPrivate *priv = self->priv;
+ gboolean old_val;
+
+ switch (prop_id) {
+ case PROP_REDIRECTING:
+ old_val = priv->redirecting;
+ priv->redirecting = g_value_get_boolean(value);
+ if (old_val && !priv->redirecting) {
+ /* This is a redirection completion case.
+ Inject hotplug event in case we missed device changes
+ during redirection processing. */
+ handle_dev_change(self);
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void g_udev_client_class_init(GUdevClientClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ GParamSpec *pspec;
+
+ gobject_class->finalize = g_udev_client_finalize;
+ gobject_class->get_property = g_udev_client_get_property;
+ gobject_class->set_property = g_udev_client_set_property;
+
+ signals[UEVENT_SIGNAL] =
+ g_signal_new("uevent",
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(GUdevClientClass, uevent),
+ NULL, NULL,
+ g_cclosure_user_marshal_VOID__BOXED_BOXED,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_STRING,
+ G_UDEV_TYPE_DEVICE);
+
+ /**
+ * GUdevClient::redirecting:
+ *
+ * This property indicates when a redirection operation
+ * is in progress on a device. It's set back to FALSE
+ * once the device is fully redirected to the guest.
+ */
+ pspec = g_param_spec_boolean("redirecting", "Redirecting",
+ "USB redirection operation is in progress",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_property(gobject_class, PROP_REDIRECTING, pspec);
+
+ g_type_class_add_private(klass, sizeof(GUdevClientPrivate));
+}
+
+static gboolean get_usb_dev_info(libusb_device *dev, GUdevDeviceInfo *udevinfo)
+{
+ struct libusb_device_descriptor desc;
+
+ g_return_val_if_fail(dev, FALSE);
+ g_return_val_if_fail(udevinfo, FALSE);
+
+ if (libusb_get_device_descriptor(dev, &desc) < 0) {
+ g_warning("cannot get device descriptor %p", dev);
+ return FALSE;
+ }
+
+ udevinfo->bus = libusb_get_bus_number(dev);
+ udevinfo->addr = libusb_get_device_address(dev);
+ udevinfo->class = desc.bDeviceClass;
+ udevinfo->vid = desc.idVendor;
+ udevinfo->pid = desc.idProduct;
+ snprintf(udevinfo->sclass, sizeof(udevinfo->sclass), "%d", udevinfo->class);
+ snprintf(udevinfo->sbus, sizeof(udevinfo->sbus), "%d", udevinfo->bus);
+ snprintf(udevinfo->saddr, sizeof(udevinfo->saddr), "%d", udevinfo->addr);
+ snprintf(udevinfo->svid, sizeof(udevinfo->svid), "%d", udevinfo->vid);
+ snprintf(udevinfo->spid, sizeof(udevinfo->spid), "%d", udevinfo->pid);
+ return TRUE;
+}
+
+/* Only vid:pid are compared */
+static gint gudev_devices_differ(gconstpointer a, gconstpointer b)
+{
+ GUdevDeviceInfo *ai, *bi;
+ gboolean same_vid;
+ gboolean same_pid;
+
+ ai = G_UDEV_DEVICE(a)->priv->udevinfo;
+ bi = G_UDEV_DEVICE(b)->priv->udevinfo;
+
+ same_vid = (ai->vid == bi->vid);
+ same_pid = (ai->pid == bi->pid);
+
+ return (same_pid && same_vid) ? 0 : -1;
+}
+
+static void notify_dev_state_change(GUdevClient *self,
+ GList *old_list,
+ GList *new_list,
+ const gchar *action)
+{
+ GList *dev;
+
+ for (dev = g_list_first(old_list); dev != NULL; dev = g_list_next(dev)) {
+ if (g_list_find_custom(new_list, dev->data, gudev_devices_differ) == NULL) {
+ /* Found a device that changed its state */
+ g_udev_device_print(dev->data, action);
+ g_signal_emit(self, signals[UEVENT_SIGNAL], 0, action, dev->data);
+ }
+ }
+}
+
+static void handle_dev_change(GUdevClient *self)
+{
+ GUdevClientPrivate *priv = self->priv;
+ GError *err = NULL;
+ GList *now_devs = NULL;
+
+ if (priv->redirecting == TRUE) {
+ /* On Windows, querying USB device list may return inconsistent results
+ if performed in parallel to redirection flow.
+ A simulated hotplug event will be injected after redirection
+ completion in order to process real device list changes that may
+ had taken place during redirection process. */
+ return;
+ }
+
+ if(g_udev_client_list_devices(self, &now_devs, &err, __FUNCTION__) < 0) {
+ g_warning("could not retrieve device list");
+ return;
+ }
+
+ g_udev_device_print_list(now_devs, "handle_dev_change: current list:");
+ g_udev_device_print_list(priv->udev_list, "handle_dev_change: previous list:");
+
+ /* Unregister devices that are not present anymore */
+ notify_dev_state_change(self, priv->udev_list, now_devs, "remove");
+
+ /* Register newly inserted devices */
+ notify_dev_state_change(self, now_devs, priv->udev_list, "add");
+
+ /* keep most recent info: free previous list, and keep current list */
+ g_udev_client_free_device_list(&priv->udev_list);
+ priv->udev_list = now_devs;
+}
+
+static LRESULT CALLBACK wnd_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
+{
+ /* Only DBT_DEVNODES_CHANGED recieved */
+ if (message == WM_DEVICECHANGE) {
+ handle_dev_change(singleton);
+ }
+ return DefWindowProc(hwnd, message, wparam, lparam);
+}
+
+/*** GUdevDevice ***/
+
+static void g_udev_device_finalize(GObject *object)
+{
+ GUdevDevice *device = G_UDEV_DEVICE(object);
+
+ g_free(device->priv->udevinfo);
+ if (G_OBJECT_CLASS(g_udev_device_parent_class)->finalize != NULL)
+ (* G_OBJECT_CLASS(g_udev_device_parent_class)->finalize)(object);
+}
+
+static void g_udev_device_class_init(GUdevDeviceClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->finalize = g_udev_device_finalize;
+ g_type_class_add_private (klass, sizeof(GUdevDevicePrivate));
+}
+
+static void g_udev_device_init(GUdevDevice *device)
+{
+ device->priv = G_TYPE_INSTANCE_GET_PRIVATE(device, G_UDEV_TYPE_DEVICE, GUdevDevicePrivate);
+}
+
+static GUdevDevice *g_udev_device_new(GUdevDeviceInfo *udevinfo)
+{
+ GUdevDevice *device;
+
+ g_return_val_if_fail(udevinfo != NULL, NULL);
+
+ device = G_UDEV_DEVICE(g_object_new(G_UDEV_TYPE_DEVICE, NULL));
+ device->priv->udevinfo = udevinfo;
+ return device;
+}
+
+const gchar *g_udev_device_get_property(GUdevDevice *udev, const gchar *property)
+{
+ GUdevDeviceInfo* udevinfo;
+
+ g_return_val_if_fail(G_UDEV_DEVICE(udev), NULL);
+ g_return_val_if_fail(property != NULL, NULL);
+
+ udevinfo = udev->priv->udevinfo;
+ g_return_val_if_fail(udevinfo != NULL, NULL);
+
+ if (g_strcmp0(property, "BUSNUM") == 0) {
+ return udevinfo->sbus;
+ } else if (g_strcmp0(property, "DEVNUM") == 0) {
+ return udevinfo->saddr;
+ } else if (g_strcmp0(property, "DEVTYPE") == 0) {
+ return "usb_device";
+ } else if (g_strcmp0(property, "VID") == 0) {
+ return udevinfo->svid;
+ } else if (g_strcmp0(property, "PID") == 0) {
+ return udevinfo->spid;
+ }
+
+ g_warn_if_reached();
+ return NULL;
+}
+
+const gchar *g_udev_device_get_sysfs_attr(GUdevDevice *udev, const gchar *attr)
+{
+ GUdevDeviceInfo* udevinfo;
+
+ g_return_val_if_fail(G_UDEV_DEVICE(udev), NULL);
+ g_return_val_if_fail(attr != NULL, NULL);
+
+ udevinfo = udev->priv->udevinfo;
+ g_return_val_if_fail(udevinfo != NULL, NULL);
+
+
+ if (g_strcmp0(attr, "bDeviceClass") == 0) {
+ return udevinfo->sclass;
+ }
+ g_warn_if_reached();
+ return NULL;
+}
+
+#ifdef DEBUG_GUDEV_DEVICE_LISTS
+static void g_udev_device_print_list(GList *l, const gchar *msg)
+{
+ GList *it;
+
+ for (it = g_list_first(l); it != NULL; it=g_list_next(it)) {
+ g_udev_device_print(it->data, msg);
+ }
+}
+#endif
+
+static void g_udev_device_print(GUdevDevice *udev, const gchar *msg)
+{
+ GUdevDeviceInfo* udevinfo;
+
+ g_return_if_fail(G_UDEV_DEVICE(udev));
+
+ udevinfo = udev->priv->udevinfo;
+ g_return_if_fail(udevinfo != NULL);
+
+ SPICE_DEBUG("%s: %d.%d 0x%04x:0x%04x class %d", msg,
+ udevinfo->bus, udevinfo->addr,
+ udevinfo->vid, udevinfo->pid, udevinfo->class);
+}
+
+static gboolean g_udev_skip_search(GUdevDevice *udev)
+{
+ GUdevDeviceInfo* udevinfo;
+ gboolean skip;
+
+ g_return_val_if_fail(G_UDEV_DEVICE(udev), FALSE);
+
+ udevinfo = udev->priv->udevinfo;
+ g_return_val_if_fail(udevinfo != NULL, FALSE);
+
+ skip = ((udevinfo->addr == 0xff) || /* root hub (HCD) */
+#if defined(LIBUSBX_API_VERSION) && (LIBUSBX_API_VERSION >= 0x010000FF)
+ (udevinfo->addr == 1) || /* root hub addr for libusbx >= 1.0.13 */
+#endif
+ (udevinfo->class == LIBUSB_CLASS_HUB) || /* hub*/
+ (udevinfo->addr == 0)); /* bad address */
+ return skip;
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2012 Red Hat, Inc.
+
+ Red Hat Authors:
+ Arnon Gilboa <agilboa@redhat.com>
+ Uri Lublin <uril@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __WIN_USB_DEV_H__
+#define __WIN_USB_DEV_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/* GUdevDevice */
+
+#define G_UDEV_TYPE_DEVICE (g_udev_device_get_type())
+#define G_UDEV_DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), G_UDEV_TYPE_DEVICE, GUdevDevice))
+#define G_UDEV_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_DEVICE, GUdevDeviceClass))
+#define G_UDEV_IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_UDEV_TYPE_DEVICE))
+#define G_UDEV_IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), G_UDEV_TYPE_DEVICE))
+#define G_UDEV_DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), G_UDEV_TYPE_DEVICE, GUdevDeviceClass))
+
+typedef struct _GUdevDevice GUdevDevice;
+typedef struct _GUdevDeviceClass GUdevDeviceClass;
+typedef struct _GUdevDevicePrivate GUdevDevicePrivate;
+
+struct _GUdevDevice
+{
+ GObject parent;
+ GUdevDevicePrivate *priv;
+};
+
+struct _GUdevDeviceClass
+{
+ GObjectClass parent_class;
+};
+
+/* GUdevClient */
+
+#define G_UDEV_TYPE_CLIENT (g_udev_client_get_type())
+#define G_UDEV_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST((o), G_UDEV_TYPE_CLIENT, GUdevClient))
+#define G_UDEV_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_UDEV_TYPE_CLIENT, GUdevClientClass))
+#define G_UDEV_IS_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), G_UDEV_TYPE_CLIENT))
+#define G_UDEV_IS_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), G_UDEV_TYPE_CLIENT))
+#define G_UDEV_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), G_UDEV_TYPE_CLIENT, GUdevClientClass))
+
+typedef struct _GUdevClient GUdevClient;
+typedef struct _GUdevClientClass GUdevClientClass;
+typedef struct _GUdevClientPrivate GUdevClientPrivate;
+
+struct _GUdevClient
+{
+ GObject parent;
+
+ GUdevClientPrivate *priv;
+};
+
+struct _GUdevClientClass
+{
+ GObjectClass parent_class;
+
+ /* signals */
+ void (*uevent)(GUdevClient *client, const gchar *action, GUdevDevice *device);
+};
+
+GType g_udev_client_get_type(void) G_GNUC_CONST;
+GUdevClient *g_udev_client_new(const gchar* const *subsystems);
+GList *g_udev_client_query_by_subsystem(GUdevClient *client, const gchar *subsystem);
+
+GType g_udev_device_get_type(void) G_GNUC_CONST;
+const gchar *g_udev_device_get_property(GUdevDevice *udev, const gchar *property);
+const gchar *g_udev_device_get_sysfs_attr(GUdevDevice *udev, const gchar *attr);
+
+GQuark g_udev_client_error_quark(void);
+#define G_UDEV_CLIENT_ERROR g_udev_client_error_quark()
+
+/**
+ * GUdevClientError:
+ * @G_UDEV_CLIENT_ERROR_FAILED: generic error code
+ * @G_UDEV_CLIENT_LIBUSB_FAILED: a libusb call failed
+ * @G_UDEV_CLIENT_WINAPI_FAILED: a winapi call failed
+ *
+ * Error codes returned by spice-client API.
+ */
+typedef enum
+{
+ G_UDEV_CLIENT_ERROR_FAILED = 1,
+ G_UDEV_CLIENT_LIBUSB_FAILED,
+ G_UDEV_CLIENT_WINAPI_FAILED
+} GUdevClientError;
+
+
+G_END_DECLS
+
+#endif /* __WIN_USB_DEV_H__ */
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ Red Hat Authors:
+ Uri Lublin <uril@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Some notes:
+ * Each installer (instance) opens a named-pipe to talk with win-usb-clerk.
+ * Each installer (instance) requests driver installation for a single device.
+ */
+
+#include "config.h"
+
+#include <windows.h>
+#include <gio/gio.h>
+#include <gio/gwin32inputstream.h>
+#include <gio/gwin32outputstream.h>
+#include "spice-util.h"
+#include "win-usb-clerk.h"
+#include "win-usb-driver-install.h"
+#include "usb-device-manager-priv.h"
+
+/* ------------------------------------------------------------------ */
+/* gobject glue */
+
+#define SPICE_WIN_USB_DRIVER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SPICE_TYPE_WIN_USB_DRIVER, SpiceWinUsbDriverPrivate))
+
+struct _SpiceWinUsbDriverPrivate {
+ USBClerkReply reply;
+ GTask *task;
+ HANDLE handle;
+ SpiceUsbDevice *device;
+};
+
+
+static void spice_win_usb_driver_initable_iface_init(GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(SpiceWinUsbDriver, spice_win_usb_driver, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, spice_win_usb_driver_initable_iface_init));
+
+static void spice_win_usb_driver_init(SpiceWinUsbDriver *self)
+{
+ self->priv = SPICE_WIN_USB_DRIVER_GET_PRIVATE(self);
+}
+
+static gboolean spice_win_usb_driver_initable_init(GInitable *initable,
+ GCancellable *cancellable,
+ GError **err)
+{
+ SpiceWinUsbDriver *self = SPICE_WIN_USB_DRIVER(initable);
+ SpiceWinUsbDriverPrivate *priv = self->priv;
+
+ SPICE_DEBUG("win-usb-driver-install: connecting to usbclerk named pipe");
+ priv->handle = CreateFile(USB_CLERK_PIPE_NAME,
+ GENERIC_READ | GENERIC_WRITE,
+ 0, NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+ NULL);
+ if (priv->handle == INVALID_HANDLE_VALUE) {
+ DWORD errval = GetLastError();
+ gchar *errstr = g_win32_error_message(errval);
+ g_set_error(err, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_USB_SERVICE,
+ "Failed to create service named pipe (%lu) %s", errval, errstr);
+ g_free(errstr);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void spice_win_usb_driver_finalize(GObject *gobject)
+{
+ SpiceWinUsbDriver *self = SPICE_WIN_USB_DRIVER(gobject);
+ SpiceWinUsbDriverPrivate *priv = self->priv;
+
+ if (priv->handle)
+ CloseHandle(priv->handle);
+
+ g_clear_object(&priv->task);
+
+ if (G_OBJECT_CLASS(spice_win_usb_driver_parent_class)->finalize)
+ G_OBJECT_CLASS(spice_win_usb_driver_parent_class)->finalize(gobject);
+}
+
+static void spice_win_usb_driver_class_init(SpiceWinUsbDriverClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = spice_win_usb_driver_finalize;
+
+ g_type_class_add_private(klass, sizeof(SpiceWinUsbDriverPrivate));
+}
+
+static void spice_win_usb_driver_initable_iface_init(GInitableIface *iface)
+{
+ iface->init = spice_win_usb_driver_initable_init;
+}
+
+/* ------------------------------------------------------------------ */
+/* callbacks */
+
+static
+void win_usb_driver_handle_reply_cb(GObject *gobject,
+ GAsyncResult *read_res,
+ gpointer user_data)
+{
+ SpiceWinUsbDriver *self;
+ SpiceWinUsbDriverPrivate *priv;
+
+ GInputStream *istream;
+ GError *err = NULL;
+ gssize bytes;
+
+ g_return_if_fail(SPICE_IS_WIN_USB_DRIVER(user_data));
+ self = SPICE_WIN_USB_DRIVER(user_data);
+ priv = self->priv;
+ istream = G_INPUT_STREAM(gobject);
+
+ bytes = g_input_stream_read_finish(istream, read_res, &err);
+
+ SPICE_DEBUG("Finished reading reply-msg from usbclerk: bytes=%ld "
+ "err_exist?=%d", (long)bytes, err!=NULL);
+
+ g_warn_if_fail(g_input_stream_close(istream, NULL, NULL));
+ g_clear_object(&istream);
+
+ if (err) {
+ g_warning("failed to read reply from usbclerk (%s)", err->message);
+ g_task_return_error(priv->task, err);
+ goto failed_reply;
+ }
+
+ if (bytes == 0) {
+ g_warning("unexpected EOF from usbclerk");
+ g_task_return_new_error(priv->task,
+ SPICE_WIN_USB_DRIVER_ERROR,
+ SPICE_WIN_USB_DRIVER_ERROR_FAILED,
+ "unexpected EOF from usbclerk");
+ goto failed_reply;
+ }
+
+ if (bytes != sizeof(priv->reply)) {
+ g_warning("usbclerk size mismatch: read %"G_GSSIZE_FORMAT" bytes,expected "
+ "%"G_GSSIZE_FORMAT" (header %"G_GSSIZE_FORMAT", size in header %d)",
+ bytes, sizeof(priv->reply), sizeof(priv->reply.hdr), priv->reply.hdr.size);
+ /* For now just warn, do not fail */
+ }
+
+ if (priv->reply.hdr.magic != USB_CLERK_MAGIC) {
+ g_warning("usbclerk magic mismatch: mine=0x%04x server=0x%04x",
+ USB_CLERK_MAGIC, priv->reply.hdr.magic);
+ g_task_return_new_error(priv->task,
+ SPICE_WIN_USB_DRIVER_ERROR,
+ SPICE_WIN_USB_DRIVER_ERROR_MESSAGE,
+ "usbclerk magic mismatch");
+ goto failed_reply;
+ }
+
+ if (priv->reply.hdr.version != USB_CLERK_VERSION) {
+ g_warning("usbclerk version mismatch: mine=0x%04x server=0x%04x",
+ USB_CLERK_VERSION, priv->reply.hdr.version);
+ g_task_return_new_error(priv->task,
+ SPICE_WIN_USB_DRIVER_ERROR,
+ SPICE_WIN_USB_DRIVER_ERROR_MESSAGE,
+ "usbclerk version mismatch");
+ }
+
+ if (priv->reply.hdr.type != USB_CLERK_REPLY) {
+ g_warning("usbclerk message with unexpected type %d",
+ priv->reply.hdr.type);
+ g_task_return_new_error(priv->task,
+ SPICE_WIN_USB_DRIVER_ERROR,
+ SPICE_WIN_USB_DRIVER_ERROR_MESSAGE,
+ "usbclerk message with unexpected type");
+ goto failed_reply;
+ }
+
+ if (priv->reply.hdr.size != bytes) {
+ g_warning("usbclerk message size mismatch: read %"G_GSSIZE_FORMAT" bytes hdr.size=%d",
+ bytes, priv->reply.hdr.size);
+ g_task_return_new_error(priv->task,
+ SPICE_WIN_USB_DRIVER_ERROR,
+ SPICE_WIN_USB_DRIVER_ERROR_MESSAGE,
+ "usbclerk message with unexpected size");
+ goto failed_reply;
+ }
+
+ if (priv->reply.status == 0) {
+ g_task_return_new_error(priv->task,
+ SPICE_WIN_USB_DRIVER_ERROR,
+ SPICE_WIN_USB_DRIVER_ERROR_MESSAGE,
+ "usbclerk error reply");
+ goto failed_reply;
+ }
+
+ g_task_return_boolean (priv->task, TRUE);
+
+ failed_reply:
+ g_clear_object(&priv->task);
+}
+
+/* ------------------------------------------------------------------ */
+/* helper functions */
+
+static
+gboolean spice_win_usb_driver_send_request(SpiceWinUsbDriver *self, guint16 op,
+ guint16 vid, guint16 pid, GError **err)
+{
+ USBClerkDriverOp req;
+ GOutputStream *ostream;
+ SpiceWinUsbDriverPrivate *priv;
+ gsize bytes;
+ gboolean ret;
+
+ SPICE_DEBUG("sending a request to usbclerk service (op=%d vid=0x%04x pid=0x%04x",
+ op, vid, pid);
+
+ g_return_val_if_fail(SPICE_IS_WIN_USB_DRIVER(self), FALSE);
+ priv = self->priv;
+
+ memset(&req, 0, sizeof(req));
+ req.hdr.magic = USB_CLERK_MAGIC;
+ req.hdr.version = USB_CLERK_VERSION;
+ req.hdr.type = op;
+ req.hdr.size = sizeof(req);
+ req.vid = vid;
+ req.pid = pid;
+
+ ostream = g_win32_output_stream_new(priv->handle, FALSE);
+
+ ret = g_output_stream_write_all(ostream, &req, sizeof(req), &bytes, NULL, err);
+ g_warn_if_fail(g_output_stream_close(ostream, NULL, NULL));
+ g_object_unref(ostream);
+ SPICE_DEBUG("write_all request returned %d written bytes %"G_GSIZE_FORMAT
+ " expecting %"G_GSIZE_FORMAT,
+ ret, bytes, sizeof(req));
+ return ret;
+}
+
+static
+void spice_win_usb_driver_read_reply_async(SpiceWinUsbDriver *self)
+{
+ SpiceWinUsbDriverPrivate *priv;
+ GInputStream *istream;
+
+ g_return_if_fail(SPICE_IS_WIN_USB_DRIVER(self));
+ priv = self->priv;
+
+ SPICE_DEBUG("waiting for a reply from usbclerk");
+
+ istream = g_win32_input_stream_new(priv->handle, FALSE);
+
+ g_input_stream_read_async(istream, &priv->reply, sizeof(priv->reply),
+ G_PRIORITY_DEFAULT,
+ g_task_get_cancellable(priv->task),
+ win_usb_driver_handle_reply_cb, self);
+}
+
+
+/* ------------------------------------------------------------------ */
+/* private api */
+
+
+G_GNUC_INTERNAL
+SpiceWinUsbDriver *spice_win_usb_driver_new(GError **err)
+{
+ GObject *self;
+
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ self = g_initable_new(SPICE_TYPE_WIN_USB_DRIVER, NULL, err, NULL);
+
+ return SPICE_WIN_USB_DRIVER(self);
+}
+
+static
+void spice_win_usb_driver_op(SpiceWinUsbDriver *self,
+ SpiceUsbDevice *device,
+ guint16 op_type,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ guint16 vid, pid;
+ GError *err = NULL;
+ GTask *task;
+ SpiceWinUsbDriverPrivate *priv;
+
+ g_return_if_fail(SPICE_IS_WIN_USB_DRIVER(self));
+ g_return_if_fail(device != NULL);
+
+ priv = self->priv;
+
+ task = g_task_new(self, cancellable, callback, user_data);
+
+ if (priv->task) { /* allow one install/uninstall request at a time */
+ g_warning("Another request exists -- try later");
+ g_task_return_new_error(task,
+ SPICE_WIN_USB_DRIVER_ERROR, SPICE_WIN_USB_DRIVER_ERROR_FAILED,
+ "Another request exists -- try later");
+ goto failed_request;
+ }
+
+
+ vid = spice_usb_device_get_vid(device);
+ pid = spice_usb_device_get_pid(device);
+
+ if (!spice_win_usb_driver_send_request(self, op_type,
+ vid, pid, &err)) {
+ g_warning("failed to send a request to usbclerk %s", err->message);
+ g_task_return_error(task, err);
+ goto failed_request;
+ }
+
+ /* set up for async read */
+ priv->task = task;
+ priv->device = device;
+
+ spice_win_usb_driver_read_reply_async(self);
+
+ return;
+
+ failed_request:
+ g_clear_object(&task);
+}
+
+/*
+ * Returns: currently returns 0 (failure) and 1 (success)
+ * possibly later we'll add error-codes
+ */
+static gboolean
+spice_win_usb_driver_op_finish(SpiceWinUsbDriver *self,
+ GAsyncResult *res, GError **err)
+{
+ GTask *task = G_TASK(res);
+
+ g_return_val_if_fail(SPICE_IS_WIN_USB_DRIVER(self), 0);
+ g_return_val_if_fail(g_task_is_valid(task, self), FALSE);
+
+ return g_task_propagate_boolean(task, err);
+}
+
+/**
+ * spice_win_usb_driver_install_async:
+ * Start libusb driver installation for @device
+ *
+ * A new NamedPipe is created for each request.
+ *
+ * Returns: TRUE if a request was sent to usbclerk
+ * FALSE upon failure to send a request.
+ */
+G_GNUC_INTERNAL
+void spice_win_usb_driver_install_async(SpiceWinUsbDriver *self,
+ SpiceUsbDevice *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SPICE_DEBUG("Win usb driver installation started");
+
+ spice_win_usb_driver_op(self, device, USB_CLERK_DRIVER_SESSION_INSTALL,
+ cancellable, callback, user_data);
+}
+
+G_GNUC_INTERNAL
+void spice_win_usb_driver_uninstall_async(SpiceWinUsbDriver *self,
+ SpiceUsbDevice *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ SPICE_DEBUG("Win usb driver uninstall operation started");
+
+ spice_win_usb_driver_op(self, device, USB_CLERK_DRIVER_REMOVE, cancellable,
+ callback, user_data);
+}
+
+G_GNUC_INTERNAL
+gboolean spice_win_usb_driver_install_finish(SpiceWinUsbDriver *self,
+ GAsyncResult *res, GError **err)
+{
+ return spice_win_usb_driver_op_finish(self, res, err);
+}
+
+G_GNUC_INTERNAL
+gboolean spice_win_usb_driver_uninstall_finish(SpiceWinUsbDriver *self,
+ GAsyncResult *res, GError **err)
+{
+ return spice_win_usb_driver_op_finish(self, res, err);
+}
+
+G_GNUC_INTERNAL
+SpiceUsbDevice *spice_win_usb_driver_get_device(SpiceWinUsbDriver *self)
+{
+ g_return_val_if_fail(SPICE_IS_WIN_USB_DRIVER(self), 0);
+
+ return self->priv->device;
+}
+
+GQuark spice_win_usb_driver_error_quark(void)
+{
+ return g_quark_from_static_string("spice-win-usb-driver-error-quark");
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2011 Red Hat, Inc.
+
+ Red Hat Authors:
+ Uri Lublin <uril@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef SPICE_WIN_USB_DRIVER_H
+#define SPICE_WIN_USB_DRIVER_H
+
+#include "usb-device-manager.h"
+
+G_BEGIN_DECLS
+
+GQuark win_usb_driver_error_quark(void);
+
+
+#define SPICE_TYPE_WIN_USB_DRIVER (spice_win_usb_driver_get_type ())
+#define SPICE_WIN_USB_DRIVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ SPICE_TYPE_WIN_USB_DRIVER, SpiceWinUsbDriver))
+#define SPICE_IS_WIN_USB_DRIVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ SPICE_TYPE_WIN_USB_DRIVER))
+#define SPICE_WIN_USB_DRIVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ SPICE_TYPE_WIN_USB_DRIVER, SpiceWinUsbDriverClass))
+#define SPICE_IS_WIN_USB_DRIVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+ SPICE_TYPE_WIN_USB_DRIVER))
+#define SPICE_WIN_USB_DRIVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+ SPICE_TYPE_WIN_USB_DRIVER, SpiceWinUsbDriverClass))
+
+typedef struct _SpiceWinUsbDriver SpiceWinUsbDriver;
+typedef struct _SpiceWinUsbDriverClass SpiceWinUsbDriverClass;
+typedef struct _SpiceWinUsbDriverPrivate SpiceWinUsbDriverPrivate;
+
+struct _SpiceWinUsbDriver
+{
+ GObject parent;
+
+ /*< private >*/
+ SpiceWinUsbDriverPrivate *priv;
+ /* Do not add fields to this struct */
+};
+
+struct _SpiceWinUsbDriverClass
+{
+ GObjectClass parent_class;
+};
+
+GType spice_win_usb_driver_get_type(void);
+
+SpiceWinUsbDriver *spice_win_usb_driver_new(GError **err);
+
+
+void spice_win_usb_driver_install_async(SpiceWinUsbDriver *self,
+ SpiceUsbDevice *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean spice_win_usb_driver_install_finish(SpiceWinUsbDriver *self,
+ GAsyncResult *res, GError **err);
+
+void spice_win_usb_driver_uninstall_async(SpiceWinUsbDriver *self,
+ SpiceUsbDevice *device,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean spice_win_usb_driver_uninstall_finish(SpiceWinUsbDriver *self,
+ GAsyncResult *res, GError **err);
+
+
+
+SpiceUsbDevice *spice_win_usb_driver_get_device(SpiceWinUsbDriver *self);
+
+#define SPICE_WIN_USB_DRIVER_ERROR spice_win_usb_driver_error_quark()
+
+/**
+ * SpiceWinUsbDriverError:
+ * @SPICE_WIN_USB_DRIVER_ERROR_FAILED: generic error code
+ * @SPICE_WIN_USB_DRIVER_ERROR_MESSAGE: bad message read from clerk
+ *
+ * Error codes returned by spice-client API.
+ */
+typedef enum
+{
+ SPICE_WIN_USB_DRIVER_ERROR_FAILED,
+ SPICE_WIN_USB_DRIVER_ERROR_MESSAGE,
+} SpiceWinUsbDriverError;
+
+GQuark spice_win_usb_driver_error_quark(void);
+
+G_END_DECLS
+
+#endif /* SPICE_WIN_USB_DRIVER_H */
--- /dev/null
+ /* wocky-http-proxy.c: Source for WockyHttpProxy
+ *
+ * Copyright (C) 2010 Collabora, Ltd.
+ * Copyright (C) 2014 Red Hat, Inc.
+ * @author Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ * @author Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "wocky-http-proxy.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+
+struct _WockyHttpProxy
+{
+ GObject parent;
+};
+
+struct _WockyHttpProxyClass
+{
+ GObjectClass parent_class;
+};
+
+static void wocky_http_proxy_iface_init (GProxyInterface *proxy_iface);
+
+#define wocky_http_proxy_get_type _wocky_http_proxy_get_type
+G_DEFINE_TYPE_WITH_CODE (WockyHttpProxy, wocky_http_proxy, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
+ wocky_http_proxy_iface_init)
+ g_io_extension_point_set_required_type (
+ g_io_extension_point_register (G_PROXY_EXTENSION_POINT_NAME),
+ G_TYPE_PROXY);
+ g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
+ g_define_type_id, "http", 0))
+
+static void
+wocky_http_proxy_init (WockyHttpProxy *proxy)
+{
+}
+
+#define HTTP_END_MARKER "\r\n\r\n"
+
+static gchar *
+create_request (GProxyAddress *proxy_address, gboolean *has_cred)
+{
+ const gchar *hostname;
+ gint port;
+ const gchar *username;
+ const gchar *password;
+ GString *request;
+ gchar *ascii_hostname;
+
+ if (has_cred)
+ *has_cred = FALSE;
+
+ hostname = g_proxy_address_get_destination_hostname (proxy_address);
+ port = g_proxy_address_get_destination_port (proxy_address);
+ username = g_proxy_address_get_username (proxy_address);
+ password = g_proxy_address_get_password (proxy_address);
+
+ request = g_string_new (NULL);
+
+ ascii_hostname = g_hostname_to_ascii (hostname);
+ g_string_append_printf (request,
+ "CONNECT %s:%i HTTP/1.0\r\n"
+ "Host: %s:%i\r\n"
+ "Proxy-Connection: keep-alive\r\n"
+ "User-Agent: GLib/%i.%i\r\n",
+ ascii_hostname, port,
+ ascii_hostname, port,
+ GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION);
+ g_free (ascii_hostname);
+
+ if (username != NULL && password != NULL)
+ {
+ gchar *cred;
+ gchar *base64_cred;
+
+ if (has_cred)
+ *has_cred = TRUE;
+
+ cred = g_strdup_printf ("%s:%s", username, password);
+ base64_cred = g_base64_encode ((guchar *) cred, strlen (cred));
+ g_free (cred);
+ g_string_append_printf (request,
+ "Proxy-Authorization: Basic %s\r\n",
+ base64_cred);
+ g_free (base64_cred);
+ }
+
+ g_string_append (request, "\r\n");
+
+ return g_string_free (request, FALSE);
+}
+
+static gboolean
+check_reply (const gchar *buffer, gboolean has_cred, GError **error)
+{
+ gint err_code;
+ const gchar *ptr = buffer + 7;
+
+ if (strncmp (buffer, "HTTP/1.", 7) != 0
+ || (*ptr != '0' && *ptr != '1'))
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
+ "Bad HTTP proxy reply");
+ return FALSE;
+ }
+
+ ptr++;
+ while (*ptr == ' ') ptr++;
+
+ err_code = atoi (ptr);
+
+ if (err_code < 200 || err_code >= 300)
+ {
+ const gchar *msg_start;
+ gchar *msg;
+
+ while (g_ascii_isdigit (*ptr))
+ ptr++;
+
+ while (*ptr == ' ')
+ ptr++;
+
+ msg_start = ptr;
+
+ ptr = strchr (msg_start, '\r');
+
+ if (ptr == NULL)
+ ptr = strchr (msg_start, '\0');
+
+ msg = g_strndup (msg_start, ptr - msg_start);
+
+ if (err_code == 407)
+ {
+ if (has_cred)
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_PROXY_AUTH_FAILED,
+ "HTTP proxy authentication failed");
+ else
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_PROXY_NEED_AUTH,
+ "HTTP proxy authentication required");
+ }
+ else if (msg[0] == '\0')
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
+ "Connection failed due to broken HTTP reply");
+ else
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
+ "HTTP proxy connection failed: %i %s",
+ err_code, msg);
+
+ g_free (msg);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static GIOStream *
+wocky_http_proxy_connect (GProxy *proxy,
+ GIOStream *io_stream,
+ GProxyAddress *proxy_address,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GInputStream *in;
+ GOutputStream *out;
+ GDataInputStream *data_in = NULL;
+ gchar *buffer = NULL;
+ gboolean has_cred;
+ GIOStream *tlsconn = NULL;
+
+ if (WOCKY_IS_HTTPS_PROXY (proxy))
+ {
+ tlsconn = g_tls_client_connection_new (io_stream,
+ G_SOCKET_CONNECTABLE(proxy_address),
+ error);
+ if (!tlsconn)
+ goto error;
+
+ GTlsCertificateFlags tls_validation_flags = G_TLS_CERTIFICATE_VALIDATE_ALL;
+#ifdef DEBUG
+ tls_validation_flags &= ~(G_TLS_CERTIFICATE_UNKNOWN_CA | G_TLS_CERTIFICATE_BAD_IDENTITY);
+#endif
+ g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn),
+ tls_validation_flags);
+ if (!g_tls_connection_handshake (G_TLS_CONNECTION (tlsconn), cancellable, error))
+ goto error;
+
+ io_stream = tlsconn;
+ }
+
+ in = g_io_stream_get_input_stream (io_stream);
+ out = g_io_stream_get_output_stream (io_stream);
+
+ data_in = g_data_input_stream_new (in);
+ g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (data_in),
+ FALSE);
+
+ buffer = create_request (proxy_address, &has_cred);
+ if (!g_output_stream_write_all (out, buffer, strlen (buffer), NULL,
+ cancellable, error))
+ goto error;
+
+ g_free (buffer);
+ buffer = g_data_input_stream_read_until (data_in, HTTP_END_MARKER, NULL,
+ cancellable, error);
+ g_clear_object(&data_in);
+
+ if (buffer == NULL)
+ {
+ if (error && (*error == NULL))
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
+ "HTTP proxy server closed connection unexpectedly.");
+ goto error;
+ }
+
+ if (!check_reply (buffer, has_cred, error))
+ goto error;
+
+ g_free (buffer);
+
+ g_object_ref (io_stream);
+ g_clear_object (&tlsconn);
+
+ return io_stream;
+
+error:
+ g_clear_object (&tlsconn);
+ g_clear_object (&data_in);
+ g_free (buffer);
+ return NULL;
+}
+
+
+typedef struct
+{
+ GIOStream *io_stream;
+ gchar *buffer;
+ gssize length;
+ gssize offset;
+ GDataInputStream *data_in;
+ gboolean has_cred;
+} ConnectAsyncData;
+
+static void request_write_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data);
+static void reply_read_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data);
+
+static void
+free_connect_data (ConnectAsyncData *data)
+{
+ if (data->io_stream != NULL)
+ g_object_unref (data->io_stream);
+
+ g_free (data->buffer);
+
+ if (data->data_in != NULL)
+ g_object_unref (data->data_in);
+
+ g_free (data);
+}
+
+static void
+complete_async_from_error (GTask *task, GError *error)
+{
+ if (error == NULL)
+ g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_PROXY_FAILED,
+ "HTTP proxy server closed connection unexpectedly.");
+
+ g_task_return_error (task, error);
+ g_object_unref (task);
+}
+
+static void
+do_write (GAsyncReadyCallback callback, GTask *task)
+{
+ GOutputStream *out;
+ ConnectAsyncData *data = g_task_get_task_data (task);
+ out = g_io_stream_get_output_stream (data->io_stream);
+ g_output_stream_write_async (out,
+ data->buffer + data->offset,
+ data->length - data->offset,
+ G_PRIORITY_DEFAULT, g_task_get_cancellable(task),
+ callback, task);
+}
+
+static void
+stream_connected (GTask *task,
+ GIOStream *io_stream)
+{
+ GInputStream *in;
+ ConnectAsyncData *data = g_task_get_task_data (task);
+
+ data->io_stream = g_object_ref (io_stream);
+ in = g_io_stream_get_input_stream (io_stream);
+ data->data_in = g_data_input_stream_new (in);
+ g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (data->data_in),
+ FALSE);
+
+ do_write (request_write_cb, task);
+}
+
+static void
+handshake_completed (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GTlsConnection *conn = G_TLS_CONNECTION (source_object);
+ GTask *task = G_TASK (user_data);
+ GError *error = NULL;
+
+ if (!g_tls_connection_handshake_finish (conn, res, &error))
+ {
+ complete_async_from_error (task, error);
+ return;
+ }
+
+ stream_connected (task, G_IO_STREAM (conn));
+}
+
+static void
+wocky_http_proxy_connect_async (GProxy *proxy,
+ GIOStream *io_stream,
+ GProxyAddress *proxy_address,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ ConnectAsyncData *data;
+
+ task = g_task_new (proxy,
+ cancellable,
+ callback,
+ user_data);
+
+ data = g_new0 (ConnectAsyncData, 1);
+
+ data->buffer = create_request (proxy_address, &data->has_cred);
+ data->length = strlen (data->buffer);
+ data->offset = 0;
+
+ g_task_set_task_data (task, data, (GDestroyNotify)free_connect_data);
+
+ if (WOCKY_IS_HTTPS_PROXY (proxy))
+ {
+ GError *error = NULL;
+ GIOStream *tlsconn;
+
+ tlsconn = g_tls_client_connection_new (io_stream,
+ G_SOCKET_CONNECTABLE(proxy_address),
+ &error);
+ if (!tlsconn)
+ {
+ complete_async_from_error (task, error);
+ return;
+ }
+
+ g_return_if_fail (tlsconn != NULL);
+
+ GTlsCertificateFlags tls_validation_flags = G_TLS_CERTIFICATE_VALIDATE_ALL;
+#ifdef DEBUG
+ tls_validation_flags &= ~(G_TLS_CERTIFICATE_UNKNOWN_CA | G_TLS_CERTIFICATE_BAD_IDENTITY);
+#endif
+ g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn),
+ tls_validation_flags);
+ g_tls_connection_handshake_async (G_TLS_CONNECTION (tlsconn),
+ G_PRIORITY_DEFAULT, cancellable,
+ handshake_completed, task);
+ }
+ else
+ {
+ stream_connected (task, io_stream);
+ }
+}
+
+static void
+request_write_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GTask *task = G_TASK(user_data);
+ ConnectAsyncData *data = g_task_get_task_data (task);
+ gssize written;
+
+ written = g_output_stream_write_finish (G_OUTPUT_STREAM (source),
+ res, &error);
+ if (written < 0)
+ {
+ complete_async_from_error (task, error);
+ return;
+ }
+
+ data->offset += written;
+
+ if (data->offset == data->length)
+ {
+ g_clear_pointer(&data->buffer, g_free);
+
+ g_data_input_stream_read_until_async (data->data_in,
+ HTTP_END_MARKER,
+ G_PRIORITY_DEFAULT,
+ g_task_get_cancellable(task),
+ reply_read_cb, task);
+
+ }
+ else
+ {
+ do_write (request_write_cb, task);
+ }
+}
+
+static void
+reply_read_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GTask *task = G_TASK(user_data);
+ ConnectAsyncData *data = g_task_get_task_data (task);
+
+ data->buffer = g_data_input_stream_read_until_finish (data->data_in,
+ res, NULL, &error);
+
+ if (data->buffer == NULL)
+ {
+ complete_async_from_error (task, error);
+ return;
+ }
+
+ if (!check_reply (data->buffer, data->has_cred, &error))
+ {
+ complete_async_from_error (task, error);
+ return;
+ }
+
+ g_task_return_pointer (task, data->io_stream, (GDestroyNotify) g_object_unref);
+ data->io_stream = NULL;
+ g_object_unref (task);
+}
+
+static GIOStream *
+wocky_http_proxy_connect_finish (GProxy *proxy,
+ GAsyncResult *result,
+ GError **error)
+{
+ GTask *task = G_TASK (result);
+
+ return g_task_propagate_pointer (task, error);
+}
+
+static gboolean
+wocky_http_proxy_supports_hostname (GProxy *proxy)
+{
+ return TRUE;
+}
+
+static void
+wocky_http_proxy_class_init (WockyHttpProxyClass *class)
+{
+}
+
+static void
+wocky_http_proxy_iface_init (GProxyInterface *proxy_iface)
+{
+ proxy_iface->connect = wocky_http_proxy_connect;
+ proxy_iface->connect_async = wocky_http_proxy_connect_async;
+ proxy_iface->connect_finish = wocky_http_proxy_connect_finish;
+ proxy_iface->supports_hostname = wocky_http_proxy_supports_hostname;
+}
+
+struct _WockyHttpsProxy
+{
+ WockyHttpProxy parent;
+};
+
+struct _WockyHttpsProxyClass
+{
+ WockyHttpProxyClass parent_class;
+};
+
+#define wocky_https_proxy_get_type _wocky_https_proxy_get_type
+G_DEFINE_TYPE_WITH_CODE (WockyHttpsProxy, wocky_https_proxy, WOCKY_TYPE_HTTP_PROXY,
+ G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
+ wocky_http_proxy_iface_init)
+ g_io_extension_point_set_required_type (
+ g_io_extension_point_register (G_PROXY_EXTENSION_POINT_NAME),
+ G_TYPE_PROXY);
+ g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
+ g_define_type_id, "https", 0))
+
+static void
+wocky_https_proxy_init (WockyHttpsProxy *proxy)
+{
+}
+
+static void
+wocky_https_proxy_class_init (WockyHttpsProxyClass *class)
+{
+}
--- /dev/null
+ /* wocky-http-proxy.h: Header for WockyHttpProxy
+ *
+ * Copyright (C) 2010 Collabora, Ltd.
+ * @author Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef _WOCKY_HTTP_PROXY_H_
+#define _WOCKY_HTTP_PROXY_H_
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define WOCKY_TYPE_HTTP_PROXY (_wocky_http_proxy_get_type ())
+#define WOCKY_HTTP_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), WOCKY_TYPE_HTTP_PROXY, WockyHttpProxy))
+#define WOCKY_HTTP_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), WOCKY_TYPE_HTTP_PROXY, WockyHttpProxyClass))
+#define WOCKY_IS_HTTP_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), WOCKY_TYPE_HTTP_PROXY))
+#define WOCKY_IS_HTTP_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), WOCKY_TYPE_HTTP_PROXY))
+#define WOCKY_HTTP_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), WOCKY_TYPE_HTTP_PROXY, WockyHttpProxyClass))
+
+typedef struct _WockyHttpProxy WockyHttpProxy;
+typedef struct _WockyHttpProxyClass WockyHttpProxyClass;
+
+GType _wocky_http_proxy_get_type (void);
+
+#define WOCKY_TYPE_HTTPS_PROXY (_wocky_https_proxy_get_type ())
+#define WOCKY_HTTPS_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), WOCKY_TYPE_HTTPS_PROXY, WockyHttpsProxy))
+#define WOCKY_HTTPS_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), WOCKY_TYPE_HTTPS_PROXY, WockyHttpsProxyClass))
+#define WOCKY_IS_HTTPS_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), WOCKY_TYPE_HTTPS_PROXY))
+#define WOCKY_IS_HTTPS_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), WOCKY_TYPE_HTTPS_PROXY))
+#define WOCKY_HTTPS_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), WOCKY_TYPE_HTTPS_PROXY, WockyHttpsProxyClass))
+
+typedef struct _WockyHttpsProxy WockyHttpsProxy;
+typedef struct _WockyHttpsProxyClass WockyHttpsProxyClass;
+
+GType _wocky_https_proxy_get_type (void);
+
+G_END_DECLS
+
+#endif /* _WOCKY_HTTP_PROXY_H_ */
--- /dev/null
+NULL =
+
+noinst_PROGRAMS =
+TESTS = test-coroutine \
+ test-util \
+ test-session \
+ test-spice-uri \
+ test-file-transfer \
+ $(NULL)
+
+if WITH_PHODAV
+TESTS += test-pipe
+endif
+
+if WITH_POLKIT
+TESTS += test-usb-acl-helper
+noinst_PROGRAMS += test-mock-acl-helper
+endif
+
+noinst_PROGRAMS += $(TESTS)
+
+AM_CPPFLAGS = \
+ $(COMMON_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(SMARTCARD_CFLAGS) \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ -DG_LOG_DOMAIN=\"GSpice\" \
+ $(NULL)
+
+AM_LDFLAGS = $(GIO_LIBS) -static
+
+LDADD = \
+ $(top_builddir)/src/libspice-client-glib-2.0.la \
+ $(NULL)
+
+test_util_SOURCES = util.c
+test_coroutine_SOURCES = coroutine.c
+test_session_SOURCES = session.c
+test_pipe_SOURCES = pipe.c
+test_spice_uri_SOURCES = uri.c
+test_file_transfer_SOURCES = file-transfer.c
+test_usb_acl_helper_SOURCES = usb-acl-helper.c
+test_usb_acl_helper_CFLAGS = -DTESTDIR=\"$(abs_builddir)\"
+test_mock_acl_helper_SOURCES = mock-acl-helper.c
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_5)
+TESTS = test-coroutine$(EXEEXT) test-util$(EXEEXT) \
+ test-session$(EXEEXT) test-spice-uri$(EXEEXT) \
+ test-file-transfer$(EXEEXT) $(am__EXEEXT_2) $(am__EXEEXT_3) \
+ $(am__EXEEXT_4)
+@WITH_PHODAV_TRUE@am__append_1 = test-pipe
+@WITH_POLKIT_TRUE@am__append_2 = test-usb-acl-helper
+@WITH_POLKIT_TRUE@am__append_3 = test-mock-acl-helper
+subdir = tests
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/ld-version.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/manywarnings.m4 \
+ $(top_srcdir)/m4/spice-compile-warnings.m4 \
+ $(top_srcdir)/m4/warnings.m4 \
+ $(top_srcdir)/spice-common/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+@WITH_POLKIT_TRUE@am__EXEEXT_1 = test-mock-acl-helper$(EXEEXT)
+am__EXEEXT_2 =
+@WITH_PHODAV_TRUE@am__EXEEXT_3 = test-pipe$(EXEEXT)
+@WITH_POLKIT_TRUE@am__EXEEXT_4 = test-usb-acl-helper$(EXEEXT)
+am__EXEEXT_5 = test-coroutine$(EXEEXT) test-util$(EXEEXT) \
+ test-session$(EXEEXT) test-spice-uri$(EXEEXT) \
+ test-file-transfer$(EXEEXT) $(am__EXEEXT_2) $(am__EXEEXT_3) \
+ $(am__EXEEXT_4)
+PROGRAMS = $(noinst_PROGRAMS)
+am_test_coroutine_OBJECTS = coroutine.$(OBJEXT)
+test_coroutine_OBJECTS = $(am_test_coroutine_OBJECTS)
+test_coroutine_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+test_coroutine_DEPENDENCIES = \
+ $(top_builddir)/src/libspice-client-glib-2.0.la \
+ $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+am_test_file_transfer_OBJECTS = file-transfer.$(OBJEXT)
+test_file_transfer_OBJECTS = $(am_test_file_transfer_OBJECTS)
+test_file_transfer_LDADD = $(LDADD)
+test_file_transfer_DEPENDENCIES = \
+ $(top_builddir)/src/libspice-client-glib-2.0.la \
+ $(am__DEPENDENCIES_1)
+am_test_mock_acl_helper_OBJECTS = mock-acl-helper.$(OBJEXT)
+test_mock_acl_helper_OBJECTS = $(am_test_mock_acl_helper_OBJECTS)
+test_mock_acl_helper_LDADD = $(LDADD)
+test_mock_acl_helper_DEPENDENCIES = \
+ $(top_builddir)/src/libspice-client-glib-2.0.la \
+ $(am__DEPENDENCIES_1)
+am_test_pipe_OBJECTS = pipe.$(OBJEXT)
+test_pipe_OBJECTS = $(am_test_pipe_OBJECTS)
+test_pipe_LDADD = $(LDADD)
+test_pipe_DEPENDENCIES = \
+ $(top_builddir)/src/libspice-client-glib-2.0.la \
+ $(am__DEPENDENCIES_1)
+am_test_session_OBJECTS = session.$(OBJEXT)
+test_session_OBJECTS = $(am_test_session_OBJECTS)
+test_session_LDADD = $(LDADD)
+test_session_DEPENDENCIES = \
+ $(top_builddir)/src/libspice-client-glib-2.0.la \
+ $(am__DEPENDENCIES_1)
+am_test_spice_uri_OBJECTS = uri.$(OBJEXT)
+test_spice_uri_OBJECTS = $(am_test_spice_uri_OBJECTS)
+test_spice_uri_LDADD = $(LDADD)
+test_spice_uri_DEPENDENCIES = \
+ $(top_builddir)/src/libspice-client-glib-2.0.la \
+ $(am__DEPENDENCIES_1)
+am_test_usb_acl_helper_OBJECTS = \
+ test_usb_acl_helper-usb-acl-helper.$(OBJEXT)
+test_usb_acl_helper_OBJECTS = $(am_test_usb_acl_helper_OBJECTS)
+test_usb_acl_helper_LDADD = $(LDADD)
+test_usb_acl_helper_DEPENDENCIES = \
+ $(top_builddir)/src/libspice-client-glib-2.0.la \
+ $(am__DEPENDENCIES_1)
+test_usb_acl_helper_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(test_usb_acl_helper_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am_test_util_OBJECTS = util.$(OBJEXT)
+test_util_OBJECTS = $(am_test_util_OBJECTS)
+test_util_LDADD = $(LDADD)
+test_util_DEPENDENCIES = \
+ $(top_builddir)/src/libspice-client-glib-2.0.la \
+ $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(test_coroutine_SOURCES) $(test_file_transfer_SOURCES) \
+ $(test_mock_acl_helper_SOURCES) $(test_pipe_SOURCES) \
+ $(test_session_SOURCES) $(test_spice_uri_SOURCES) \
+ $(test_usb_acl_helper_SOURCES) $(test_util_SOURCES)
+DIST_SOURCES = $(test_coroutine_SOURCES) $(test_file_transfer_SOURCES) \
+ $(test_mock_acl_helper_SOURCES) $(test_pipe_SOURCES) \
+ $(test_session_SOURCES) $(test_spice_uri_SOURCES) \
+ $(test_usb_acl_helper_SOURCES) $(test_util_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red='\e[0;31m'; \
+ grn='\e[0;32m'; \
+ lgn='\e[1;32m'; \
+ blu='\e[1;34m'; \
+ mgn='\e[0;35m'; \
+ brg='\e[1m'; \
+ std='\e[m'; \
+ fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACL_HELPER_DIR = @ACL_HELPER_DIR@
+ACL_LIBS = @ACL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMMON_CFLAGS = @COMMON_CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GOBJECT2_CFLAGS = @GOBJECT2_CFLAGS@
+GOBJECT2_LIBS = @GOBJECT2_LIBS@
+GREP = @GREP@
+GSTAUDIO_CFLAGS = @GSTAUDIO_CFLAGS@
+GSTAUDIO_LIBS = @GSTAUDIO_LIBS@
+GSTVIDEO_CFLAGS = @GSTVIDEO_CFLAGS@
+GSTVIDEO_LIBS = @GSTVIDEO_LIBS@
+GST_INSPECT_1_0 = @GST_INSPECT_1_0@
+GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
+GTHREAD_LIBS = @GTHREAD_LIBS@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_REQUIRED = @GTK_REQUIRED@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+JPEG_LIBS = @JPEG_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUSB_HOTPLUG_CFLAGS = @LIBUSB_HOTPLUG_CFLAGS@
+LIBUSB_HOTPLUG_LIBS = @LIBUSB_HOTPLUG_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PHODAV_CFLAGS = @PHODAV_CFLAGS@
+PHODAV_LIBS = @PHODAV_LIBS@
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PNP_IDS = @PNP_IDS@
+POFILES = @POFILES@
+POLICYDIR = @POLICYDIR@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PULSE_CFLAGS = @PULSE_CFLAGS@
+PULSE_LIBS = @PULSE_LIBS@
+PYTHON = @PYTHON@
+RANLIB = @RANLIB@
+SASL_CFLAGS = @SASL_CFLAGS@
+SASL_LIBS = @SASL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_CFLAGS = @SPICE_CFLAGS@
+SPICE_GLIB_CFLAGS = @SPICE_GLIB_CFLAGS@
+SPICE_GLIB_REQUIRES = @SPICE_GLIB_REQUIRES@
+SPICE_GTK_CFLAGS = @SPICE_GTK_CFLAGS@
+SPICE_GTK_LOCALEDIR = @SPICE_GTK_LOCALEDIR@
+SPICE_GTK_MAJOR_VERSION = @SPICE_GTK_MAJOR_VERSION@
+SPICE_GTK_MICRO_VERSION = @SPICE_GTK_MICRO_VERSION@
+SPICE_GTK_MINOR_VERSION = @SPICE_GTK_MINOR_VERSION@
+SPICE_GTK_REQUIRES = @SPICE_GTK_REQUIRES@
+SPICE_PROTOCOL_CFLAGS = @SPICE_PROTOCOL_CFLAGS@
+SPICE_PROTOCOL_LIBS = @SPICE_PROTOCOL_LIBS@
+SSL_CFLAGS = @SSL_CFLAGS@
+SSL_LIBS = @SSL_LIBS@
+STOW = @STOW@
+STRIP = @STRIP@
+USBREDIR_CFLAGS = @USBREDIR_CFLAGS@
+USBREDIR_LIBS = @USBREDIR_LIBS@
+USB_IDS = @USB_IDS@
+USE_NLS = @USE_NLS@
+VALAC = @VALAC@
+VAPIDIR = @VAPIDIR@
+VAPIGEN = @VAPIGEN@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_LDFLAGS = @WARN_LDFLAGS@
+WARN_PYFLAGS = @WARN_PYFLAGS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+XGETTEXT = @XGETTEXT@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+AM_CPPFLAGS = \
+ $(COMMON_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(SMARTCARD_CFLAGS) \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ -DG_LOG_DOMAIN=\"GSpice\" \
+ $(NULL)
+
+AM_LDFLAGS = $(GIO_LIBS) -static
+LDADD = \
+ $(top_builddir)/src/libspice-client-glib-2.0.la \
+ $(NULL)
+
+test_util_SOURCES = util.c
+test_coroutine_SOURCES = coroutine.c
+test_session_SOURCES = session.c
+test_pipe_SOURCES = pipe.c
+test_spice_uri_SOURCES = uri.c
+test_file_transfer_SOURCES = file-transfer.c
+test_usb_acl_helper_SOURCES = usb-acl-helper.c
+test_usb_acl_helper_CFLAGS = -DTESTDIR=\"$(abs_builddir)\"
+test_mock_acl_helper_SOURCES = mock-acl-helper.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign tests/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+test-coroutine$(EXEEXT): $(test_coroutine_OBJECTS) $(test_coroutine_DEPENDENCIES) $(EXTRA_test_coroutine_DEPENDENCIES)
+ @rm -f test-coroutine$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_coroutine_OBJECTS) $(test_coroutine_LDADD) $(LIBS)
+
+test-file-transfer$(EXEEXT): $(test_file_transfer_OBJECTS) $(test_file_transfer_DEPENDENCIES) $(EXTRA_test_file_transfer_DEPENDENCIES)
+ @rm -f test-file-transfer$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_file_transfer_OBJECTS) $(test_file_transfer_LDADD) $(LIBS)
+
+test-mock-acl-helper$(EXEEXT): $(test_mock_acl_helper_OBJECTS) $(test_mock_acl_helper_DEPENDENCIES) $(EXTRA_test_mock_acl_helper_DEPENDENCIES)
+ @rm -f test-mock-acl-helper$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_mock_acl_helper_OBJECTS) $(test_mock_acl_helper_LDADD) $(LIBS)
+
+test-pipe$(EXEEXT): $(test_pipe_OBJECTS) $(test_pipe_DEPENDENCIES) $(EXTRA_test_pipe_DEPENDENCIES)
+ @rm -f test-pipe$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_pipe_OBJECTS) $(test_pipe_LDADD) $(LIBS)
+
+test-session$(EXEEXT): $(test_session_OBJECTS) $(test_session_DEPENDENCIES) $(EXTRA_test_session_DEPENDENCIES)
+ @rm -f test-session$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_session_OBJECTS) $(test_session_LDADD) $(LIBS)
+
+test-spice-uri$(EXEEXT): $(test_spice_uri_OBJECTS) $(test_spice_uri_DEPENDENCIES) $(EXTRA_test_spice_uri_DEPENDENCIES)
+ @rm -f test-spice-uri$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_spice_uri_OBJECTS) $(test_spice_uri_LDADD) $(LIBS)
+
+test-usb-acl-helper$(EXEEXT): $(test_usb_acl_helper_OBJECTS) $(test_usb_acl_helper_DEPENDENCIES) $(EXTRA_test_usb_acl_helper_DEPENDENCIES)
+ @rm -f test-usb-acl-helper$(EXEEXT)
+ $(AM_V_CCLD)$(test_usb_acl_helper_LINK) $(test_usb_acl_helper_OBJECTS) $(test_usb_acl_helper_LDADD) $(LIBS)
+
+test-util$(EXEEXT): $(test_util_OBJECTS) $(test_util_DEPENDENCIES) $(EXTRA_test_util_DEPENDENCIES)
+ @rm -f test-util$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_util_OBJECTS) $(test_util_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/coroutine.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file-transfer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mock-acl-helper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pipe.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_usb_acl_helper-usb-acl-helper.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uri.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+test_usb_acl_helper-usb-acl-helper.o: usb-acl-helper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_usb_acl_helper_CFLAGS) $(CFLAGS) -MT test_usb_acl_helper-usb-acl-helper.o -MD -MP -MF $(DEPDIR)/test_usb_acl_helper-usb-acl-helper.Tpo -c -o test_usb_acl_helper-usb-acl-helper.o `test -f 'usb-acl-helper.c' || echo '$(srcdir)/'`usb-acl-helper.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_usb_acl_helper-usb-acl-helper.Tpo $(DEPDIR)/test_usb_acl_helper-usb-acl-helper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='usb-acl-helper.c' object='test_usb_acl_helper-usb-acl-helper.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_usb_acl_helper_CFLAGS) $(CFLAGS) -c -o test_usb_acl_helper-usb-acl-helper.o `test -f 'usb-acl-helper.c' || echo '$(srcdir)/'`usb-acl-helper.c
+
+test_usb_acl_helper-usb-acl-helper.obj: usb-acl-helper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_usb_acl_helper_CFLAGS) $(CFLAGS) -MT test_usb_acl_helper-usb-acl-helper.obj -MD -MP -MF $(DEPDIR)/test_usb_acl_helper-usb-acl-helper.Tpo -c -o test_usb_acl_helper-usb-acl-helper.obj `if test -f 'usb-acl-helper.c'; then $(CYGPATH_W) 'usb-acl-helper.c'; else $(CYGPATH_W) '$(srcdir)/usb-acl-helper.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test_usb_acl_helper-usb-acl-helper.Tpo $(DEPDIR)/test_usb_acl_helper-usb-acl-helper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='usb-acl-helper.c' object='test_usb_acl_helper-usb-acl-helper.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_usb_acl_helper_CFLAGS) $(CFLAGS) -c -o test_usb_acl_helper-usb-acl-helper.obj `if test -f 'usb-acl-helper.c'; then $(CYGPATH_W) 'usb-acl-helper.c'; else $(CYGPATH_W) '$(srcdir)/usb-acl-helper.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+test-coroutine.log: test-coroutine$(EXEEXT)
+ @p='test-coroutine$(EXEEXT)'; \
+ b='test-coroutine'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-util.log: test-util$(EXEEXT)
+ @p='test-util$(EXEEXT)'; \
+ b='test-util'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-session.log: test-session$(EXEEXT)
+ @p='test-session$(EXEEXT)'; \
+ b='test-session'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-spice-uri.log: test-spice-uri$(EXEEXT)
+ @p='test-spice-uri$(EXEEXT)'; \
+ b='test-spice-uri'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-file-transfer.log: test-file-transfer$(EXEEXT)
+ @p='test-file-transfer$(EXEEXT)'; \
+ b='test-file-transfer'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-pipe.log: test-pipe$(EXEEXT)
+ @p='test-pipe$(EXEEXT)'; \
+ b='test-pipe'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-usb-acl-helper.log: test-usb-acl-helper$(EXEEXT)
+ @p='test-usb-acl-helper$(EXEEXT)'; \
+ b='test-usb-acl-helper'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+ clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+#include <glib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "coroutine.h"
+
+static gpointer co_entry_check_self(gpointer data)
+{
+ g_assert(data == coroutine_self());
+ g_assert(!coroutine_self_is_main());
+
+ return NULL;
+}
+
+static gpointer co_entry_42(gpointer data)
+{
+ g_assert(GPOINTER_TO_INT(data) == 42);
+ g_assert(!coroutine_self_is_main());
+
+ return GINT_TO_POINTER(0x42);
+}
+
+static void test_coroutine_simple(void)
+{
+ struct coroutine *self = coroutine_self();
+ struct coroutine co = {
+ .stack_size = 16 << 20,
+ .entry = co_entry_42,
+ };
+ gpointer result;
+
+ g_assert(coroutine_self_is_main());
+
+ coroutine_init(&co);
+ result = coroutine_yieldto(&co, GINT_TO_POINTER(42));
+ g_assert_cmpint(GPOINTER_TO_INT(result), ==, 0x42);
+
+ g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*!to->exited*");
+ coroutine_yieldto(&co, GINT_TO_POINTER(42));
+ g_test_assert_expected_messages();
+
+ g_assert(self == coroutine_self());
+ g_assert(coroutine_self_is_main());
+}
+
+static gpointer co_entry_two(gpointer data G_GNUC_UNUSED)
+{
+ struct coroutine *self = coroutine_self();
+ struct coroutine co = {
+ .stack_size = 16 << 20,
+ .entry = co_entry_check_self,
+ };
+
+ g_assert(!coroutine_self_is_main());
+ coroutine_init(&co);
+ coroutine_yieldto(&co, &co);
+
+ g_assert(self == coroutine_self());
+ return NULL;
+}
+
+static void test_coroutine_two(void)
+{
+ struct coroutine *self = coroutine_self();
+ struct coroutine co = {
+ .stack_size = 16 << 20,
+ .entry = co_entry_two,
+ };
+
+ coroutine_init(&co);
+ coroutine_yieldto(&co, NULL);
+
+ g_assert(self == coroutine_self());
+}
+
+static gpointer co_entry_yield(gpointer data)
+{
+ gpointer val;
+
+ g_assert(data == NULL);
+ val = coroutine_yield(GINT_TO_POINTER(1));
+ g_assert_cmpint(GPOINTER_TO_INT(val), ==, 2);
+
+ g_assert(!coroutine_self_is_main());
+
+ val = coroutine_yield(GINT_TO_POINTER(3));
+ g_assert_cmpint(GPOINTER_TO_INT(val), ==, 4);
+
+ return NULL;
+}
+
+static void test_coroutine_yield(void)
+{
+ struct coroutine *self = coroutine_self();
+ struct coroutine co = {
+ .stack_size = 16 << 20,
+ .entry = co_entry_yield,
+ };
+ gpointer val;
+
+ coroutine_init(&co);
+ val = coroutine_yieldto(&co, NULL);
+
+ g_assert(self == coroutine_self());
+ g_assert_cmpint(GPOINTER_TO_INT(val), ==, 1);
+
+ val = coroutine_yieldto(&co, GINT_TO_POINTER(2));
+
+ g_assert(self == coroutine_self());
+ g_assert_cmpint(GPOINTER_TO_INT(val), ==, 3);
+
+ val = coroutine_yieldto(&co, GINT_TO_POINTER(4));
+
+ g_assert(self == coroutine_self());
+ g_assert(val == NULL);
+
+ g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "*!to->exited*");
+ coroutine_yieldto(&co, GINT_TO_POINTER(42));
+ g_test_assert_expected_messages();
+}
+
+int main(int argc, char* argv[])
+{
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add_func("/coroutine/simple", test_coroutine_simple);
+ g_test_add_func("/coroutine/two", test_coroutine_two);
+ g_test_add_func("/coroutine/yield", test_coroutine_yield);
+
+ return g_test_run ();
+}
--- /dev/null
+#include <gio/gio.h>
+
+#include "spice-file-transfer-task-priv.h"
+
+typedef struct _Fixture {
+ GFile **files;
+ guint num_files;
+ guint num_files_done;
+ GCancellable *cancellable;
+ GMainLoop *loop;
+ GHashTable *xfer_tasks;
+} Fixture;
+
+typedef struct _AgentAsync {
+ SpiceFileTransferTask *xfer_task;
+ VDAgentFileXferStatusMessage msg;
+} AgentAsync;
+
+#define SINGLE_FILE 1
+#define MULTIPLE_FILES 10
+
+#define T10ns (G_TIME_SPAN_MILLISECOND / 100)
+
+const gchar content[] = "0123456789_spice-file-transfer-task";
+
+static void
+f_setup(Fixture *f, gconstpointer user_data)
+{
+ guint i;
+ GError *err = NULL;
+
+ f->loop = g_main_loop_new(NULL, FALSE);
+ f->num_files = GPOINTER_TO_UINT(user_data);
+ f->num_files_done = 0;
+ f->files = g_new0(GFile *, f->num_files + 1);
+ f->cancellable = g_cancellable_new();
+ for (i = 0; i < f->num_files; i++) {
+ gboolean success;
+ GFileIOStream *iostream;
+
+ f->files[i] = g_file_new_tmp("spice-file-transfer-XXXXXX", &iostream, &err);
+ g_assert_no_error(err);
+ g_assert_nonnull(iostream);
+ g_clear_object(&iostream);
+
+ success = g_file_replace_contents (f->files[i], content, strlen(content), NULL, FALSE,
+ G_FILE_CREATE_NONE, NULL, f->cancellable, &err);
+ g_assert_no_error(err);
+ g_assert_true(success);
+ }
+}
+
+static void
+f_teardown(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ guint i;
+ GError *err = NULL;
+
+ g_main_loop_unref(f->loop);
+ g_clear_object(&f->cancellable);
+ g_clear_pointer(&f->xfer_tasks, g_hash_table_unref);
+
+ for (i = 0; i < f->num_files; i++) {
+ g_file_delete(f->files[i], NULL, &err);
+ g_assert_no_error(err);
+ g_object_unref(f->files[i]);
+ }
+ g_clear_pointer(&f->files, g_free);
+}
+
+/*******************************************************************************
+ * TEST SIMPLE TRANSFER
+ ******************************************************************************/
+static void
+transfer_xfer_task_on_finished(SpiceFileTransferTask *xfer_task G_GNUC_UNUSED,
+ GError *error G_GNUC_UNUSED,
+ gpointer user_data)
+{
+ Fixture *f = user_data;
+
+ f->num_files_done++;
+ if (f->num_files == f->num_files_done)
+ g_main_loop_quit(f->loop);
+}
+
+static void
+transfer_read_async_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ SpiceFileTransferTask *xfer_task;
+ gssize count;
+ char *buffer;
+ GError *error = NULL;
+
+ xfer_task = SPICE_FILE_TRANSFER_TASK(source_object);
+ count = spice_file_transfer_task_read_finish(xfer_task, res, &buffer, &error);
+ g_assert_no_error(error);
+
+ if (count == 0) {
+ spice_file_transfer_task_completed(xfer_task, NULL);
+ return;
+ }
+
+ spice_file_transfer_task_read_async(xfer_task, transfer_read_async_cb, NULL);
+}
+
+static void
+transfer_init_async_cb(GObject *obj, GAsyncResult *res, gpointer data G_GNUC_UNUSED)
+{
+ GFileInfo *info;
+ SpiceFileTransferTask *xfer_task;
+ GError *error = NULL;
+
+ xfer_task = SPICE_FILE_TRANSFER_TASK(obj);
+ info = spice_file_transfer_task_init_task_finish(xfer_task, res, &error);
+ g_assert_no_error(error);
+ g_assert_nonnull(info);
+ g_object_unref(info);
+
+ /* read file loop */
+ spice_file_transfer_task_read_async(xfer_task, transfer_read_async_cb, NULL);
+}
+
+static void
+test_simple_transfer(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ f->xfer_tasks = spice_file_transfer_task_create_tasks(f->files, NULL, G_FILE_COPY_NONE, f->cancellable);
+ g_hash_table_iter_init(&iter, f->xfer_tasks);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ SpiceFileTransferTask *xfer_task = SPICE_FILE_TRANSFER_TASK(value);
+ g_signal_connect(xfer_task, "finished", G_CALLBACK(transfer_xfer_task_on_finished), f);
+ spice_file_transfer_task_init_task_async(xfer_task, transfer_init_async_cb, NULL);
+ }
+ g_main_loop_run (f->loop);
+}
+
+/*******************************************************************************
+ * TEST CANCEL ON INIT TASK
+ ******************************************************************************/
+static void
+transfer_cancelled_on_init_async_cb(GObject *obj, GAsyncResult *res, gpointer data)
+{
+ GFileInfo *info;
+ SpiceFileTransferTask *xfer_task;
+ GError *error = NULL;
+
+ xfer_task = SPICE_FILE_TRANSFER_TASK(obj);
+ info = spice_file_transfer_task_init_task_finish(xfer_task, res, &error);
+ g_assert_error(error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
+ g_assert_null(info);
+ g_clear_error(&error);
+
+ transfer_xfer_task_on_finished(NULL, NULL, data);
+}
+
+static void
+test_cancel_before_task_init(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ f->xfer_tasks = spice_file_transfer_task_create_tasks(f->files, NULL, G_FILE_COPY_NONE, f->cancellable);
+ g_hash_table_iter_init(&iter, f->xfer_tasks);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ SpiceFileTransferTask *xfer_task = SPICE_FILE_TRANSFER_TASK(value);
+ g_signal_connect(xfer_task, "finished", G_CALLBACK(transfer_xfer_task_on_finished), f);
+ g_cancellable_cancel(f->cancellable);
+ spice_file_transfer_task_init_task_async(xfer_task, transfer_cancelled_on_init_async_cb, f);
+ }
+ g_main_loop_run (f->loop);
+}
+
+static void
+test_cancel_after_task_init(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ f->xfer_tasks = spice_file_transfer_task_create_tasks(f->files, NULL, G_FILE_COPY_NONE, f->cancellable);
+ g_hash_table_iter_init(&iter, f->xfer_tasks);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ SpiceFileTransferTask *xfer_task = SPICE_FILE_TRANSFER_TASK(value);
+ g_signal_connect(xfer_task, "finished", G_CALLBACK(transfer_xfer_task_on_finished), f);
+ spice_file_transfer_task_init_task_async(xfer_task, transfer_cancelled_on_init_async_cb, f);
+ g_cancellable_cancel(f->cancellable);
+ }
+ g_main_loop_run (f->loop);
+}
+
+/*******************************************************************************
+ * TEST CANCEL ON READ ASYNC
+ ******************************************************************************/
+
+static void
+transfer_cancelled_read_async_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceFileTransferTask *xfer_task;
+ gssize count;
+ char *buffer;
+ GError *error = NULL;
+
+ xfer_task = SPICE_FILE_TRANSFER_TASK(source_object);
+ count = spice_file_transfer_task_read_finish(xfer_task, res, &buffer, &error);
+ g_assert_error(error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
+ g_assert_cmpint(count, ==, -1);
+ g_clear_error(&error);
+
+ transfer_xfer_task_on_finished(NULL, NULL, user_data);
+}
+
+static void
+transfer_on_init_async_cb_before_read_cancel(GObject *obj, GAsyncResult *res, gpointer data)
+{
+ GFileInfo *info;
+ SpiceFileTransferTask *xfer_task;
+ GError *error = NULL;
+ GCancellable *cancellable;
+
+ xfer_task = SPICE_FILE_TRANSFER_TASK(obj);
+ info = spice_file_transfer_task_init_task_finish(xfer_task, res, &error);
+ g_assert_no_error(error);
+ g_assert_nonnull(info);
+ g_object_unref(info);
+
+ cancellable = spice_file_transfer_task_get_cancellable(xfer_task);
+ g_cancellable_cancel(cancellable);
+ spice_file_transfer_task_read_async(xfer_task, transfer_cancelled_read_async_cb, data);
+}
+
+static void
+transfer_on_init_async_cb_after_read_cancel(GObject *obj, GAsyncResult *res, gpointer data)
+{
+ GFileInfo *info;
+ SpiceFileTransferTask *xfer_task;
+ GError *error = NULL;
+ GCancellable *cancellable;
+
+ xfer_task = SPICE_FILE_TRANSFER_TASK(obj);
+ info = spice_file_transfer_task_init_task_finish(xfer_task, res, &error);
+ g_assert_no_error(error);
+ g_assert_nonnull(info);
+ g_object_unref(info);
+
+ cancellable = spice_file_transfer_task_get_cancellable(xfer_task);
+ spice_file_transfer_task_read_async(xfer_task, transfer_cancelled_read_async_cb, data);
+ g_cancellable_cancel(cancellable);
+}
+
+static void
+test_cancel_before_read_async(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ f->xfer_tasks = spice_file_transfer_task_create_tasks(f->files, NULL, G_FILE_COPY_NONE, NULL);
+ g_hash_table_iter_init(&iter, f->xfer_tasks);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ SpiceFileTransferTask *xfer_task = SPICE_FILE_TRANSFER_TASK(value);
+ g_signal_connect(xfer_task, "finished", G_CALLBACK(transfer_xfer_task_on_finished), f);
+ spice_file_transfer_task_init_task_async(xfer_task, transfer_on_init_async_cb_before_read_cancel, f);
+ }
+ g_main_loop_run (f->loop);
+}
+
+static void
+test_cancel_after_read_async(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ f->xfer_tasks = spice_file_transfer_task_create_tasks(f->files, NULL, G_FILE_COPY_NONE, NULL);
+ g_hash_table_iter_init(&iter, f->xfer_tasks);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ SpiceFileTransferTask *xfer_task = SPICE_FILE_TRANSFER_TASK(value);
+ g_signal_connect(xfer_task, "finished", G_CALLBACK(transfer_xfer_task_on_finished), f);
+ spice_file_transfer_task_init_task_async(xfer_task, transfer_on_init_async_cb_after_read_cancel, f);
+ }
+ g_main_loop_run (f->loop);
+}
+
+/*******************************************************************************
+ * TEST AGENT CANCEL ON READ
+ ******************************************************************************/
+
+static void
+transfer_agent_cancelled_read_async_cb(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SpiceFileTransferTask *xfer_task;
+ gssize count;
+ char *buffer;
+ GError *error = NULL;
+
+ xfer_task = SPICE_FILE_TRANSFER_TASK(source_object);
+ count = spice_file_transfer_task_read_finish(xfer_task, res, &buffer, &error);
+ g_assert_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED);
+ g_assert_cmpint(count, ==, -1);
+ g_clear_error(&error);
+
+ transfer_xfer_task_on_finished(NULL, NULL, user_data);
+}
+
+static void
+transfer_on_init_async_cb_agent_cancel(GObject *obj, GAsyncResult *res, gpointer data)
+{
+ GFileInfo *info;
+ SpiceFileTransferTask *xfer_task;
+ GError *error = NULL;
+
+ xfer_task = SPICE_FILE_TRANSFER_TASK(obj);
+ info = spice_file_transfer_task_init_task_finish(xfer_task, res, &error);
+ g_assert_no_error(error);
+ g_assert_nonnull(info);
+ g_object_unref(info);
+
+ spice_file_transfer_task_read_async(xfer_task, transfer_agent_cancelled_read_async_cb, data);
+
+ error = g_error_new(SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "transfer is cancelled by spice agent");
+ spice_file_transfer_task_completed(xfer_task, error);
+}
+
+static void
+test_agent_cancel_on_read(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ f->xfer_tasks = spice_file_transfer_task_create_tasks(f->files, NULL, G_FILE_COPY_NONE, NULL);
+ g_hash_table_iter_init(&iter, f->xfer_tasks);
+ while (g_hash_table_iter_next(&iter, &key, &value)) {
+ SpiceFileTransferTask *xfer_task = SPICE_FILE_TRANSFER_TASK(value);
+ g_signal_connect(xfer_task, "finished", G_CALLBACK(transfer_xfer_task_on_finished), f);
+ spice_file_transfer_task_init_task_async(xfer_task, transfer_on_init_async_cb_agent_cancel, f);
+ }
+ g_main_loop_run (f->loop);
+}
+
+/* Tests summary:
+ *
+ * This tests are specific to SpiceFileTransferTask in order to verify:
+ * - Cancelation from User;
+ * - Error/Cancelation from Agent;
+ * - Bad behavior from Agent;
+ *
+ * SpiceFileTransferTask is in charge of initializing, reading and finalizing
+ * all IO for the file user wants to transfer but being unaware of how the
+ * protocol works. As there are several combinations of events, these tests
+ * intend to find errors, leaks and crashes on SpiceFileTransferTask in common
+ * set of events in order to avoid regression in the drag-and-drop feature.
+ *
+ * Small overview of how File Transfer works.
+ *
+ * 1.) User calls spice_main_file_copy_async with a list of files to send to the
+ * guest
+ * 2.) SpiceMainChannel creates a SpiceFileTransferTask per File and request its
+ * initialization using spice_file_transfer_task_init_task_async(). The init
+ * function will open a GFileInputStream and request the GFileInfo of file;
+ * 3.) Using the GFileInfo object, SpiceMainChannel starts the File Transfer
+ * protocol with VD_AGENT_FILE_XFER_START. Agent responds with
+ * VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA which starts the read IO using
+ * spice_file_transfer_task_read_async()
+ * 4.) After the read is done, SpiceMainChannel does an async flush to the
+ * agent, using the buffer provided by SpiceFileTransferTask; The read IO
+ * will be kept going while SpiceMainChannel has agent tokens to use.
+ * 5-) After SpiceMainChannel sends enough data, it can always receive:
+ * - VD_AGENT_FILE_XFER_STATUS_CAN_SEND_DATA: to send more data;
+ * - VD_AGENT_FILE_XFER_STATUS_SUCCESS: all data was sent;
+ * - VD_AGENT_FILE_XFER_STATUS_ERROR: unexpected behavior on agent side;
+ * - VD_AGENT_FILE_XFER_STATUS_CANCELLED: transfer was cancelled by agent;
+ * 6-) In any case of termination, the following SpiceFileTransferTask function
+ * should always be called: spice_file_transfer_task_completed(); This will
+ * trigger from SpiceFileTransferTask all necessary events to finalize user
+ * side, memory allocation and so on.
+ */
+int main(int argc, char* argv[])
+{
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add("/spice-file-transfer-task/single/simple-transfer",
+ Fixture, GUINT_TO_POINTER(SINGLE_FILE),
+ f_setup, test_simple_transfer, f_teardown);
+
+ g_test_add("/spice-file-transfer-task/single/cancel/before-task-init",
+ Fixture, GUINT_TO_POINTER(SINGLE_FILE),
+ f_setup, test_cancel_before_task_init, f_teardown);
+
+ g_test_add("/spice-file-transfer-task/single/cancel/after-task-init",
+ Fixture, GUINT_TO_POINTER(SINGLE_FILE),
+ f_setup, test_cancel_after_task_init, f_teardown);
+
+ g_test_add("/spice-file-transfer-task/single/cancel/before-read-async",
+ Fixture, GUINT_TO_POINTER(SINGLE_FILE),
+ f_setup, test_cancel_before_read_async, f_teardown);
+
+ g_test_add("/spice-file-transfer-task/single/cancel/after-read-async",
+ Fixture, GUINT_TO_POINTER(SINGLE_FILE),
+ f_setup, test_cancel_after_read_async, f_teardown);
+
+ g_test_add("/spice-file-transfer-task/single/agent/cancel",
+ Fixture, GUINT_TO_POINTER(SINGLE_FILE),
+ f_setup, test_agent_cancel_on_read, f_teardown);
+
+ g_test_add("/spice-file-transfer-task/multiple/simple-transfer",
+ Fixture, GUINT_TO_POINTER(MULTIPLE_FILES),
+ f_setup, test_simple_transfer, f_teardown);
+
+ g_test_add("/spice-file-transfer-task/multiple/cancel/before-task-init",
+ Fixture, GUINT_TO_POINTER(MULTIPLE_FILES),
+ f_setup, test_cancel_before_task_init, f_teardown);
+
+ g_test_add("/spice-file-transfer-task/multiple/cancel/after-task-init",
+ Fixture, GUINT_TO_POINTER(MULTIPLE_FILES),
+ f_setup, test_cancel_after_task_init, f_teardown);
+
+ g_test_add("/spice-file-transfer-task/multiple/cancel/before--read-async",
+ Fixture, GUINT_TO_POINTER(MULTIPLE_FILES),
+ f_setup, test_cancel_before_read_async, f_teardown);
+
+ g_test_add("/spice-file-transfer-task/multiple/cancel/after-read-async",
+ Fixture, GUINT_TO_POINTER(MULTIPLE_FILES),
+ f_setup, test_cancel_after_read_async, f_teardown);
+
+ g_test_add("/spice-file-transfer-task/multiple/agent/cancel",
+ Fixture, GUINT_TO_POINTER(MULTIPLE_FILES),
+ f_setup, test_agent_cancel_on_read, f_teardown);
+
+ return g_test_run();
+}
--- /dev/null
+/*
+ Copyright (C) 2016 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <glib.h>
+#include <gio/gunixinputstream.h>
+
+static int exit_status;
+static GMainLoop *loop;
+static GDataInputStream *stdin_stream;
+
+static void cleanup(void)
+{
+ if (loop)
+ g_main_loop_quit(loop);
+}
+
+
+static void stdin_read_complete(GObject *src, GAsyncResult *res, gpointer data G_GNUC_UNUSED)
+{
+ char *s = NULL;
+ const char *response = NULL;
+ GError *err = NULL;
+ gsize len;
+
+ s = g_data_input_stream_read_line_finish(G_DATA_INPUT_STREAM(src), res,
+ &len, &err);
+
+ /* exit the program to return an early EOF to the caller */
+ if (g_getenv("TEST_EOF"))
+ goto done;
+
+ /* Don't return any response, but continue running to simulate a
+ * unresponsive binary */
+ if (g_getenv("TEST_NORESPONSE"))
+ return;
+
+ /* specify a particular resonse to be returned to the caller */
+ response = g_getenv("TEST_RESPONSE");
+ if (!response)
+ response = "SUCCESS";
+
+ fprintf(stdout, "%s\n", response);
+ fflush(stdout);
+
+done:
+ g_clear_error(&err);
+ g_free(s);
+ cleanup();
+}
+
+int main(void)
+{
+ GInputStream *stdin_unix_stream;
+
+ loop = g_main_loop_new(NULL, FALSE);
+
+ stdin_unix_stream = g_unix_input_stream_new(STDIN_FILENO, 0);
+ stdin_stream = g_data_input_stream_new(stdin_unix_stream);
+ g_data_input_stream_set_newline_type(stdin_stream,
+ G_DATA_STREAM_NEWLINE_TYPE_LF);
+ g_clear_object(&stdin_unix_stream);
+ g_data_input_stream_read_line_async(stdin_stream, G_PRIORITY_DEFAULT, NULL,
+ stdin_read_complete, NULL);
+
+ g_main_loop_run(loop);
+
+ g_object_unref(stdin_stream);
+ g_main_loop_unref(loop);
+
+ return exit_status;
+}
--- /dev/null
+#include <glib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <locale.h>
+
+#include "giopipe.h"
+
+typedef struct _Fixture {
+ GIOStream *p1;
+ GIOStream *p2;
+
+ GInputStream *ip1;
+ GOutputStream *op1;
+ GInputStream *ip2;
+ GOutputStream *op2;
+
+ gchar buf[16];
+ gchar *data;
+ guint16 data_len;
+ guint16 read_size;
+ guint16 total_read;
+
+ GList *sources;
+
+ GMainLoop *loop;
+ GCancellable *cancellable;
+ guint timeout;
+} Fixture;
+
+static gboolean
+stop_loop (gpointer data)
+{
+ GMainLoop *loop = data;
+
+ g_main_loop_quit (loop);
+ g_assert_not_reached();
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+fixture_set_up(Fixture *fixture,
+ gconstpointer user_data G_GNUC_UNUSED)
+{
+ unsigned int i;
+
+ spice_make_pipe(&fixture->p1, &fixture->p2);
+ g_assert_true(G_IS_IO_STREAM(fixture->p1));
+ g_assert_true(G_IS_IO_STREAM(fixture->p2));
+
+ fixture->op1 = g_io_stream_get_output_stream(fixture->p1);
+ g_assert_true(G_IS_OUTPUT_STREAM(fixture->op1));
+ fixture->ip1 = g_io_stream_get_input_stream(fixture->p1);
+ g_assert_true(G_IS_INPUT_STREAM(fixture->ip1));
+ fixture->op2 = g_io_stream_get_output_stream(fixture->p2);
+ g_assert_true(G_IS_OUTPUT_STREAM(fixture->op2));
+ fixture->ip2 = g_io_stream_get_input_stream(fixture->p2);
+ g_assert_true(G_IS_INPUT_STREAM(fixture->ip2));
+
+ for (i = 0; i < sizeof(fixture->buf); i++) {
+ fixture->buf[i] = 0x42 + i;
+ }
+
+ fixture->sources = NULL;
+ fixture->cancellable = g_cancellable_new();
+ fixture->loop = g_main_loop_new (NULL, FALSE);
+ fixture->timeout = g_timeout_add (1000, stop_loop, fixture->loop);
+}
+
+static void
+fixture_tear_down(Fixture *fixture,
+ gconstpointer user_data G_GNUC_UNUSED)
+{
+ g_clear_object(&fixture->p1);
+ g_clear_object(&fixture->p2);
+
+ if (fixture->sources)
+ g_list_free_full(fixture->sources, (GDestroyNotify) g_source_unref);
+
+ g_clear_pointer(&fixture->data, g_free);
+ g_clear_object(&fixture->cancellable);
+ g_source_remove(fixture->timeout);
+ g_main_loop_unref(fixture->loop);
+}
+
+static void
+test_pipe_readblock(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ GError *error = NULL;
+ gssize size;
+
+ size = g_input_stream_read(f->ip2, f->buf, 1,
+ f->cancellable, &error);
+
+ g_assert_cmpint(size, ==, -1);
+ g_assert_error(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
+
+ g_clear_error(&error);
+}
+
+static void
+test_pipe_writeblock(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ GError *error = NULL;
+ gssize size;
+
+ size = g_output_stream_write(f->op1, "", 1,
+ f->cancellable, &error);
+
+ g_assert_cmpint(size, ==, -1);
+ g_assert_error(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
+
+ g_clear_error(&error);
+}
+
+static void
+write_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ GError *error = NULL;
+ GMainLoop *loop = user_data;
+ gssize nbytes;
+
+ nbytes = g_output_stream_write_finish(G_OUTPUT_STREAM(source), result, &error);
+
+ g_assert_no_error(error);
+ g_assert_cmpint(nbytes, >, 0);
+ g_clear_error(&error);
+
+ g_main_loop_quit (loop);
+}
+
+static void
+read_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ GError *error = NULL;
+ gssize nbytes, expected = GPOINTER_TO_INT(user_data);
+
+ nbytes = g_input_stream_read_finish(G_INPUT_STREAM(source), result, &error);
+
+ g_assert_cmpint(nbytes, ==, expected);
+ g_assert_no_error(error);
+ g_clear_error(&error);
+}
+
+static void
+test_pipe_writeread(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ g_output_stream_write_async(f->op1, "", 1, G_PRIORITY_DEFAULT,
+ f->cancellable, write_cb, f->loop);
+ g_input_stream_read_async(f->ip2, f->buf, 1, G_PRIORITY_DEFAULT,
+ f->cancellable, read_cb, GINT_TO_POINTER(1));
+
+ g_main_loop_run (f->loop);
+
+ g_output_stream_write_async(f->op1, "", 1, G_PRIORITY_DEFAULT,
+ f->cancellable, write_cb, f->loop);
+ g_input_stream_read_async(f->ip2, f->buf, 1, G_PRIORITY_DEFAULT,
+ f->cancellable, read_cb, GINT_TO_POINTER(1));
+
+ g_main_loop_run (f->loop);
+}
+
+static void
+test_pipe_readwrite(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ g_input_stream_read_async(f->ip2, f->buf, 1, G_PRIORITY_DEFAULT,
+ f->cancellable, read_cb, GINT_TO_POINTER(1));
+ g_output_stream_write_async(f->op1, "", 1, G_PRIORITY_DEFAULT,
+ f->cancellable, write_cb, f->loop);
+
+ g_main_loop_run (f->loop);
+}
+
+static void
+test_pipe_write16read8(Fixture *f, gconstpointer user_data)
+{
+ g_output_stream_write_async(f->op1, "0123456789abcdef", 16, G_PRIORITY_DEFAULT,
+ f->cancellable, write_cb, f->loop);
+ g_input_stream_read_async(f->ip2, f->buf, 8, G_PRIORITY_DEFAULT,
+ f->cancellable, read_cb, GINT_TO_POINTER(8));
+
+ g_main_loop_run (f->loop);
+
+ /* check next read would block */
+ test_pipe_readblock(f, user_data);
+}
+
+static void
+test_pipe_write8read16(Fixture *f, gconstpointer user_data)
+{
+ g_output_stream_write_async(f->op1, "01234567", 8, G_PRIORITY_DEFAULT,
+ f->cancellable, write_cb, f->loop);
+ g_input_stream_read_async(f->ip2, f->buf, 16, G_PRIORITY_DEFAULT,
+ f->cancellable, read_cb, GINT_TO_POINTER(8));
+
+ g_main_loop_run (f->loop);
+
+ /* check next read would block */
+ test_pipe_writeblock(f, user_data);
+}
+
+static void
+readclose_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ GError *error = NULL;
+ gssize nbytes;
+ GMainLoop *loop = user_data;
+
+ nbytes = g_input_stream_read_finish(G_INPUT_STREAM(source), result, &error);
+
+ g_assert_cmpint(nbytes, ==, -1);
+ g_assert_error(error, G_IO_ERROR, G_IO_ERROR_CLOSED);
+ g_clear_error(&error);
+
+ g_main_loop_quit (loop);
+}
+
+static void
+test_pipe_readclosestream(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ GError *error = NULL;
+
+ g_input_stream_read_async(f->ip2, f->buf, 1, G_PRIORITY_DEFAULT,
+ f->cancellable, readclose_cb, f->loop);
+ g_io_stream_close(f->p1, f->cancellable, &error);
+
+ g_main_loop_run (f->loop);
+}
+
+static void
+test_pipe_readclose(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ GError *error = NULL;
+
+ g_input_stream_read_async(f->ip2, f->buf, 1, G_PRIORITY_DEFAULT,
+ f->cancellable, readclose_cb, f->loop);
+ g_output_stream_close(f->op1, f->cancellable, &error);
+
+ g_main_loop_run (f->loop);
+}
+
+static void
+readcancel_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ GError *error = NULL;
+ gssize nbytes;
+ GMainLoop *loop = user_data;
+
+ nbytes = g_input_stream_read_finish(G_INPUT_STREAM(source), result, &error);
+
+ g_assert_cmpint(nbytes, ==, -1);
+ g_assert_error(error, G_IO_ERROR, G_IO_ERROR_CLOSED);
+ g_clear_error(&error);
+
+ g_main_loop_quit (loop);
+}
+
+static void
+test_pipe_readcancel(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ GError *error = NULL;
+
+ g_input_stream_read_async(f->ip2, f->buf, 1, G_PRIORITY_DEFAULT,
+ f->cancellable, readcancel_cb, f->loop);
+ g_output_stream_close(f->op1, f->cancellable, &error);
+
+ g_main_loop_run (f->loop);
+}
+
+static gchar *
+get_test_data(gint n)
+{
+ GString *s = g_string_sized_new(n);
+ const gchar *data = "01234567abcdefgh";
+ gint i, q;
+
+ q = n / 16;
+ for (i = 0; i < q; i++)
+ s = g_string_append(s, data);
+
+ s = g_string_append_len(s, data, (n % 16));
+ return g_string_free(s, FALSE);
+}
+
+static void
+write_all_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Fixture *f = user_data;
+ GError *error = NULL;
+ gsize nbytes;
+
+ g_output_stream_write_all_finish(G_OUTPUT_STREAM(source), result, &nbytes, &error);
+ g_assert_no_error(error);
+ g_assert_cmpint(nbytes, ==, f->data_len);
+ g_clear_error(&error);
+
+ g_main_loop_quit (f->loop);
+}
+
+static void
+read_chunk_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Fixture *f = user_data;
+ GError *error = NULL;
+ gssize nbytes;
+ gboolean data_match;
+
+ nbytes = g_input_stream_read_finish(G_INPUT_STREAM(source), result, &error);
+ g_assert_no_error(error);
+ g_assert_cmpint(nbytes, >, 0);
+ data_match = (g_ascii_strncasecmp(f->data + f->total_read, f->buf, nbytes) == 0);
+ g_assert_true(data_match);
+
+ f->total_read += nbytes;
+ if (f->total_read != f->data_len) {
+ g_input_stream_read_async(f->ip2, f->buf, f->read_size, G_PRIORITY_DEFAULT,
+ f->cancellable, read_chunk_cb, f);
+ }
+}
+
+static void
+test_pipe_write_all_64_read_chunks_16(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ f->data_len = 64;
+ f->data = get_test_data(f->data_len);
+ f->read_size = 16;
+ f->total_read = 0;
+
+ g_output_stream_write_all_async(f->op1, f->data, f->data_len, G_PRIORITY_DEFAULT,
+ f->cancellable, write_all_cb, f);
+ g_input_stream_read_async(f->ip2, f->buf, f->read_size, G_PRIORITY_DEFAULT,
+ f->cancellable, read_chunk_cb, f);
+ g_main_loop_run (f->loop);
+}
+
+static void
+read_chunk_cb_and_try_write(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Fixture *f = user_data;
+ GError *error = NULL;
+ gssize nbytes;
+ gboolean data_match;
+
+ nbytes = g_input_stream_read_finish(G_INPUT_STREAM(source), result, &error);
+ g_assert_no_error(error);
+ g_assert_cmpint(nbytes, >, 0);
+ data_match = (g_ascii_strncasecmp(f->data + f->total_read, f->buf, nbytes) == 0);
+ g_assert_true(data_match);
+
+ f->total_read += nbytes;
+ if (f->total_read != f->data_len) {
+ /* try write before reading another chunk */
+ g_output_stream_write(f->op1, "", 1, f->cancellable, &error);
+ g_assert_error(error, G_IO_ERROR, G_IO_ERROR_PENDING);
+ g_clear_error(&error);
+
+ g_input_stream_read_async(f->ip2, f->buf, f->read_size, G_PRIORITY_DEFAULT,
+ f->cancellable, read_chunk_cb_and_try_write, f);
+ }
+}
+
+static void
+test_pipe_concurrent_write(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ f->data_len = 64;
+ f->data = get_test_data(f->data_len);
+ f->read_size = 16;
+ f->total_read = 0;
+
+ g_output_stream_write_all_async(f->op1, f->data, f->data_len, G_PRIORITY_DEFAULT,
+ f->cancellable, write_all_cb, f);
+ g_input_stream_read_async(f->ip2, f->buf, f->read_size, G_PRIORITY_DEFAULT,
+ f->cancellable, read_chunk_cb_and_try_write, f);
+ g_main_loop_run (f->loop);
+}
+
+static void
+write_all_cb_zombie_check(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Fixture *f = user_data;
+ GError *error = NULL;
+ gsize nbytes;
+ GList *it;
+
+ g_output_stream_write_all_finish(G_OUTPUT_STREAM(source), result, &nbytes, &error);
+ g_assert_no_error(error);
+ g_assert_cmpint(nbytes, ==, f->data_len);
+ g_clear_error(&error);
+
+ for (it = f->sources; it != NULL; it = it->next) {
+ GSource *s = it->data;
+ g_assert_true (g_source_is_destroyed (s));
+ }
+
+ g_main_loop_quit (f->loop);
+}
+
+static gboolean
+source_cb (gpointer user_data G_GNUC_UNUSED)
+{
+ return G_SOURCE_REMOVE;
+}
+
+#define NUM_OF_DUMMY_GSOURCE 1000
+
+static void
+read_chunk_cb_and_do_zombie(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Fixture *f = user_data;
+ GError *error = NULL;
+ gssize nbytes;
+ gboolean data_match, try_zombie;
+ gint i;
+
+ nbytes = g_input_stream_read_finish(G_INPUT_STREAM(source), result, &error);
+ g_assert_no_error(error);
+ g_assert_cmpint(nbytes, >, 0);
+ data_match = (g_ascii_strncasecmp(f->data + f->total_read, f->buf, nbytes) == 0);
+ g_assert_true(data_match);
+
+ /* Simulate more Pollable GSources created to read from Pipe; This should
+ * not fail but giopipe does not allow concurrent read/write which means
+ * that only the *last* GSource created will be the one that does the actual
+ * read; The other GSources that are still active should be dispatched.
+ * (In this test, only the real GSource created in g_input_stream_read_async
+ * will read the data) */
+
+ /* Create GSources in all iterations besides the last one, simply because
+ * it is convenient! The execution of the last interaction should give enough
+ * time for for all dummy GSources being detached. */
+ f->total_read += nbytes;
+ try_zombie = (f->total_read + f->read_size < f->data_len);
+
+ if (try_zombie) {
+ for (i = 0; i < NUM_OF_DUMMY_GSOURCE/2; i++) {
+ GSource *s = g_pollable_input_stream_create_source(G_POLLABLE_INPUT_STREAM(f->ip2), NULL);
+ g_source_set_callback(s, source_cb, NULL, NULL);
+ g_source_attach(s, NULL);
+ f->sources = g_list_prepend(f->sources, s);
+ }
+ }
+
+ if (f->total_read != f->data_len)
+ g_input_stream_read_async(f->ip2, f->buf, f->read_size, G_PRIORITY_DEFAULT,
+ f->cancellable, read_chunk_cb_and_do_zombie, f);
+
+ if (try_zombie) {
+ for (i = 0; i < NUM_OF_DUMMY_GSOURCE/2; i++) {
+ GSource *s = g_pollable_input_stream_create_source(G_POLLABLE_INPUT_STREAM(f->ip2), NULL);
+ g_source_set_callback(s, source_cb, NULL, NULL);
+ g_source_attach(s, NULL);
+ f->sources = g_list_prepend(f->sources, s);
+ }
+ }
+}
+
+static void
+test_pipe_zombie_sources(Fixture *f, gconstpointer user_data G_GNUC_UNUSED)
+{
+ f->data_len = 64;
+ f->data = get_test_data(f->data_len);
+ f->read_size = 16;
+ f->total_read = 0;
+
+ g_output_stream_write_all_async(f->op1, f->data, f->data_len, G_PRIORITY_DEFAULT,
+ f->cancellable, write_all_cb_zombie_check, f);
+ g_input_stream_read_async(f->ip2, f->buf, f->read_size, G_PRIORITY_DEFAULT,
+ f->cancellable, read_chunk_cb_and_do_zombie, f);
+ g_main_loop_run (f->loop);
+}
+
+int main(int argc, char* argv[])
+{
+ setlocale(LC_ALL, "");
+
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add("/pipe/readblock", Fixture, NULL,
+ fixture_set_up, test_pipe_readblock,
+ fixture_tear_down);
+
+ g_test_add("/pipe/writeblock", Fixture, NULL,
+ fixture_set_up, test_pipe_writeblock,
+ fixture_tear_down);
+
+ g_test_add("/pipe/writeread", Fixture, NULL,
+ fixture_set_up, test_pipe_writeread,
+ fixture_tear_down);
+
+ g_test_add("/pipe/readwrite", Fixture, NULL,
+ fixture_set_up, test_pipe_readwrite,
+ fixture_tear_down);
+
+ g_test_add("/pipe/write16read8", Fixture, NULL,
+ fixture_set_up, test_pipe_write16read8,
+ fixture_tear_down);
+
+ g_test_add("/pipe/write8read16", Fixture, NULL,
+ fixture_set_up, test_pipe_write8read16,
+ fixture_tear_down);
+
+ g_test_add("/pipe/write-all64-read-chunks16", Fixture, NULL,
+ fixture_set_up, test_pipe_write_all_64_read_chunks_16,
+ fixture_tear_down);
+
+ g_test_add("/pipe/concurrent-write", Fixture, NULL,
+ fixture_set_up, test_pipe_concurrent_write,
+ fixture_tear_down);
+
+ g_test_add("/pipe/zombie-sources", Fixture, NULL,
+ fixture_set_up, test_pipe_zombie_sources,
+ fixture_tear_down);
+
+ g_test_add("/pipe/readclosestream", Fixture, NULL,
+ fixture_set_up, test_pipe_readclosestream,
+ fixture_tear_down);
+
+ g_test_add("/pipe/readclose", Fixture, NULL,
+ fixture_set_up, test_pipe_readclose,
+ fixture_tear_down);
+
+ g_test_add("/pipe/readcancel", Fixture, NULL,
+ fixture_set_up, test_pipe_readcancel,
+ fixture_tear_down);
+
+ return g_test_run();
+}
--- /dev/null
+#include <spice-client.h>
+
+static void test_session_uri(void)
+{
+ SpiceSession *s;
+ guint i;
+
+ struct {
+ gchar *port;
+ gchar *tls_port;
+ gchar *uri_input;
+ gchar *uri_output;
+ } tests[] = {
+ /* Arguments with empty value */
+ { "5900", NULL,
+ "spice://localhost?port=5900&tls-port=",
+ "spice://localhost?port=5900&" },
+ { "5910", NULL,
+ "spice://localhost?tls-port=&port=5910",
+ "spice://localhost?port=5910&" },
+ { NULL, "5920",
+ "spice://localhost?tls-port=5920&port=",
+ "spice://localhost?tls-port=5920" },
+ { NULL, "5930",
+ "spice://localhost?port=&tls-port=5930",
+ "spice://localhost?tls-port=5930" },
+ };
+
+ /* Set URI and check URI, port and tls_port */
+ for (i = 0; i < G_N_ELEMENTS(tests); i++) {
+ gchar *uri, *port, *tls_port;
+
+ s = spice_session_new();
+ g_object_set(s, "uri", tests[i].uri_input, NULL);
+ g_object_get(s,
+ "uri", &uri,
+ "port", &port,
+ "tls-port", &tls_port,
+ NULL);
+ g_assert_cmpstr(tests[i].uri_output, ==, uri);
+ g_assert_cmpstr(tests[i].port, ==, port);
+ g_assert_cmpstr(tests[i].tls_port, ==, tls_port);
+ g_clear_pointer(&uri, g_free);
+ g_clear_pointer(&port, g_free);
+ g_clear_pointer(&tls_port, g_free);
+ g_object_unref(s);
+ }
+
+ /* Set port and tls_port, check URI */
+ for (i = 0; i < G_N_ELEMENTS(tests); i++) {
+ gchar *uri;
+
+ s = spice_session_new();
+ g_object_set(s,
+ "port", tests[i].port,
+ "tls-port", tests[i].tls_port,
+ NULL);
+ g_object_get(s, "uri", &uri, NULL);
+ g_assert_cmpstr(tests[i].uri_output, ==, uri);
+ g_clear_pointer(&uri, g_free);
+ g_object_unref(s);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add_func("/session/uri", test_session_uri);
+
+ return g_test_run();
+}
--- /dev/null
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ Copyright (C) 2016 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#include <glib.h>
+#include <spice-client.h>
+#include "spice-uri-priv.h"
+
+/* GLIB_CHECK_VERSION(2, 40, 0) */
+#ifndef g_assert_nonnull
+#define g_assert_nonnull g_assert
+#endif
+
+struct test_case {
+ gchar *uri;
+ gchar *scheme;
+ gchar *hostname;
+ guint port;
+ gchar *user;
+ gchar *password;
+ gchar *error_msg;
+};
+
+static void test_spice_uri_bad(const struct test_case invalid_test_cases[], const guint cases_cnt)
+{
+ guint i;
+
+ SpiceURI *uri = spice_uri_new();
+ g_assert_nonnull(uri);
+
+ for (i = 0; i < cases_cnt; i++) {
+ GError *error = NULL;
+ g_assert_false(spice_uri_parse(uri, invalid_test_cases[i].uri, &error));
+ g_assert_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED);
+ g_assert_cmpstr(error->message, ==, invalid_test_cases[i].error_msg);
+ g_error_free(error);
+ }
+
+ g_object_unref(uri);
+}
+
+static void test_spice_uri_good(const struct test_case valid_test_cases[], const guint cases_cnt)
+{
+ guint i;
+
+ SpiceURI *uri = spice_uri_new();
+ g_assert_nonnull(uri);
+
+ for (i = 0; i < cases_cnt; i++) {
+ GError *error = NULL;
+ g_assert_true(spice_uri_parse(uri, valid_test_cases[i].uri, &error));
+ g_assert_cmpstr(spice_uri_get_scheme(uri), ==, valid_test_cases[i].scheme);
+ g_assert_cmpstr(spice_uri_get_hostname(uri), ==, valid_test_cases[i].hostname);
+ g_assert_cmpstr(spice_uri_get_user(uri), ==, valid_test_cases[i].user);
+ g_assert_cmpstr(spice_uri_get_password(uri), ==, valid_test_cases[i].password);
+ g_assert_cmpuint(spice_uri_get_port(uri), ==, valid_test_cases[i].port);
+ g_assert_no_error(error);
+ }
+
+ g_object_unref(uri);
+}
+
+static void test_spice_uri_ipv4_bad(void)
+{
+ const struct test_case invalid_test_cases[] = {
+ {"http://:80", "http", NULL, 80, NULL, NULL, "Invalid hostname in uri address"},
+ {"http://", "http", NULL, 3128, NULL, NULL, "Invalid hostname in uri address"},
+ {"http://127.0.0.1:port", "http", "127.0.0.1", 3128, NULL, NULL,
+ "Invalid uri port: port"},
+ {"http://127.0.0.1:", "http", "127.0.0.1", 3128, NULL, NULL, "Missing uri port"},
+ {"http://127.0.0.1:-80", "http", "127.0.0.1", 3128, NULL, NULL, "Port out of range"},
+ {"http://127.0.0.1:4294967396", "http", "127.0.0.1", 3128, NULL, NULL, "Port out of range"},
+ {"http://127.0.0.1:12345678901234", "http", "127.0.0.1", 3128, NULL, NULL, "Port out of range"},
+ {"scheme://192.168.1.1:3128", "http", "127.0.0.1", 3128, NULL, NULL,
+ "Invalid uri scheme for proxy: scheme"},
+ };
+
+ test_spice_uri_bad(invalid_test_cases, G_N_ELEMENTS(invalid_test_cases));
+}
+
+static void test_spice_uri_ipv4_good(void)
+{
+ const struct test_case valid_test_cases[] = {
+ {"http://127.0.0.1/", "http", "127.0.0.1", 3128, NULL, NULL, NULL},
+ {"https://127.0.0.1", "https", "127.0.0.1", 3129, NULL, NULL, NULL},
+ {"127.0.0.1", "http", "127.0.0.1", 3128, NULL, NULL, NULL},
+ {"http://user:password@host:80", "http", "host", 80, "user", "password", NULL},
+ {"https://host:42", "https", "host", 42, NULL, NULL, NULL}, /* tests resetting of username & password */
+ };
+
+ test_spice_uri_good(valid_test_cases, G_N_ELEMENTS(valid_test_cases));
+}
+
+static void test_spice_uri_ipv6_bad(void)
+{
+ const struct test_case invalid_test_cases[] = {
+ {"http://[]:80", "http", NULL, 80, NULL, NULL, "Invalid hostname in uri address"},
+ {"http://[::1", "http", NULL, 3128, NULL, NULL, "Missing ']' in ipv6 uri"},
+ {"http://[host]1234", "http", "host", 3128, NULL, NULL, "Invalid uri address"},
+ {"http://[host]foo/", "http", "host", 3128, NULL, NULL, "Invalid uri address"},
+ {"http://[::1]:port", "http", "::1", 3128, NULL, NULL, "Invalid uri port: port"},
+ {"http://[::127.0.0.1]:", "http", "::127.0.0.1", 3128, NULL, NULL, "Missing uri port"},
+ {"http://[::127.0.0.1]:-42", "http", "::127.0.0.1", 3128, NULL, NULL, "Port out of range"},
+ {"[3ffe:2a00:100:7031::1]:42000000", "http", "3ffe:2a00:100:7031::1", 3128, NULL, NULL, "Port out of range"},
+ {"scheme://[3ffe::192.168.1.1]:3128", "http", "3ffe::192.168.1.1", 3128, NULL, NULL,
+ "Invalid uri scheme for proxy: scheme"},
+ };
+
+ test_spice_uri_bad(invalid_test_cases, G_N_ELEMENTS(invalid_test_cases));
+}
+
+static void test_spice_uri_ipv6_good(void)
+{
+ const struct test_case valid_test_cases[] = {
+ {"http://user:password@[host]:80/", "http", "host", 80, "user", "password", NULL},
+ {"http://user@[1080:0:0:0:8:800:200C:4171]:100", "http", "1080:0:0:0:8:800:200C:4171", 100,
+ "user", NULL, NULL},
+ {"https://[1080::8:800:200C:417A]", "https", "1080::8:800:200C:417A", 3129, NULL, NULL, NULL},
+ {"[3ffe:2a00:100:7031::1]", "http", "3ffe:2a00:100:7031::1", 3128, NULL, NULL, NULL},
+ };
+
+ test_spice_uri_good(valid_test_cases, G_N_ELEMENTS(valid_test_cases));
+}
+
+int main(int argc, char* argv[])
+{
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add_func("/spice_uri/ipv4/bad-uri", test_spice_uri_ipv4_bad);
+ g_test_add_func("/spice_uri/ipv4/good-uri", test_spice_uri_ipv4_good);
+ g_test_add_func("/spice_uri/ipv6/bad-uri", test_spice_uri_ipv6_bad);
+ g_test_add_func("/spice_uri/ipv6/good-uri", test_spice_uri_ipv6_good);
+
+ return g_test_run();
+}
--- /dev/null
+/*
+ Copyright (C) 2016 Red Hat, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <glib.h>
+#include "usb-acl-helper.h"
+
+typedef struct {
+ SpiceUsbAclHelper *acl_helper;
+ GCancellable *cancellable;
+ GMainLoop *loop;
+ guint timeout_source;
+} Fixture;
+
+gboolean abort_test(gpointer user_data)
+{
+ Fixture *fixture = user_data;
+ g_cancellable_cancel(fixture->cancellable);
+ fixture->timeout_source = 0;
+ return G_SOURCE_REMOVE;
+}
+
+gboolean cancel_test(gpointer user_data)
+{
+ Fixture *fixture = user_data;
+ g_cancellable_cancel(fixture->cancellable);
+ return G_SOURCE_REMOVE;
+}
+
+static void data_setup(Fixture *fixture, gconstpointer user_data G_GNUC_UNUSED)
+{
+ g_setenv("SPICE_USB_ACL_BINARY", TESTDIR"/test-mock-acl-helper", TRUE);
+ fixture->cancellable = g_cancellable_new();
+ fixture->acl_helper = spice_usb_acl_helper_new();
+ fixture->loop = g_main_loop_new(NULL, FALSE);
+ /* abort test after 2 seconds if it hasn't yet completed */
+ fixture->timeout_source = g_timeout_add_seconds(2, abort_test, fixture);
+}
+
+static void data_teardown(Fixture *fixture, gconstpointer user_data G_GNUC_UNUSED)
+{
+ if (fixture->timeout_source)
+ g_source_remove(fixture->timeout_source);
+ g_object_unref(fixture->cancellable);
+ g_object_unref(fixture->acl_helper);
+ g_main_loop_unref(fixture->loop);
+ g_unsetenv("SPICE_USB_ACL_BINARY");
+}
+
+
+static void success_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Fixture *f = user_data;
+ GError *error = NULL;
+ if (!spice_usb_acl_helper_open_acl_finish(SPICE_USB_ACL_HELPER(source), result, &error))
+ g_error("%s", error->message);
+ g_main_loop_quit(f->loop);
+}
+
+static void test_acl_helper_success(Fixture *fixture, gconstpointer user_data G_GNUC_UNUSED)
+{
+ spice_usb_acl_helper_open_acl_async(fixture->acl_helper, 1, 1,
+ fixture->cancellable, success_cb, fixture);
+ g_main_loop_run(fixture->loop);
+}
+
+static void spawn_fail_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Fixture *f = user_data;
+ GError *error = NULL;
+ gboolean success = spice_usb_acl_helper_open_acl_finish(SPICE_USB_ACL_HELPER(source), result, &error);
+ g_assert(!success);
+ g_assert (error->domain == G_SPAWN_ERROR);
+ g_clear_error(&error);
+ g_main_loop_quit(f->loop);
+}
+
+static void test_acl_helper_spawn_fail(Fixture *fixture, gconstpointer user_data G_GNUC_UNUSED)
+{
+ g_setenv("SPICE_USB_ACL_BINARY", "does-not-exist", TRUE);
+ spice_usb_acl_helper_open_acl_async(fixture->acl_helper, 1, 1,
+ fixture->cancellable, spawn_fail_cb,
+ fixture);
+ g_main_loop_run(fixture->loop);
+}
+
+static void early_eof_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Fixture *f = user_data;
+ GError *error = NULL;
+ gboolean success = spice_usb_acl_helper_open_acl_finish(SPICE_USB_ACL_HELPER(source), result, &error);
+ g_assert(!success);
+ g_assert(error->domain == SPICE_CLIENT_ERROR);
+ g_assert(error->code == SPICE_CLIENT_ERROR_FAILED);
+ g_clear_error(&error);
+ g_main_loop_quit(f->loop);
+}
+
+/* helper sends EOF before sending a response */
+static void test_acl_helper_early_eof(Fixture *fixture, gconstpointer user_data G_GNUC_UNUSED)
+{
+ g_setenv("TEST_EOF", "1", TRUE);
+ spice_usb_acl_helper_open_acl_async(fixture->acl_helper, 1, 1,
+ fixture->cancellable, early_eof_cb, fixture);
+ g_main_loop_run(fixture->loop);
+ g_unsetenv("TEST_EOF");
+}
+
+static void helper_canceled_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Fixture *f = user_data;
+ GError *error = NULL;
+ gboolean success = spice_usb_acl_helper_open_acl_finish(SPICE_USB_ACL_HELPER(source), result, &error);
+ g_assert(!success);
+ g_assert(error->domain == G_IO_ERROR);
+ g_assert(error->code == G_IO_ERROR_CANCELLED);
+ g_clear_error(&error);
+ g_main_loop_quit(f->loop);
+}
+
+static void test_acl_helper_helper_canceled(Fixture *fixture, gconstpointer user_data G_GNUC_UNUSED)
+{
+ g_setenv("TEST_RESPONSE", "CANCELED", TRUE);
+ spice_usb_acl_helper_open_acl_async(fixture->acl_helper, 1, 1,
+ fixture->cancellable, helper_canceled_cb, fixture);
+ g_main_loop_run(fixture->loop);
+ g_unsetenv("TEST_RESPONSE");
+}
+
+static void helper_error_response_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Fixture *f = user_data;
+ GError *error = NULL;
+ gboolean success = spice_usb_acl_helper_open_acl_finish(SPICE_USB_ACL_HELPER(source), result, &error);
+ g_assert(!success);
+ g_assert(error->domain == SPICE_CLIENT_ERROR);
+ g_assert(error->code == SPICE_CLIENT_ERROR_FAILED);
+ g_clear_error(&error);
+ g_main_loop_quit(f->loop);
+}
+
+static void test_acl_helper_error_response(Fixture *fixture, gconstpointer user_data G_GNUC_UNUSED)
+{
+ g_setenv("TEST_RESPONSE", "Not authorized", TRUE);
+ spice_usb_acl_helper_open_acl_async(fixture->acl_helper, 1, 1,
+ fixture->cancellable, helper_error_response_cb, fixture);
+ g_main_loop_run(fixture->loop);
+ g_unsetenv("TEST_RESPONSE");
+}
+
+static void client_canceled_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ Fixture *f = user_data;
+ GError *error = NULL;
+ gboolean success = spice_usb_acl_helper_open_acl_finish(SPICE_USB_ACL_HELPER(source), result, &error);
+ g_assert(!success);
+ g_assert(error->domain == G_IO_ERROR);
+ g_assert(error->code == G_IO_ERROR_CANCELLED);
+ g_clear_error(&error);
+ g_main_loop_quit(f->loop);
+}
+
+static void test_acl_helper_client_canceled(Fixture *fixture, gconstpointer user_data G_GNUC_UNUSED)
+{
+ /* ensure that the acl-helper does not have respond, so we can cancel the
+ * task before we get a response from the helper binary */
+ g_setenv("TEST_NORESPONSE", "1", TRUE);
+ spice_usb_acl_helper_open_acl_async(fixture->acl_helper, 1, 1,
+ fixture->cancellable, client_canceled_cb, fixture);
+ g_idle_add(cancel_test, fixture);
+ g_main_loop_run(fixture->loop);
+ g_unsetenv("TEST_NORESPONSE");
+}
+
+static void test_acl_helper_no_response(Fixture *fixture, gconstpointer user_data G_GNUC_UNUSED)
+{
+ /* ensure that the acl-helper does not have respond, so we can cancel the
+ * task before we get a response from the helper binary */
+ g_setenv("TEST_NORESPONSE", "1", TRUE);
+ spice_usb_acl_helper_open_acl_async(fixture->acl_helper, 1, 1,
+ fixture->cancellable, client_canceled_cb, fixture);
+ g_main_loop_run(fixture->loop);
+ g_unsetenv("TEST_NORESPONSE");
+}
+
+int main(int argc, char* argv[])
+{
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add("/usb-acl-helper/success", Fixture, NULL,
+ data_setup, test_acl_helper_success, data_teardown);
+ g_test_add("/usb-acl-helper/spawn-fail", Fixture, NULL,
+ data_setup, test_acl_helper_spawn_fail, data_teardown);
+ g_test_add("/usb-acl-helper/early-eof", Fixture, NULL,
+ data_setup, test_acl_helper_early_eof, data_teardown);
+ g_test_add("/usb-acl-helper/helper-canceled", Fixture, NULL,
+ data_setup, test_acl_helper_helper_canceled, data_teardown);
+ g_test_add("/usb-acl-helper/helper-error", Fixture, NULL,
+ data_setup, test_acl_helper_error_response, data_teardown);
+ g_test_add("/usb-acl-helper/client-canceled", Fixture, NULL,
+ data_setup, test_acl_helper_client_canceled, data_teardown);
+ g_test_add("/usb-acl-helper/no-response", Fixture, NULL,
+ data_setup, test_acl_helper_no_response, data_teardown);
+ /* additional possible test cases:
+ * - unable to set nonblocking flag on io channel?
+ * - unable to write bus number to helper binary
+ * - unable to flush channel
+ * - read_line from helper binary returns something other than G_IO_STATUS_NORMAL
+ */
+
+ return g_test_run ();
+}
+
--- /dev/null
+#include <glib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define __SPICE_CLIENT_H_INSIDE__
+#include "spice-util-priv.h"
+
+enum {
+ DOS2UNIX = 1 << 0,
+ UNIX2DOS = 1 << 1,
+};
+
+static const struct {
+ const gchar *d;
+ const gchar *u;
+ glong flags;
+} dosunix[] = {
+ { "", "", DOS2UNIX|UNIX2DOS },
+ { "a", "a", DOS2UNIX|UNIX2DOS },
+ { "\r\n", "\n", DOS2UNIX|UNIX2DOS },
+ { "\r\n\r\n", "\n\n", DOS2UNIX|UNIX2DOS },
+ { "a\r\n", "a\n", DOS2UNIX|UNIX2DOS },
+ { "a\r\n\r\n", "a\n\n", DOS2UNIX|UNIX2DOS },
+ { "\r\n\r\na\r\n\r\n", "\n\na\n\n", DOS2UNIX|UNIX2DOS },
+ { "1\r\n\r\na\r\n\r\n2", "1\n\na\n\n2", DOS2UNIX|UNIX2DOS },
+ { "\n", "\n", DOS2UNIX },
+ { "\n\n", "\n\n", DOS2UNIX },
+ { "\r\n", "\r\n", UNIX2DOS },
+ { "\r\r\n", "\r\r\n", UNIX2DOS },
+ { "é\r\né", "é\né", DOS2UNIX|UNIX2DOS },
+ { "\r\né\r\né\r\n", "\né\né\n", DOS2UNIX|UNIX2DOS }
+ /* TODO: add some utf8 test cases */
+};
+
+static void test_dos2unix(void)
+{
+ gchar *tmp;
+ unsigned int i;
+
+ for (i = 0; i < G_N_ELEMENTS(dosunix); i++) {
+ if (!(dosunix[i].flags & DOS2UNIX))
+ continue;
+
+ tmp = spice_dos2unix(dosunix[i].d, -1);
+ g_assert_cmpstr(tmp, ==, dosunix[i].u);
+ g_free(tmp);
+
+ /* including ending \0 */
+ tmp = spice_dos2unix(dosunix[i].d, strlen(dosunix[i].d) + 1);
+ g_assert_cmpstr(tmp, ==, dosunix[i].u);
+ g_free(tmp);
+ }
+}
+
+static void test_unix2dos(void)
+{
+ gchar *tmp;
+ unsigned int i;
+
+ for (i = 0; i < G_N_ELEMENTS(dosunix); i++) {
+ if (!(dosunix[i].flags & UNIX2DOS))
+ continue;
+
+ tmp = spice_unix2dos(dosunix[i].u, -1);
+ g_assert_cmpstr(tmp, ==, dosunix[i].d);
+ g_free(tmp);
+
+ /* including ending \0 */
+ tmp = spice_unix2dos(dosunix[i].u, strlen(dosunix[i].u) + 1);
+ g_assert_cmpstr(tmp, ==, dosunix[i].d);
+ g_free(tmp);
+ }
+}
+
+static const struct {
+ unsigned width;
+ unsigned height;
+ gchar *and;
+ gchar *xor;
+ gchar *dest;
+} mono[] = {
+ {
+ 8, 6,
+ "11111111"
+ "11111111"
+ "11111111"
+ "11111111"
+ "11111111"
+ "11111111"
+ ,
+ "00000000"
+ "00000000"
+ "00000100"
+ "00000100"
+ "00000000"
+ "00000000"
+ ,
+ "0000" "0000" "0000" "0000" "0000" "0000" "0000" "0000"
+ "0000" "0000" "0000" "0000" "0001" "0001" "0001" "0000"
+ "0000" "0000" "0000" "0000" "0001" "1111" "0001" "0000"
+ "0000" "0000" "0000" "0000" "0001" "1111" "0001" "0000"
+ "0000" "0000" "0000" "0000" "0001" "0001" "0001" "0000"
+ "0000" "0000" "0000" "0000" "0000" "0000" "0000" "0000"
+ }
+};
+
+static void set_bit(guint8 *d, unsigned bit, unsigned value)
+{
+ if (value) {
+ *d |= (0x80 >> bit);
+ } else {
+ *d &= ~(0x80 >> bit);
+ }
+}
+
+static void test_set_bit(void)
+{
+ struct {
+ unsigned len;
+ gchar *src;
+ gchar *dest;
+ } tests[] = {
+ {
+ 4,
+ "1111",
+ "\xf0",
+ },
+ {
+ 16,
+ "1111011100110001",
+ "\xf7\x31",
+ }
+ };
+ unsigned int i, j, bit;
+ guint8 *dest;
+ unsigned int bytes;
+
+ for (i = 0 ; i < G_N_ELEMENTS(tests); ++i) {
+ bytes = (tests[i].len + 7) / 8;
+ dest = g_malloc0(bytes);
+ for (j = 0 ; j < tests[i].len;) {
+ for (bit = 0 ; bit < 8 && j < tests[i].len; ++bit, ++j) {
+ set_bit(&dest[j / 8], bit, tests[i].src[j] == '0' ? 0 : 1);
+ }
+ }
+ for (j = 0 ; j < bytes; ++j) {
+ g_assert(dest[j] == (guchar) tests[i].dest[j]);
+ }
+ g_free(dest);
+ }
+}
+
+static void test_mono_edge_highlight(void)
+{
+ unsigned int i;
+ int j, bit;
+ guint8 *and;
+ guint8 *xor;
+ guint8 *dest;
+ guint8 *dest_correct;
+ int size, pixels;
+
+ test_set_bit();
+
+ for (i = 0 ; i < G_N_ELEMENTS(mono); ++i) {
+ pixels = mono[i].width * mono[i].height;
+ size = (pixels + 7) / 8;
+ and = g_malloc0(size);
+ xor = g_malloc0(size);
+ dest = g_malloc0(pixels * 4);
+ dest_correct = g_malloc(pixels * 4);
+ for (j = 0 ; j < pixels;) {
+ for (bit = 0; bit < 8 && j < pixels; ++bit, ++j) {
+ set_bit(&and[j / 8], bit, mono[i].and[j] == '0' ? 0 : 1);
+ set_bit(&xor[j / 8], bit, mono[i].xor[j] == '0' ? 0 : 1);
+ }
+ }
+ for (j = 0 ; j < pixels * 4 ; ++j) {
+ dest_correct[j] = mono[i].dest[j] == '0' ? 0x00 : 0xff;
+ }
+ spice_mono_edge_highlight(mono[i].width, mono[i].height, and, xor, dest);
+ for (j = 0; j < pixels; ++j) {
+ g_assert(dest[j] == dest_correct[j]);
+ }
+ g_free(and);
+ g_free(xor);
+ g_free(dest);
+ g_free(dest_correct);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add_func("/util/dos2unix", test_dos2unix);
+ g_test_add_func("/util/unix2dos", test_unix2dos);
+ g_test_add_func("/util/mono_edge_highlight", test_mono_edge_highlight);
+
+ return g_test_run ();
+}
--- /dev/null
+NULL =
+CLEANFILES =
+
+vapidir = $(datadir)/vala/vapi
+vapi_DATA = \
+ spice-client-glib-2.0.vapi \
+ $(NULL)
+dist_vapi_DATA = \
+ spice-client-glib-2.0.deps \
+ $(NULL)
+
+if WITH_GTK
+vapi_DATA += spice-client-gtk-3.0.vapi
+dist_vapi_DATA += spice-client-gtk-3.0.deps
+endif
+
+EXTRA_DIST = \
+ spice-client-gtk-3.0.deps \
+ SpiceClientGLib-2.0.metadata \
+ $(NULL)
+
+CLEANFILES += $(vapi_DATA)
+
+spice-client-glib-2.0.vapi: $(top_builddir)/src/SpiceClientGLib-2.0.gir SpiceClientGLib-2.0.metadata
+ $(AM_V_GEN)$(VAPIGEN) -q \
+ --metadatadir=$(srcdir) \
+ --library spice-client-glib-2.0 \
+ --pkg gio-2.0 \
+ $<
+
+spice-client-gtk-3.0.vapi: $(top_builddir)/src/SpiceClientGtk-3.0.gir spice-client-glib-2.0.vapi
+ $(AM_V_GEN)$(VAPIGEN) -q \
+ --vapidir=$(builddir) \
+ --girdir=$(top_builddir)/src \
+ --pkg spice-client-glib-2.0 \
+ --pkg gtk+-3.0 \
+ --library spice-client-gtk-3.0 \
+ $<
+
+-include $(top_srcdir)/git.mk
--- /dev/null
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@WITH_GTK_TRUE@am__append_1 = spice-client-gtk-3.0.vapi
+@WITH_GTK_TRUE@am__append_2 = spice-client-gtk-3.0.deps
+subdir = vapi
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \
+ $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/ld-version.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/manywarnings.m4 \
+ $(top_srcdir)/m4/spice-compile-warnings.m4 \
+ $(top_srcdir)/m4/warnings.m4 \
+ $(top_srcdir)/spice-common/m4/spice-deps.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__dist_vapi_DATA_DIST) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__dist_vapi_DATA_DIST = spice-client-glib-2.0.deps \
+ spice-client-gtk-3.0.deps
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(vapidir)" "$(DESTDIR)$(vapidir)"
+DATA = $(dist_vapi_DATA) $(vapi_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ACL_HELPER_DIR = @ACL_HELPER_DIR@
+ACL_LIBS = @ACL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CAIRO_CFLAGS = @CAIRO_CFLAGS@
+CAIRO_LIBS = @CAIRO_LIBS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMMON_CFLAGS = @COMMON_CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GIO_CFLAGS = @GIO_CFLAGS@
+GIO_LIBS = @GIO_LIBS@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GOBJECT2_CFLAGS = @GOBJECT2_CFLAGS@
+GOBJECT2_LIBS = @GOBJECT2_LIBS@
+GREP = @GREP@
+GSTAUDIO_CFLAGS = @GSTAUDIO_CFLAGS@
+GSTAUDIO_LIBS = @GSTAUDIO_LIBS@
+GSTVIDEO_CFLAGS = @GSTVIDEO_CFLAGS@
+GSTVIDEO_LIBS = @GSTVIDEO_LIBS@
+GST_INSPECT_1_0 = @GST_INSPECT_1_0@
+GTHREAD_CFLAGS = @GTHREAD_CFLAGS@
+GTHREAD_LIBS = @GTHREAD_LIBS@
+GTKDOC_CHECK = @GTKDOC_CHECK@
+GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
+GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
+GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
+GTKDOC_MKPDF = @GTKDOC_MKPDF@
+GTKDOC_REBASE = @GTKDOC_REBASE@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_REQUIRED = @GTK_REQUIRED@
+GUDEV_CFLAGS = @GUDEV_CFLAGS@
+GUDEV_LIBS = @GUDEV_LIBS@
+HTML_DIR = @HTML_DIR@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
+INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
+INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
+INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
+INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
+INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
+INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
+INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
+JPEG_LIBS = @JPEG_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUSB_HOTPLUG_CFLAGS = @LIBUSB_HOTPLUG_CFLAGS@
+LIBUSB_HOTPLUG_LIBS = @LIBUSB_HOTPLUG_LIBS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LZ4_CFLAGS = @LZ4_CFLAGS@
+LZ4_LIBS = @LZ4_LIBS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PHODAV_CFLAGS = @PHODAV_CFLAGS@
+PHODAV_LIBS = @PHODAV_LIBS@
+PIE_CFLAGS = @PIE_CFLAGS@
+PIE_LDFLAGS = @PIE_LDFLAGS@
+PIXMAN_CFLAGS = @PIXMAN_CFLAGS@
+PIXMAN_LIBS = @PIXMAN_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PNP_IDS = @PNP_IDS@
+POFILES = @POFILES@
+POLICYDIR = @POLICYDIR@
+POLKIT_CFLAGS = @POLKIT_CFLAGS@
+POLKIT_LIBS = @POLKIT_LIBS@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+PULSE_CFLAGS = @PULSE_CFLAGS@
+PULSE_LIBS = @PULSE_LIBS@
+PYTHON = @PYTHON@
+RANLIB = @RANLIB@
+SASL_CFLAGS = @SASL_CFLAGS@
+SASL_LIBS = @SASL_LIBS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SMARTCARD_CFLAGS = @SMARTCARD_CFLAGS@
+SMARTCARD_LIBS = @SMARTCARD_LIBS@
+SPICE_CFLAGS = @SPICE_CFLAGS@
+SPICE_GLIB_CFLAGS = @SPICE_GLIB_CFLAGS@
+SPICE_GLIB_REQUIRES = @SPICE_GLIB_REQUIRES@
+SPICE_GTK_CFLAGS = @SPICE_GTK_CFLAGS@
+SPICE_GTK_LOCALEDIR = @SPICE_GTK_LOCALEDIR@
+SPICE_GTK_MAJOR_VERSION = @SPICE_GTK_MAJOR_VERSION@
+SPICE_GTK_MICRO_VERSION = @SPICE_GTK_MICRO_VERSION@
+SPICE_GTK_MINOR_VERSION = @SPICE_GTK_MINOR_VERSION@
+SPICE_GTK_REQUIRES = @SPICE_GTK_REQUIRES@
+SPICE_PROTOCOL_CFLAGS = @SPICE_PROTOCOL_CFLAGS@
+SPICE_PROTOCOL_LIBS = @SPICE_PROTOCOL_LIBS@
+SSL_CFLAGS = @SSL_CFLAGS@
+SSL_LIBS = @SSL_LIBS@
+STOW = @STOW@
+STRIP = @STRIP@
+USBREDIR_CFLAGS = @USBREDIR_CFLAGS@
+USBREDIR_LIBS = @USBREDIR_LIBS@
+USB_IDS = @USB_IDS@
+USE_NLS = @USE_NLS@
+VALAC = @VALAC@
+VAPIDIR = @VAPIDIR@
+VAPIGEN = @VAPIGEN@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WARN_LDFLAGS = @WARN_LDFLAGS@
+WARN_PYFLAGS = @WARN_PYFLAGS@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+XGETTEXT = @XGETTEXT@
+Z_LIBS = @Z_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+CLEANFILES = $(vapi_DATA)
+vapidir = $(datadir)/vala/vapi
+vapi_DATA = spice-client-glib-2.0.vapi $(NULL) $(am__append_1)
+dist_vapi_DATA = spice-client-glib-2.0.deps $(NULL) $(am__append_2)
+EXTRA_DIST = \
+ spice-client-gtk-3.0.deps \
+ SpiceClientGLib-2.0.metadata \
+ $(NULL)
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign vapi/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign vapi/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-dist_vapiDATA: $(dist_vapi_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_vapi_DATA)'; test -n "$(vapidir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(vapidir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(vapidir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(vapidir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(vapidir)" || exit $$?; \
+ done
+
+uninstall-dist_vapiDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_vapi_DATA)'; test -n "$(vapidir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(vapidir)'; $(am__uninstall_files_from_dir)
+install-vapiDATA: $(vapi_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(vapi_DATA)'; test -n "$(vapidir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(vapidir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(vapidir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(vapidir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(vapidir)" || exit $$?; \
+ done
+
+uninstall-vapiDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(vapi_DATA)'; test -n "$(vapidir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(vapidir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(vapidir)" "$(DESTDIR)$(vapidir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_vapiDATA install-vapiDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_vapiDATA uninstall-vapiDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am \
+ install-dist_vapiDATA install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip install-vapiDATA \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
+ uninstall-am uninstall-dist_vapiDATA uninstall-vapiDATA
+
+.PRECIOUS: Makefile
+
+
+spice-client-glib-2.0.vapi: $(top_builddir)/src/SpiceClientGLib-2.0.gir SpiceClientGLib-2.0.metadata
+ $(AM_V_GEN)$(VAPIGEN) -q \
+ --metadatadir=$(srcdir) \
+ --library spice-client-glib-2.0 \
+ --pkg gio-2.0 \
+ $<
+
+spice-client-gtk-3.0.vapi: $(top_builddir)/src/SpiceClientGtk-3.0.gir spice-client-glib-2.0.vapi
+ $(AM_V_GEN)$(VAPIGEN) -q \
+ --vapidir=$(builddir) \
+ --girdir=$(top_builddir)/src \
+ --pkg spice-client-glib-2.0 \
+ --pkg gtk+-3.0 \
+ --library spice-client-gtk-3.0 \
+ $<
+
+-include $(top_srcdir)/git.mk
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+Channel.open_fd#virtual_method skip
--- /dev/null
+spice-client-glib-2.0
+gtk+-3.0